feat: add AgentInstance A2A gateway - #2446
Conversation
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
There was a problem hiding this comment.
Pull request overview
This PR introduces an authenticated A2A gRPC gateway path for AgentInstance interactions by adding a transport-neutral gateway handler, a runtime dialer that routes via Atenet using :authority, and wiring the handler into controller-v2’s gRPC server. It also formalizes a public, logical AgentInstance authority format (<uuid>.<namespace>.agents) and persists it when instances become READY.
Changes:
- Persist a logical public A2A authority on
AgentInstancereadiness and add parsing/validation helpers (+ unit tests). - Add an A2A gateway handler that authenticates/authorizes, resolves
AgentInstancefrom storage, then proxies A2A calls to the private runtime. - Wire A2A handler registration + method policies into the shared gRPC server and controller-v2 startup (including an Atenet-based runtime dialer).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| go/core/v2/agentinstance/workflow.go | Stores public logical A2A authority when an instance transitions to READY. |
| go/core/v2/agentinstance/authority.go | Defines logical authority format and strict parsing/validation for gateway routing. |
| go/core/v2/agentinstance/authority_test.go | Adds round-trip and rejection tests for authority parsing. |
| go/core/v2/a2agateway/runtime.go | Implements Atenet-backed dialer that routes to private Actor via grpc.WithAuthority and forwards auth/trace. |
| go/core/v2/a2agateway/gateway.go | Adds authenticated/authorized A2A request handler that resolves and proxies to instance runtime. |
| go/core/v2/a2agateway/gateway_test.go | Adds unit tests for authority resolution, authz lookup, and runtime lifecycle (including gRPC authority read). |
| go/core/internal/grpcserver/server.go | Adds optional A2A handler registration to the shared gRPC server. |
| go/core/internal/grpcserver/policy.go | Registers A2A RPCs in the default method policy map so auth middleware can authorize them. |
| go/core/cmd/controller-v2/main.go | Wires the gateway and runtime dialer into controller-v2’s gRPC server configuration. |
Suppressed comments (1)
go/core/v2/a2agateway/gateway.go:85
- The gateway returns internal errors to clients with the raw upstream dial error string. That can leak network topology/details (targets, DNS, cert errors). Prefer a generic message and log the detailed error on the server side.
client, err := g.dialer.Dial(ctx, instance)
if err != nil {
return nil, a2atype.NewError(a2atype.ErrInternalError, fmt.Sprintf("connect to AgentInstance runtime: %v", err))
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if err != nil { | ||
| return nil, a2atype.NewError(a2atype.ErrInternalError, fmt.Sprintf("load AgentInstance: %v", err)) | ||
| } |
There was a problem hiding this comment.
Fixed in ac21f91: the gateway now logs underlying storage and dial failures server-side while returning generic internal errors to callers. Added regression coverage for both paths.
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Summary
This is the routing/proxy slice of K10. Durable public Task persistence, public/private ID mapping, ordering, and idempotency remain follow-up work.
Testing