Skip to content

feat(a2a): add 1.0 agent gateway - #196

Open
legendtkl wants to merge 6 commits into
astaxie:mainfrom
legendtkl:codex/a2a-1-0-agent-gateway
Open

feat(a2a): add 1.0 agent gateway#196
legendtkl wants to merge 6 commits into
astaxie:mainfrom
legendtkl:codex/a2a-1-0-agent-gateway

Conversation

@legendtkl

@legendtkl legendtkl commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds a disabled-by-default A2A 1.0 Agent Gateway to TokenHub. The gateway lets authenticated callers discover and invoke reviewed upstream Agents through TokenHub while preserving centralized access control, task isolation, routing, budgets, auditability, and deployment controls. This implements the agreed scope of #160 using A2A 1.0 exclusively; A2A 0.3 is intentionally unsupported.

Related Issue

Relates to #160.

Changes

  • Add A2A 1.0 JSON-RPC and SSE gateway support for SendMessage, SendStreamingMessage, GetTask, ListTasks, CancelTask, and SubscribeToTask, plus authenticated Agent Card discovery.
  • Add the agent/<slug> OpenAI Responses bridge for non-streaming and streaming calls.
  • Add database- and catalog-managed Agent registration, encrypted instance credentials, revisions and rollback, weighted priority routing, task affinity, passive health cooldowns, and atomic cross-replica concurrency leases.
  • Add default-deny Agent access bindings for global, team, project, API key, end user, calling Agent, and access-group scopes, including skill filtering and deny precedence.
  • Add sanitized gateway task identities, API-key and end-user task isolation, delegation tokens, loop/depth protection, execution graphs, runtime/call/token/cost/concurrency budgets, and MCP/model usage accounting.
  • Add SSRF and DNS-rebinding protections, redirect blocking, sensitive-header filtering, bounded upstream responses, and request-level execution finalization.
  • Add the Agent Gateway admin page, execution observability, English/Simplified Chinese/Japanese UI copy and documentation, deployment configuration, release packaging, and SDK process E2E fixtures.

Type of Change

  • Bug fix
  • New feature
  • Refactor or maintenance
  • Documentation
  • Deployment or configuration

Verification

  • cd backend && go test ./...
  • cd backend && go vet ./...
  • cd frontend && npm run typecheck
  • cd frontend && npm run build
  • node --test tools/*.test.mjs — 116 tests passed
  • node tools/check-doc-translations.mjs --base origin/main --head HEAD
  • node tools/check-ui-translations.mjs
  • node tools/check-env-contract.mjs
  • node tools/check-source-lines.mjs
  • git diff --check
  • Real backend process plus independent A2A upstream process: all six A2A 1.0 methods, task and artifact SSE events, explicit 0.3 rejection, and streaming/non-streaming Responses bridge passed.
  • PostgreSQL 16 two-replica E2E: shared task affinity and atomic max_concurrency=1 admission passed.
  • Browser E2E: Agent registration, access binding, revision creation, rollback, execution observability, responsive layout, and clean browser console passed.
  • Native/container installer tests and all three rendered Docker Compose configurations passed; the container entrypoint test was run in its Linux target environment.

Compatibility, Security, and Operations

  • Existing OpenAI-compatible endpoints remain compatible. New public surfaces are /a2a/<slug> and the agent/<slug> Responses model namespace.
  • The gateway requires A2A-Version: 1.0; missing versions and A2A 0.3 are rejected intentionally.
  • The feature defaults to disabled through TOKENHUB_A2A_ENABLED=false. Rollback is to disable the flag; registry, task, and execution data remain stored.
  • Startup migration adds Agent registry, instance lease, access-control, task, execution graph, revision, and usage tables.
  • Upstream credentials are encrypted with the TokenHub secret key and are never exposed through public cards or admin execution payloads.
  • Production upstreams require HTTPS and public network destinations. TOKENHUB_A2A_ALLOW_PRIVATE_UPSTREAMS=true is restricted to controlled development environments.
  • A reviewed data/agent-catalog.yaml is added to source, container, and native release artifacts.

Checklist

  • Tests were added or updated for behavior changes, or the reason they are unnecessary is documented.
  • No credentials, local .env files, databases, backups, or runtime logs are included.
  • Environment variable changes are synchronized across examples, Compose, start.sh, and deployment documentation where applicable.
  • Shared user-facing behavior is documented consistently in English, Simplified Chinese, and Japanese where applicable.
  • data/model-catalog.yaml remains tracked and catalog changes were reviewed where applicable.
  • git diff --check passes.

Copilot AI balanced review requested due to automatic review settings August 11, 2026 16:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@astaxie astaxie left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the complete current diff at d96c682. This head is not mergeable yet:

  • Required Backend/CI fails because parseSSEDataForTest is unused in backend/internal/server/agent_e2e_test.go:819.
  • The runtime A2A dial guard in agent_gateway.go only rejects private/loopback/unspecified/link-local addresses. It still permits CGNAT and other special-use destinations (for example 100.100.100.200), after which agentCredentialTransport attaches static instance credentials. Reuse a complete special-use classifier at validation and dial time, and add credential-bearing dial regressions.
  • Issue #160 requires fixed A2A 0.3/1.0 compatibility, but this head only advertises/accepts 1.0 and explicitly rejects 0.3. Either implement the acceptance criterion with compatibility tests or update the issue/scope before closing it.
  • Direct JSON-RPC calls distinguish a missing Agent (TASK_NOT_FOUND) from an existing but unauthorized Agent (UNAUTHORIZED), creating the existence oracle that #160 prohibits. Return the same non-disclosing response as Card discovery.
  • Only input text is evaluated by guardrails. Non-streaming output, streaming status messages, and artifact parts are persisted/returned without the output/artifact content-policy hook required by #160.
  • This adds tracked data/agent-catalog.yaml, while AGENTS.md still says only data/model-catalog.yaml is tracked and other runtime data is ignored. Synchronize the repository guide.

No approval while these blockers and the failing required check remain.

Copilot AI review requested due to automatic review settings August 12, 2026 16:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@legendtkl

Copy link
Copy Markdown
Collaborator Author

Addressed the review findings in 9b2a81d:

  • Removed the unused parseSSEDataForTest helper/import that broke the required Backend check.
  • Replaced the narrow private-IP check with a shared conservative special-use classifier at both registration validation and runtime dial time. It covers CGNAT (100.64.0.0/10), documentation/benchmark/reserved/multicast ranges, and IPv6 special-use space; a credential-bearing regression verifies 100.100.100.200 is rejected before the connection is made.
  • Unified missing, unauthenticated, and unauthorized direct JSON-RPC Agent admission responses to the same non-disclosing TASK_NOT_FOUND response, with exact-body regressions.
  • Added output guardrails for non-streaming messages/tasks, task status messages, streaming status events, task artifacts, and streaming artifact events before return and persistence. Direct A2A errors expose CONTENT_POLICY_VIOLATION; the Responses bridge maps policy blocks to 403 guardrail_blocked or a streaming guardrail_blocked error event instead of an upstream failure.
  • Updated AGENTS.md to document both tracked catalog sources.

A2A 0.3 is intentionally not implemented, per the confirmed product scope that this gateway uses A2A 1.0 exclusively. I changed the PR relationship from Closes #160 to Relates to #160, so this PR will not incorrectly close the broader issue while its 0.3 acceptance criterion remains unresolved.

Validation rerun: focused A2A E2E, go test ./..., go vet ./..., all repository gates (116 tests), full translation co-change check, frontend typecheck/build, and git diff --check. The mandatory independent read-only review found one error-classification issue, which was fixed and then re-reviewed with no remaining findings.

Please re-review the updated head when convenient.

…ateway

# Conflicts:
#	backend/go.mod
#	backend/internal/server/gateway_http.go
#	backend/internal/server/http.go
#	backend/internal/server/multi_instance_e2e_test.go
Copilot AI review requested due to automatic review settings August 12, 2026 16:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@legendtkl

Copy link
Copy Markdown
Collaborator Author

Follow-up: merged the latest origin/main into the PR head in 979388c and resolved the four overlapping files while preserving both A2A and the newly merged durable Responses functionality. Agent Responses continue through the A2A bridge; ordinary background=true Responses continue through the durable queue; background=true with agent/<slug> now fails explicitly with agent_background_not_supported and has an E2E regression.

Post-merge validation passed: focused A2A E2E, go test ./..., go vet ./..., repository gates (122/122), full doc/UI/env/source-line checks, frontend npm ci, typecheck and production build, and git diff --check. A final independent read-only review of the conflict resolutions found no issues.

@legendtkl
legendtkl requested a review from astaxie August 12, 2026 16:19
Comment thread backend/internal/server/agent_gateway.go Outdated
Comment thread backend/internal/server/gateway_http.go
Comment thread backend/internal/server/agent_http.go Outdated
Comment thread backend/internal/server/agent_gateway.go Outdated
Comment thread backend/internal/server/agent_responses.go Outdated
Copilot AI review requested due to automatic review settings August 16, 2026 03:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…ixes

# Conflicts:
#	backend/go.sum
#	backend/internal/server/http.go
#	docs/deployment.md
#	docs/ja/deployment.md
#	docs/zh-CN/deployment.md
#	frontend/features/admin/i18n/translations.tsx
Copilot AI review requested due to automatic review settings August 16, 2026 03:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@astaxie astaxie left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed the complete current diff at 51b24f5. The three author replies are verified: streamed task state and artifacts are folded into the persisted snapshot, delegated background Responses are rejected before budget admission and job creation, and direct delegation now rejects expired backing API keys. The full backend suite, go vet, frontend tests/typecheck/build, all 122 repository tests and gates, three Compose renders, native installer tests, git diff check, and all required GitHub checks pass. I found no remaining code blocker. Approval still requires the PR body to preserve the current template: add the required English title/body checklist item and record explicit pass results for the first four Verification commands. The Linux-only container entrypoint test and SDK process smoke were not rerun locally; the corresponding GitHub Deployment and backend checks are green.

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