Repository navigation
fix(server): run follow-up messages in the sender's contextvars - #1317
Merged
mykytanetipa merged 2 commits intoOct 6, 2026
Merged
Conversation
ActiveTask creates its producer once, during the first request for a task, so every later message on the task ran AgentExecutor.execute() with the first request's contextvars. Capture the caller's context in enqueue_request() and run execute() in it. Fixes a2aproject#1316
🧪 Code Coverage (vs
|
mykytanetipa
pushed a commit
that referenced
this pull request
Oct 19, 2026
🤖 I have created a release *beep* *boop* --- ## [1.2.3](v1.2.2...v1.2.3) (2026-10-17) ### Bug Fixes * **client:** ignore the patch version when preferring a 1.0 interface ([#1304](#1304)) ([cbb2d84](cbb2d84)) * **client:** normalize malformed agent card parsing errors ([#1307](#1307)) ([486f0f6](486f0f6)) * **compat:** block on a v0.3 gRPC and REST send without configuration ([#1334](#1334)) ([8160310](8160310)), closes [#1321](#1321) * **compat:** treat a v0.3 history_length of 0 as unlimited in JSON-RPC and REST ([#1312](#1312)) ([e86695c](e86695c)) * **jcs:** count open containers for the nesting bound, so an empty container leaf is refused ([#1294](#1294)) ([5653daf](5653daf)) * **server:** isolate push notification failures from the task lifecycle ([#1329](#1329)) ([0ee47d7](0ee47d7)) * **server:** mark internal lifecycle events done so a cancelled stream frees its producer ([#1336](#1336)) ([a4c4fc9](a4c4fc9)) * **server:** reject push URLs in shared address space ([#1326](#1326)) ([01da00b](01da00b)) * **server:** release the ActiveTask after a direct Message response ([#1297](#1297)) ([49ebce6](49ebce6)) * **server:** run follow-up messages in the sender's contextvars ([#1317](#1317)) ([a016002](a016002)) * **server:** warn when an AgentCard is missing required fields ([#1279](#1279)) ([4f4101c](4f4101c)) * **telemetry:** let trace_function alone decide a span's status ([#1309](#1309)) ([59dcbfb](59dcbfb)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
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.
Description
ActiveTaskcreates its producer once, during the first request for a task. Later messages on the same task are queued to that producer, soAgentExecutor.execute()ran with the first request's contextvars. Per-request values set by ASGI middleware or aServerCallContextBuilder(auth tokens, tenant identity, tracing) were stale on every follow-up turn, for example a reply afterinput-required.This change captures
contextvars.copy_context()inenqueue_request(), which runs in the sender's request, and runsexecute()in that context as a child task. Awaiting the child keeps cancellation working, because cancelling the producer cancels the child.Context.run(asyncio.create_task, ...)works on Python 3.10.Only
execute()changes context. Task-store writes and push notifications still run in the producer's context, as before.Tested:
New
test_follow_up_message_runs_in_sender_contextvars, for bothon_message_sendandon_message_send_stream. It fails onmainand passes with this change.The reproduction in [Bug]: DefaultRequestHandler runs follow-up messages on a task with the first request's contextvars #1316 prints
request-2for the follow-up../scripts/lint.shpasses.uv run pytest --cov=srcgives 2223 passed, 93% coverage.tests/integration/cross_version/client_server/test_client_server.pywas deselected because its server fails to start in my local environment onmaintoo.Follow the
CONTRIBUTINGGuide.Make your Pull Request title in the https://www.conventionalcommits.org/ specification.
Ensure the tests and linter pass (Run
bash scripts/format.shfrom the repository root to format)Appropriate docs were updated (if necessary)
Fixes #1316 🦕