Add A2A worker progress updates - #63
Merged
Merged
Conversation
dimavrem22
force-pushed
the
feat/a2a-worker-progress
branch
5 times, most recently
from
August 15, 2026 04:39
cbed5b9 to
403e657
Compare
dimavrem22
force-pushed
the
feat/a2a-worker-progress
branch
from
August 15, 2026 04:53
403e657 to
6302e0a
Compare
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.
Executive Summary
Adds durable, human-readable progress reporting for long-running inbound A2A worker tasks.
Description
When an inbound A2A task is durably registered, the worker immediately sends a cadence-aware nonterminal receipt, then emits concise progress on a referenced timer that defaults to 180 seconds. Setting the interval to zero disables periodic generation and timers while retaining the immediate receipt and its retry path. Each summary runs in a separate tool-disabled session with bounded task context, the previous delivered update, and up to eight normalized host-lifecycle identifiers; arguments and results are excluded, and unsafe output falls back to one generic nonterminal sentence.
The durable registry journals acknowledgement and periodic delivery candidates independently, so overlapping retries cannot overwrite or clear each other. Each sender clears only its own exact candidate, legacy single-slot state migrates on access, and worker-role history reconciles accepted responses without duplication. Catch-up revalidates persisted candidates against the same authoritative admission contract before acknowledgement, progress, or model dispatch. A stale persisted generation cannot suppress the server-current caller message; the admitted generation is rewritten with authoritative caller metadata and parts. Remote discovery enumerates both submitted and working tasks with task-ID deduplication, then selects the latest caller-role message.
Every inbound task-created or task-message webhook, including an existing-key acknowledgement retry, is checked against the authoritative A2A task before registry writes, acknowledgement, or model dispatch. Admission requires an exact task ID and context ID, an active submitted or working state, and a webhook message key matching the latest caller-role message. Caller metadata and message parts are rebuilt from that authoritative caller message rather than accepted from the webhook. The in-process cancellation tombstone remains a concurrency fence, while authoritative admission also rejects delayed canceled generations after restart.
Before explicit complete, ask-caller, or fail intents—and before a collected plain completion—the worker persists an entry-level reply fence, then drains progress and acknowledgement work. An ambiguous response followed by restart cannot resume the fenced turn; only a genuine new caller message key acquires new work. Input-required and auth-required are authoritative stopped states alongside terminal states, preventing acknowledgement, progress, or replay in the post-reply crash window.
A stopped supervisor is replaced with a fenced task owner that retains the original cadence phase. Per-message admission serialization prevents simultaneous duplicate webhooks from both reading an absent registry entry and starting duplicate work. Task/context admission is serialized with cancellation, so cancellation cannot miss a worker admitted just after its run snapshot. Shutdown closes admission before draining locks, deliveries, supervisors, retries, and active worker turns. Informational updates remain visible in protocol history without waking the requester.
Reason
Long-running A2A work should remain visibly active to people and passive clients without spending a full requester-agent turn on every informational update. Delivery failures, spoofed or stale webhook data, ambiguous replies, restarts, simultaneous webhook delivery, stopped states, cancellation, and shutdown must not silently disable, duplicate, overwrite, misroute, or outlive the worker lifecycle.
Decisions
Testing
npm test— 45 files passed, 587 tests passed.npm run typecheck— passed.npm run build— passed.npm test -- tests/inbound/session.test.ts— 143 tests passed.npm test -- tests/a2a-registry.test.ts— 4 tests passed.python3 -m pytest -q tests/live/test_mock_openai.py— 3 passed.python3.11 -m pytest -q tests/live/test_a2a_helpers.pywith the local SDK onPYTHONPATH— 3 passed.python3.11 -m py_compile tests/live/a2a_driver.py tests/live/mock_openai.py— passed.git diff --check— passed.4 + 6 = 10.