Repository navigation
fix(server): save a resumed turn's message with its first event - #1392
Draft
mykytanetipa wants to merge 1 commit into
Draft
mykytanetipa wants to merge 1 commit into
mykytanetipa wants to merge 1 commit into
Conversation
When a task waiting for input is resumed, the consumer added the user's message to the history with a separate save before applying the agent's first event. That save wrote the task with its previous state, and in cluster mode it also wrote a Task(INPUT_REQUIRED) row to the shared event log. A SubscribeToTask on another replica treated that row as the end of the stream and missed the rest of the turn. The message is now added in memory and persisted by the save of the event itself, so a resumed turn writes no stale state. If that save conflicts, the message is added again when the event is retried on the reloaded task.
🧪 Code Coverage (vs
|
| Base | PR | Delta | |
|---|---|---|---|
| src/a2a/server/agent_execution/active_task.py | 95.92% | 95.91% | 🔴 -0.01% |
| src/a2a/server/cluster/database_event_stream.py | 96.94% | 92.86% | 🔴 -4.08% |
| src/a2a/server/cluster/database_task_store.py | 96.55% | 99.31% | 🟢 +2.76% |
| src/a2a/server/events/event_queue_v2.py | 91.79% | 92.27% | 🟢 +0.48% |
| src/a2a/server/request_handlers/default_request_handler_v2.py | 87.68% | 88.54% | 🟢 +0.86% |
| src/a2a/utils/telemetry.py | 90.70% | 91.47% | 🟢 +0.78% |
| Total | 93.15% | 93.20% | 🟢 +0.05% |
Generated by coverage-comment.yml
4 tasks done
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.
Resuming a task that waits for input wrote the task once with its old state, which a subscriber on another replica took as the end of the stream. Found while working on #1324.
Example:
sequenceDiagram participant C as Client participant A as Replica A (runs agent) participant S as Shared store participant B as Replica B Note over S: T is INPUT_REQUIRED C->>A: SendMessage(T, follow-up) C->>B: SubscribeToTask(T) A->>S: save T + message, still INPUT_REQUIRED S-->>B: event log row Task(INPUT_REQUIRED) B-->>C: stream closed (interrupted state) A->>S: WORKING, artifact, COMPLETED Note over C: never sees the rest of the turnFix: the follow-up message is added to the task in memory and persisted by the save of the agent's first event, so a resumed turn no longer writes its previous state. If that save conflicts with another replica, the message is added again when the event is retried on the reloaded task, so it is not lost. In the example B follows the turn to completion, and the message is recorded once.
Tested: a remote subscriber follows a resumed turn to completion, and the message is recorded once, including after a conflict; full suite and Postgres/MySQL tests pass.