feat(api): a per-run hook for callbacks and context - #79
Merged
Conversation
create_router gains turn_context: a context manager entered inside the SSE generator, given the request and both ids, yielding the turn's runnable config. create_app forwards the same argument. A context manager rather than a config factory because a tracing callback is a value passed to the turn while a correlation id read by an httpx hook is a context variable, which has to be set for the duration. Both need to be in force while the turn runs, not while the handler is on the stack. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ciaransweet
pushed a commit
that referenced
this pull request
Aug 13, 2026
🤖 I have created a release *beep* *boop* --- ## [0.5.6](mcp-toolsets-runtime-v0.5.5...mcp-toolsets-runtime-v0.5.6) (2026-08-13) ### Features * **api:** a per-run hook for callbacks and context ([#79](#79)) ([5474256](5474256)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: ds-release-bot[bot] <116609932+ds-release-bot[bot]@users.noreply.github.com>
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.
create_routerhad no seam for what a host puts around a run.create_runcalled
stream_turn(agent, question, thread_id)with no config and entered onlyuser_credentialsinside the SSE generator — so a deployment could serve theagent over HTTP but could not trace it.
The hook
Called per run with the request and both ids, entered inside the stream, and
whatever it yields becomes the turn's runnable config.
create_apptakes thesame argument and forwards it. Omit it and nothing changes.
Why a context manager, not a config factory
The two things a host wants here differ in kind. A tracing callback is a
value handed to the turn. A correlation id stamped onto the outbound MCP
calls — a header on every call a turn makes, read by an httpx event hook at
request time — is a context variable, which has to be set for the duration
rather than passed.
A factory returning a config covers the first and not the second. A context
manager covers both, and yields the config on the way in.
Both share a lifetime requirement, which is why this is entered beside
user_credentialsrather than wrapped around the route: by the time the firsttool is called, the request handler has long returned, so anything scoped to
its stack is already gone.
Tests
Three, each pinning a property that would otherwise regress silently:
wrapper that never exits leaks whatever it opened, once per run;
only inside it records a chain start, which it cannot do if the config is
dropped;
ContextVarset inside it is visible from the tool call, which is theproperty a config factory could not have delivered and the reason for the
shape.
332 tests pass, lint clean.
What it unblocks
dss-agentic-ai-servicesis about to serve its agent over these routes, withthe Langfuse tracing and
x-trace-idcorrelation its Chainlit host alreadydoes. Without this the API would be the one surface in that deployment
producing no traces at all, and the alternative was forking
POST /runsdownstream — a permanent divergence on the route most likely to change here.
🤖 Generated with Claude Code