Repository navigation
refactor(gateway): one Caller value for role and session; the three binding scopes side by side - #166
Merged
Conversation
…inding scopes side by side Behaviour-neutral. The role lived in one ContextVar bound per request, the session key in another bound per MCP session, and the _meta stamp was assembled by hand in the MCP proxy tool, in /step and in the trigger engine. A frozen Caller(role, session) in caller.py now carries both, Caller.current() reads it and Caller.meta() is the one place that produces the stamp, with the `default` sentinel documented where it is stamped: a _meta role entry of any value is what marks a call as proxied under the protocol, so an unforwarded caller is stamped `default` on purpose. _call_child_tool takes a Caller (None for an unattributed trigger action). The per-MCP-session lifespan leaves __init__ for a _session_lifespan method next to _asgi_app (request scope) and _process_lifespan (process scope), so the three scopes read in one place and __init__ only wires. The wire names stay literals in constants.py because the gateway container ships without agentenv_protocol; a unit test now pins them to the protocol's exports instead. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
earakely-scale
force-pushed
the
refactor/gateway-caller-and-lifespans
branch
from
October 12, 2026 02:05
5f76657 to
7ace4a1
Compare
Collaborator
Author
|
Light chaos round on this head (7ace4a1), loopback: a real
The same round on #167's head (6a9a432, which includes this commit) is identical: 14/14. |
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.
Behaviour-neutral restructuring, rebased onto
mainafter #165 merged (its chaos-round fix included).One caller value. The role lived in one ContextVar bound per request, the session key in another bound per MCP session, and the
_metastamp was assembled by hand in three places (the MCP proxy tool,/step, the trigger engine).caller.pyadds a frozenCaller(role, session):Caller.current()reads it,Caller.meta()is the one place that produces the stamp, and_call_child_tooltakes aCaller(None for an unattributed trigger action). Thedefaultsentinel now has its home there, with why it is load-bearing: under the protocol a_metarole entry of any value marks a call as proxied, so an unforwarded caller is stampeddefaulton purpose.The three scopes side by side. The per-MCP-session lifespan leaves
__init__for a_session_lifespanmethod next to_asgi_app(request scope) and_process_lifespan(process scope), with one comment explaining how the session's server task inherits the initialize request's role and passes the key to every tools/call.__init__only wires.Wire names. The issue asked to import the keys from
agentenv_protocol; the gateway container ships without that package (constants.pyis a hand-kept mirror by design), so they stay literals and a unit test pins them to the protocol's exports instead.No wire change: same
_metakeys and values, same headers, same JSON-RPC rewriting.tst/unit/env/gateway: 377 passing (372 after #165, plus the five caller tests); the two tests that reached into the old ContextVars bind aCallerinstead.🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; no actionable issues were found.Summary
The PR replaces separate role and session values with one frozen
Callerand moves the MCP session lifespan out of__init__.Caller.Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR HTTP[HTTP request role] --> Caller[Caller] MCP[MCP session key] --> Caller Caller --> Filter[Tool role filter] Caller --> Meta[Caller.meta] Step[REST step role] --> Meta Trigger[Attributed trigger role] --> Meta Meta --> Child[Child tools/call] Unattributed[Unattributed trigger] -->|No metadata| ChildReviews (2) · Last reviewed commit: "refactor(gateway): one Caller value for ..." · Reviewed by Greptile