Skip to content

Releases: firstintent/a2a-bridge

v0.2.0 — Multi-target routing

15 Apr 18:06
cd16871

Choose a tag to compare

a2a-bridge v0.2.0 — Multi-target routing

One daemon can now front multiple Claude Code workspaces at
once. ACP and A2A callers pick which one they want via a
kind:id TargetId; single-CC deployments keep working without
any config change.

Highlights

  • TargetId model. Every attached agent is addressed as
    kind:id (e.g. claude:proj-a, codex:default). Validated at
    every boundary; no more silent fallback to default.
  • Plugin-side workspace id. a2a-bridge claude announces its
    TargetId on attach, derived from A2A_BRIDGE_WORKSPACE_ID
    A2A_BRIDGE_STATE_DIR basename → conversation id → default.
    Two CC sessions with different state-dirs attach as distinct
    targets with no extra config.
  • a2a-bridge acp --target <kind:id>. ACP callers pick the
    target. Missing flag keeps v0.1 behaviour.
  • A2A contextId → TargetId routing. Operator-supplied map
    via A2A_BRIDGE_CONTEXT_ROUTES (JSON env var). Unmapped
    contexts fall back to claude:default. Validated at startup.
  • Outbound reply targeting. CC's reply tool gains an
    optional target field. Present → daemon forwards to that
    Room; absent → today's behaviour.
  • Attach conflict policy. Two CCs claiming the same TargetId:
    the second is rejected with a descriptive error naming the
    incumbent. Re-run with a2a-bridge claude --force (or
    A2A_BRIDGE_FORCE_ATTACH=1) to take over — the evicted session
    receives a CC-visible notification.
  • a2a-bridge daemon targets. New inspection subcommand.
    Prints a plain-text table of every TargetId the daemon tracks,
    with attach state, the WS connection id, and uptime since the
    attach landed.
  • Per-target inbound gateway. Inbound A2A/ACP text for
    claude:ws-a lands only on CC-A's socket, and CC-A's reply can
    only close CC-A's in-flight turn — no cross-target leakage.
  • session/load compatibility. Advertised + implemented as a
    stateless no-op so OpenClaw acpx's "persistent session" mode
    can respawn the subprocess without losing its prompt.

Backward compatibility

All additions are opt-in. v0.1 plugins / subprocesses work
unchanged against a v0.2 daemon and vice versa. Callers that
don't supply --target / contextRoutes route to
claude:default, matching today's behaviour.

Deferred to v0.3

  • Codex peer-id routing (a2a-bridge codex --id <id>). Unlike
    claude, codex is a daemon-internal adapter; multi-instancing
    requires a per-id peer registry + port allocation refactor that
    didn't fit v0.2. Codex remains codex:default (single
    instance).
  • Hot-reload of contextRoutes (startup-time only today).
  • Dynamic target discovery on the ACP side.

Control-plane wire additions (for embedders)

  • claude_connect grows { target?: string; force?: boolean }.
  • New server → plugin frames:
    • claude_connect_rejected { target, reason }
    • claude_connect_replaced { target }
  • acp_turn_start grows { target?: string }.
  • claude_to_codex grows { target?: string }.
  • New RPC pair: list_targets { requestId }
    targets_response { requestId, targets: TargetEntry[] }.

Install

npm install -g a2a-bridge@0.2.0

Upgrade notes

  • Nothing breaks if you weren't using --target /
    contextRoutes.
  • If you had scripts greping a2a-bridge daemon targets for
    claude:default, they now only match when a v0.1-style attach
    (no explicit target) is actually live.
  • ACP clients running in "persistent session" mode (OpenClaw
    acpx) that previously failed on session/load will start
    working without further config changes.

Docs


Full changelog: see CHANGELOG.md.
Previous release: v0.1.0.