Repository navigation
Conversation
…nses Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🤖 Claude-generated PR description
This replaces #41 with a much thinner layer. llm and datasette-llm now emit their own spans, so datasette-agent only has to add the agent-level unit: one span per turn.
Depends on (unreleased, pinned temporarily):
chat {model}andexecute_tool {name}spansdatasette_llm.promptspan carrying the purposeWhat's emitted
invoke_agent datasette-agent(INTERNAL) wraps each_run_chaincall inrun_agentandresume_agent. Its attributes:gen_ai.operation.name=invoke_agentgen_ai.agent.name=datasette-agentgen_ai.conversation.iddatasette_agent.mode:chatorresumedatasette_agent.outcome:completed,question,browser_task,errororcancelledErrors set
error.type(the class name) and ERROR status. Cancellation is not an error. On Datasette ≥ 1.0a41 the turn nests under core's request span. The resulting trace is:Changes
agent.py: +11/−6. Only the two_run_chaincall sites are wrapped, inside the existingtry, so errors reach the span before being turned into SSE._run_chainitself is untouched.datasette_agent/telemetry.py: new,opentelemetry-apionly. It is a no-op without an SDK and imports nothing fromdatasette.telemetry, so it works on Datasette 1.0a37+.TEMPORARY pins, remove before release
[tool.uv.sources]inpyproject.tomlpoints llm and datasette-llm at theirasg017/otel-v2branches.test.ymlandpublish.ymlinstall those branches in the samepip installas the package. It has to be the same command, because the branches share version numbers with PyPI, so a separatepip installwould keep the PyPI copies.llm/datasette-llmfloors once the upstream PRs ship.Also included: the one-line Cache-Control test fix from #42, as its own commit. It will drop out on rebase once #42 merges.
Tests:
tests/test_telemetry.pycovers:datasette_llm.promptandchatdescendantsquestion, followed by aresumeturnerrorCancelledErrorandKeyboardInterrupt) ending ascancellederrorand the caller's context is restoredResults:
uv run pytest: 305 passeduv run --with datasette==1.0a37 pytest: 305 passednode --test tests/test_smd.mjs: 14 passedClient disconnects: when the client disconnects mid-chain, the turn ends as
errorand the caller's context is restored. datasette-llm#8 now ends its own abandonedpromptspan asabandonedwithout logging detach errors.Next in the stack: background runs and the explorer as linked trace roots.
🤖 Generated with Claude Code