Repository navigation
feat(a2a): governed inbound for donkey.serve() tasks (#225) - #1225
Merged
Merged
Conversation
Each inbound A2A task now binds a run, as an outgoing donkey.run() does: - correlation: adopt the caller's X-Correlation-Id (or the correlation_header name) when well-formed, else mint one; exposed as A2ATask.correlation_id and sent on every downstream call - cost tags: the configured tags ride every downstream call (span attributes; headers with send_cost_headers); caller cost headers are never adopted - one donkey.a2a.task SERVER span per task, parenting the downstream donkey.llm.chat spans and joining a caller's W3C traceparent; failures mark it with error.type only, never the message - a downstream refusal is re-raised as its typed DonkeyError and fails the task with a text part plus a structured error data part (type, refusal, correlation_id, call_id); remediation and bodies stay in logs The framework-free core lives in core/inbound.py (placed in the core layers contract beside transport/approvals); Donkey.serve() passes the telemetry and correlation_header settings and typed_refusals(). Inbound policy enforcement stays the gateway's job. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Closed
4 tasks
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.
Closes #225.
Every task that
donkey.serve()/build_app()runs is now governed the same way an outbounddonkey.run()is.What a served task gets
X-Correlation-Id, or the header named by thecorrelation_headersetting. It mints a new ID when the header is missing or malformed (header-safe, at most 128 characters). Handlers read it asA2ATask.correlation_id, and every downstream call sends it.donkey.a2a.taskSERVER span parents the downstreamdonkey.llm.chatspans. It joins the caller's trace when they send a W3Ctraceparent. A failure sets onlyerror.typeand ERROR status, never the exception message.{"error": {"type", "refusal", "correlation_id", "call_id"}}. No stack trace or exception text reaches the caller.Donkey.serve()passes the framework-awaretyped_refusals()bridge.Design notes
core/inbound.py, so it can be reused by a future MCP or HTTP inbound surface. It is placed in the core layers contract astransport | approvals | inbound. I added no ADR because this follows the approvals/spanflush precedent; say if you want one.website/content/a2a.mdx, not a separate page. ARCHITECTURE.md is updated too.docs/verified-apis.mdrow is marked UNVERIFIED. Whether an Omni Gateway A2A proxy forwards the caller'sX-Correlation-Idis untested live.run_context_from_headersand MCP remain open there.Verification
pytest -q: 3717 passed, 118 skipped. There are 19 new tests intests/unit/test_a2a_governed_inbound.py.ruff check,ruff format --check,mypy,lint-imports(9 contracts kept) and vulture are clean.generate_docs.py --checkandcheck_docs_sync --strictare in sync, and the llms files are regenerated.🤖 Generated with Claude Code