fix(server): accept trailing-slash JSON-RPC endpoint; enqueue Task in TCK SUT - #1165
Open
kuangmi-bit wants to merge 2 commits into
Open
fix(server): accept trailing-slash JSON-RPC endpoint; enqueue Task in TCK SUT#1165kuangmi-bit wants to merge 2 commits into
kuangmi-bit wants to merge 2 commits into
Conversation
… TCK SUT Two changes that together let the 1.0 TCK exercise the JSON-RPC SUT: 1. create_jsonrpc_routes now registers both the exact rpc_url and its trailing-slash variant. HTTP clients (httpx in particular) normalize an empty request path to a trailing slash, so POST /a2a/jsonrpc/ was previously 404 even though /a2a/jsonrpc worked. This is a protocol compatibility fix: the spec does not mandate one spelling over the other, and a 404 on the trailing-slash form breaks any client that does not strip it. 2. tck/sut_agent.py now enqueues the Task itself (via new_task_from_user_message) before emitting TaskStatusUpdateEvents. The SDK's active-task machinery requires this ordering (InvalidAgentResponseError otherwise), and the 1.0 TCK CORE-SEND tests assert it. Verified against a2a-tck 1.0.0.alpha2 (jsonrpc, must level): 53 failed -> 6 failed before this change, with the remaining failures being SUT feature gaps (artifacts) and one SDK error-code mapping gap, not transport issues.
🧪 Code Coverage (vs
|
| Base | PR | Delta | |
|---|---|---|---|
| src/a2a/server/events/event_queue_v2.py | 91.79% | 91.28% | 🔴 -0.51% |
| src/a2a/utils/telemetry.py | 91.47% | 90.70% | 🔴 -0.78% |
| Total | 93.00% | 92.97% | 🔴 -0.02% |
Generated by coverage-comment.yml
…card
Two more 1.0 compatibility fixes surfaced by running the REST and gRPC
rows of the TCK:
- protocolBinding 'REST' -> 'HTTP+JSON': the 1.0 TCK's protocol binding
map only recognizes JSONRPC / GRPC / HTTP+JSON. The old name made the
whole REST transport untestable ("No usable transports after filtering").
- gRPC interface url 'http://localhost:50051' -> 'localhost:50051': the
gRPC client treats the url as a channel target; the http:// prefix
fails DNS resolution in grpcio.
Verified against a2a-tck 1.0.0.alpha2 (must level):
- jsonrpc: 6 failed / 67 passed
- http_json (REST): 5 failed / 61 passed
- grpc: 7 failed / 48 passed
Remaining failures are SUT feature gaps (artifact-carrying responses,
MessageResponse variants) plus two status/error-code mappings.
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.
Summary
Two changes that let the A2A 1.0 TCK exercise the JSON-RPC SUT (part of the work tracked in #666):
create_jsonrpc_routesaccepts the trailing-slash endpoint variant. HTTP clients (httpx in particular) normalize an empty request path to a trailing slash, soPOST /a2a/jsonrpc/previously returned 404 even though/a2a/jsonrpcworked. The spec does not mandate one spelling over the other, and a 404 on the trailing-slash form breaks any spec-conformant client that does not strip it. Both variants now route to the same dispatcher.tck/sut_agent.pyenqueues the Task itself before emittingTaskStatusUpdateEvents (vianew_task_from_user_message). The SDK's active-task machinery requires this ordering (it raisesInvalidAgentResponseErrorotherwise), and the 1.0 TCKCORE-SEND-*requirements assert it.Verification
Ran the 1.0 TCK (
a2a-tcktag1.0.0.alpha2, jsonrpc transport, must level) against the SUT locally:The remaining 6 failures are not transport issues — they are SUT feature gaps (artifact-carrying responses, DM-ART-001) and one SDK error-code mapping gap (
ContentTypeNotSupportedErrorreported asParseError). Those are follow-ups; this PR fixes the transport-level blockers.Unit tests:
tests/server/routes/96 passed. Ruff clean on touched files.Related