Skip to content

feat(a2a): A2A v1.0 client compatibility (SendMessage alias + v1.0 agent card) - #10839

Merged
diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.50from
wpec:feat/a2a-v1-compat
Aug 21, 2026
Merged

diegosouzapw merged 2 commits into
diegosouzapw:release/v3.8.50from
wpec:feat/a2a-v1-compat

Conversation

@wpec

@wpec wpec commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Problem

OmniRoute's A2A server speaks A2A v0.3 (message/send, message/stream). Clients on A2A v1.0 — the current a2a-sdk 1.x, Hermes Agent, and others — send the renamed methods SendMessage / SendStreamingMessage and 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 (a SendMessageResponse oneof), whereas OmniRoute returns v0.3 top-level artifacts/metadata.

This is the same gap LiteLLM hit and documented in BerriAI/litellm#30795 ("gateway advertises protocolVersion 1.0 but speaks 0.3").

Changes

  1. 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.

  2. 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.0 SendMessageResponse: a task carrying status.state (TASK_STATE_*), status.message.parts[].text, and task.artifacts (Message parts), plus the echoed contextId. v0.3 callers keep the exact existing response.

  3. v1.0 Agent Card (src/app/.well-known/agent-card.json/route.ts, new) — serves a v1.0 card with supportedInterfaces declaring both 1.0 and 0.3 on the same JSON-RPC endpoint. The legacy /.well-known/agent.json (v0.3) is left as-is.

Backward compatibility

  • Existing v0.3 clients are unaffected: aliases only add method names, and the response is only reshaped when a 1.0 method was used.
  • tasks/get / tasks/cancel names are identical across versions, so they're shared.

Caveats / follow-ups

  • Not run against a full local build — I could not npm install + typecheck in my environment. The change is small and syntax-checked (esbuild transform), but please CI-verify.
  • Streaming: SendStreamingMessage is 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 synchronous SendMessage path.
  • If desired, the supportedInterfaces could later advertise a distinct v1.0 URL if a fully 1.0-native handler is added.

@wpec
wpec requested a review from diegosouzapw as a code owner August 20, 2026 11:54
@diegosouzapw
diegosouzapw merged commit b87056a into diegosouzapw:release/v3.8.50 Aug 21, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants