A2A bridge
Purpose
Agentweaver keeps the workflow graph, graph-level approval gates, checkpoints, and durable persistence in the orchestration host. It sends each leaf agent turn to AgentHost over A2A HTTP+JSON. Structured run events cross that boundary and are persisted by the caller's event pipeline; pod-local tool approval waits have a separate return path.
RemoteAgentProxy implements the workflow agent surface on the worker. It forwards a turn, receives streamed output and run events, and re-emits them to the local runtime.
AgentHost hosts an A2ATurnBridgeAgent around the provider-backed runtime. It exposes POST /a2a/agent/v1/message:stream and GET /a2a/agent/v1/card on port 8088 by default.
Workflow agents
RemoteWorkflowAgentFactory returns RemoteAgentProxy for five workflow agents:
- worker
- RAI
- Rubberduck
- Build/Test
- Scribe
The Operator Assistant also uses RemoteAgentProxy, outside IWorkflowAgentFactory.
Turn and event transport
The worker sends turn setup as the first A2A DataContent part. This setup contains workspace and repository context, model and system-prompt data, project and agent identity, and revision state.
AgentHost sends assistant updates and structured RunEvent values through the same stream. RunEventDataPartCodec serializes the run events, which the worker appends to its local event pipeline.
See the canonical A2A sequence. Transport EOF alone is not success: the proxy checks the definitive turn-end marker and structured failures.
Warm-pool configuration
AgentHost starts in standby without a run identity. When the API claims a warm pod, it makes one POST /configure request. The request includes run, project, agent, and purpose identity; shared and local workspace descriptors; turn authentication; approval settings; and provider configuration.
The provider payload is either copilotCredential or byokProviderConfiguration. Repository, preview, and MCP broker credentials are optional and purpose-scoped.
The claim/configure sequence distinguishes listener liveness from configured readiness. /healthz returns HTTP 200 with standby before configuration and ready afterward. /configure accepts one configuration per pod; a second attempt returns 409. Other nonexempt requests return 503 before setup completes.
Production launch supplies a fresh turn bearer. The A2A middleware compares it when a nonempty token is configured; the optional request field is not unconditional endpoint enforcement. /configure cannot authenticate with the token it delivers. NetworkPolicy and configured transport protections are separate controls; the additive preview ingress range also includes port 8088 (see network-policy limitations).
The claim is also stamped with the active durable run-lease fencing token. After process recovery or child-dispatch takeover increments that token, a new API worker rejects the older claim, stops its pod, and configures a replacement before delivering another turn. This prevents two AgentHost turns from sharing one run identity or publishing competing worktree results.
Security boundary
The sandbox pod has no database connection and does not hold an ICheckpointStore. It cannot retrieve ambient user credentials from Key Vault, CSI volumes, shared storage, or host configuration.
The A2A turn token is unique to the run. A token from one pod cannot authorize a turn against another pod.
Source
apps/Agentweaver.Api/Sandbox/RemoteWorkflowAgentFactory.csapps/Agentweaver.Api/Sandbox/KubernetesSandboxExecutor.csapps/Agentweaver.AgentHost/Program.csapps/Agentweaver.AgentHost/A2ATurnBridgeAgent.cs
Visual model
Coordinator-to-agent communication and A2A runtime
Structured source · Editable draw.io
Related reading
Diagram details and constraints
| Element | Contract |
|---|---|
| title | A2A remotes a leaf turn, not the graph |
| takeaway | Setup and task cross to AgentHost; assistant output and structured events return. |
| Workflow graph | Workflow graph |
| Workflow graph | Host owns gates/checkpoints |
| Workflow graph | Five factory-created leaf types |
| RemoteAgentProxy | RemoteAgentProxy |
| RemoteAgentProxy | Build setup DataContent |
| RemoteAgentProxy | Task TextContent in same message |
| AgentHost bridge | AgentHost bridge |
| AgentHost bridge | message:stream over HTTP+JSON |
| AgentHost bridge | Apply per-turn context |
| Caller event pipeline | Caller event pipeline |
| Caller event pipeline | Decoded structured events |
| Caller event pipeline | Durable state outside pod |
| Proxy stream decoder | Proxy stream decoder |
| Proxy stream decoder | Output + RunEventDataPart |
| Proxy stream decoder | Check definitive turn end |
| Leaf runtime | Leaf runtime |
| Leaf runtime | Execute provider/tool loop |
| Leaf runtime | Stream updates and events |
| arrow-1 | invoke |
| arrow-2 | send |
| arrow-3 | run |
| arrow-4 | stream |
| arrow-5 | append |
| note-0 | Claim/configure is a separate lifecycle, completed before this exchange. |
| note-1 | EOF alone is not successful completion; structured failures remain failures. |
| notes | Claim/configure is a separate lifecycle, completed before this exchange.; EOF alone is not successful completion; structured failures remain failures. |
Diagram details and constraints
| Element | Contract |
|---|---|
| title | Bind, reach standby, configure once |
| takeaway | Liveness precedes configuration; production delivers run credentials out of pod specs. |
| Prepare launch | Prepare launch |
| Prepare launch | Resolve provider and run context |
| Prepare launch | Mint fresh turn token |
| Claim warm pod | Claim warm pod |
| Claim warm pod | Create/adopt; omit spec.env |
| Claim warm pod | Wait Ready + bound pod name |
| Resolve and register | Resolve and register |
| Resolve and register | Pod mapping / token registry |
| Resolve and register | Resolve actual pod IP |
| GET /healthz | GET /healthz |
| GET /healthz | HTTP 200 standby |
| GET /healthz | Listener liveness, not turn ready |
| POST /configure | POST /configure |
| POST /configure | Identity / workspace / approvals |
| POST /configure | Copilot capability OR BYOK |
| AgentHost setup | AgentHost setup |
| AgentHost setup | One-time configuration |
| AgentHost setup | Effective workspace + HOME |
| Configuration guards | Configuration guards |
| Configuration guards | Second configure: 409 |
| Configuration guards | Other routes: 503 before ready |
| Register effective endpoint | Register effective endpoint |
| Register effective endpoint | Return effective working directory |
| Register effective endpoint | Shared/local/private fallback |
| First A2A turn | First A2A turn |
| First A2A turn | Production sends turn bearer |
| First A2A turn | Equality guard when nonempty |
| arrow-1 | launch |
| arrow-2 | bound |
| arrow-3 | poll |
| arrow-4 | reachable |
| arrow-5 | setup |
| arrow-6 | ready |
| arrow-7 | invoke |
| note-0 | Top, middle and bottom rows are successive launch stages. |
| note-1 | Repository / preview / broker credentials have separate purposes. |
| note-2 | Optional schema fields do not imply unconditional endpoint enforcement. |
| notes | Top, middle and bottom rows are successive launch stages.; Repository / preview / broker credentials have separate purposes.; Optional schema fields do not imply unconditional endpoint enforcement. |

