Repository navigation
feat(a2a): A2A v1.0 client compatibility (SendMessage alias + v1.0 agent card) - #10839
Merged
diegosouzapw merged 2 commits intoAug 21, 2026
Merged
Conversation
diegosouzapw
merged commit Aug 21, 2026
b87056a
into
diegosouzapw:release/v3.8.50
0 of 3 checks passed
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…ent card) (diegosouzapw#10839) Adds A2A v1.0 client compatibility: aliases the renamed v1.0 method names (SendMessage → message/send, SendStreamingMessage → message/stream) and reshapes the synchronous reply into the v1.0 SendMessageResponse shape (task.status.message.parts[].text, task.artifacts) for requests that arrive via a v1.0 method — v0.3 callers keep the exact existing response. Also serves a v1.0 Agent Card at /.well-known/agent-card.json declaring both protocol versions on the same JSON-RPC endpoint. The PR had no tests and the author noted they couldn't build/typecheck locally — validated in an isolated worktree boarded onto origin/release/v3.8.50 (0 conflicts, 2 files): - Wrote a TDD regression test (tests/unit/a2a-v1-compat-10839.test.ts, 4 tests) exercising the real POST handler end-to-end: v1.0 SendMessage aliasing + response reshaping, v0.3 message/send keeping its existing shape, SendStreamingMessage no longer 404ing, and the new agent-card.json route declaring both 1.0/0.3 interfaces. Pushed fix-in-place. - 20/20 existing A2A tests still pass (a2a-auth-timing-safe, a2a-enabled-route, a2a-tasks-auth, t09-a2a-lifecycle, agent-card-route) — no regressions. - check-file-size, check-changelog-integrity: OK. - typecheck:core: clean (the author's local-build concern didn't reproduce). - check-complexity / check-cognitive-complexity: OK, both under baseline. Co-authored-by: wpec <wpec@users.noreply.github.com>
3 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.
Problem
OmniRoute's A2A server speaks A2A v0.3 (
message/send,message/stream). Clients on A2A v1.0 — the currenta2a-sdk1.x, Hermes Agent, and others — send the renamed methodsSendMessage/SendStreamingMessageand get:{"jsonrpc":"2.0","id":"1","error":{"code":-32601,"message":"Method not found: SendMessage"}}Even when aliased, a 1.0 client can't read the reply: v1.0 expects the text inside
task.status.message.parts[].text(aSendMessageResponseoneof), whereas OmniRoute returns v0.3 top-levelartifacts/metadata.This is the same gap LiteLLM hit and documented in BerriAI/litellm#30795 ("gateway advertises protocolVersion 1.0 but speaks 0.3").
Changes
Method aliases (
src/app/a2a/route.ts) —SendMessage → message/send,SendStreamingMessage → message/stream. The switch dispatches on the normalized name, so existing v0.3 behavior is untouched.v1.0 response shape (
src/app/a2a/route.ts) — when the request arrived via a 1.0 method, the synchronous reply is rebuilt as a v1.0SendMessageResponse: ataskcarryingstatus.state(TASK_STATE_*),status.message.parts[].text, andtask.artifacts(Message parts), plus the echoedcontextId. v0.3 callers keep the exact existing response.v1.0 Agent Card (
src/app/.well-known/agent-card.json/route.ts, new) — serves a v1.0 card withsupportedInterfacesdeclaring both1.0and0.3on the same JSON-RPC endpoint. The legacy/.well-known/agent.json(v0.3) is left as-is.Backward compatibility
tasks/get/tasks/cancelnames are identical across versions, so they're shared.Caveats / follow-ups
npm install+ typecheck in my environment. The change is small and syntax-checked (esbuild transform), but please CI-verify.SendStreamingMessageis aliased so it no longer 404s, but the SSE chunks are still v0.3-shaped (out of scope here). Most 1.0 clients use the synchronousSendMessagepath.supportedInterfacescould later advertise a distinct v1.0 URL if a fully 1.0-native handler is added.