Skip to main content
is the execution router between Convex and gateway runtimes. It accepts dispatch requests from Convex, delegates them to the appropriate ExecutionAdapter, streams events via SSE, and delivers results back to Convex via callbacks. Bridge is not middleware — it does not transform data or apply business logic.

BridgeWhat Bridge Does

ResponsibilityHow
Route dispatchReceives step execution requests from Convex, selects the correct adapter by provider name, calls adapter.execute()
Stream eventsSSE endpoint pushes execution events (tool calls, assistant text, progress) to connected Burgundy clients
Deliver callbacksPOSTs execution results to Convex callback URLs with 3x retry and exponential backoff
Manage adaptersLoads one or more adapters at startup, initializes each, runs health checks
Gateway APIProxies management requests (agent CRUD, skill sync, model discovery) to adapters that support RuntimeManager

BridgeBridge Dispatch Flow

Bridge Dispatch Flow

1
ConvexConvex InterpreterGovernance gates passed

Sends dispatch payload: taskId, agentId, message, systemPrompt, model, tools, timeout, callbackUrl

HTTP POST /api/v2/dispatch
2
BridgeBridge ServerValidates request, authenticates token

Parses body, verifies gateway token hash, builds ExecutionRequest from dispatch payload.

adapter.execute(request)
3
🔌 Gateway AdapterExecutes on runtime

Translates ExecutionRequest to runtime-native format. Runs the task. Returns ExecutionResult with output, usage, cost.

callback to convex (3x retry)
4
ConvexConvex Callback HandlerIdempotent, deduped

Records step result, token events, and cost. Fires completion event to interpreter. Dedup via callbackDedup table.

📺 SSE Stream· Live events to Burgundy during steps 2-3
tool.invokedassistant.textexec.progresstool.completed
Convex
Bridge
Gateway
SSE

🔧 The ExecutionAdapter Interface

Every gateway adapter implements a single interface. The contract is intentionally thin — accept a normalized request, execute it, return a normalized result.
interface ExecutionAdapter {
  readonly provider: string;              // "openclaw" | "claude-agent-sdk" | "vercel-ai" | "gloo-ai"
  initialize(config: AdapterConfig): Promise<void>;
  shutdown(): Promise<void>;
  checkHealth(): Promise<AdapterHealthStatus>;
  capabilities(): GatewayCapabilities;
  execute(request: ExecutionRequest): Promise<ExecutionResult>;
  cancel(taskHandle: string): Promise<boolean>;
  onEvent?(listener: ExecutionEventListener): void;
  offEvent?(listener: ExecutionEventListener): void;
}
Bridge handles everything else: prompt assembly from workspace files, tool spec normalization, output strategy selection, and callback delivery. The adapter’s only job is to run the task and return a result.

Multi-Adapter Mode

A single Bridge instance can load multiple adapters simultaneously. Set the BRIDGE_ADAPTERS environment variable to a comma-separated list of provider names (e.g., BRIDGE_ADAPTERS=openclaw,gloo-ai). Bridge initializes each adapter at startup and routes each dispatch request to the correct adapter based on the provider field in the request payload. This replaces the earlier one-Bridge-per-adapter deployment model — multiple gateways can now share a single Bridge URL.

📥 ExecutionRequest

The bridge builds a fully-assembled, gateway-agnostic execution request before passing it to the adapter:
FieldTypeDescription
taskIdstringUnique identifier generated by Bridge
agentIdstringPlatform agent ID for logging and telemetry
messagestringThe work to perform (command + stdin + output instructions)
systemPromptstring?Fully assembled system prompt (SOUL.md + agent config)
modelstring?Requested model (e.g., claude-sonnet-4-6)
toolsNormalizedTool[]?Normalized tool definitions for the adapter to translate
mcpServersMcpServerSpec[]?MCP server configurations
timeoutSecondsnumberMaximum execution time
outputStrategyOutputStrategyHow results should be captured (file, stream, or structured)
resumeTokenstring?Resume a prior conversation session
metadataRecord?Opaque workflow context (run_id, step_id, cwd)

📤 ExecutionResult

Every adapter returns a normalized result:
FieldTypeDescription
status"ok" | "error"Execution outcome
outputstring?Agent’s output text
outputsRecord?Structured outputs (parsed by adapter)
durationMsnumberExecution duration
usageNormalizedUsage?Token counts (input, output, thinking, cache)
costUsdnumber?Cost in USD if the runtime provides it
modelstring?Actual model used (may differ from requested)
resumeTokenstring?Token for session continuity
conversationMessagesConversationMessage[]?Full LLM conversation captured during execution

🔌 Built-in Adapters

Package: @tangogroup/adapter-openclawStateful daemon. Stores agent configs, manages workspace files, supports MCP and sandboxing. The most full-featured adapter.Interfaces implemented: ExecutionAdapter, RuntimeManager, AgentManager, SkillManager, SystemManager
CapabilitySupported
StreamingYes
Session ResumeYes
File I/OYes
MCP ServersYes
SandboxingYes
Cost TrackingYes
ManagementYes

📺 SSE Event Streaming

Bridge maintains an SSE endpoint that Burgundy clients connect to for real-time execution events:
GET /api/events → Server-Sent Events stream
Events follow a standard shape:
Event typeEmitted whenData
execution.startedAdapter begins executiontaskId, agentId
assistant.textLLM produces output texttaskId, content
tool.invokedAgent calls a tooltaskId, toolName, input
tool.completedTool returns a resulttaskId, toolName, output
execution.progressAdapter reports progresstaskId, custom data
execution.completedExecution finishes successfullytaskId, output, usage
execution.failedExecution failstaskId, error, errorCode
Adapters that support streaming (OpenClaw, Claude Agent SDK, Gloo AI) emit events during execution. Adapters that do not (Vercel AI) emit only execution.started and execution.completed/execution.failed.

🔄 Callback Handling

When execution completes, Bridge delivers the result to Convex via an HTTP callback:
  1. Bridge POSTs the ExecutionResult to the callback URL provided in the dispatch request.
  2. On failure, Bridge retries up to 3 times with exponential backoff.
  3. Convex deduplicates callbacks using the callbackDedup table (keyed on taskId). Duplicate callbacks are acknowledged but not processed.
  4. On successful delivery, Convex records the step result, creates token events for cost tracking, and fires a completion event to the interpreter.
If all 3 callback attempts fail, the step remains in a “running” state. Convex’s step timeout enforcer (runs every 60 seconds) will detect the stalled step and apply the on_failure policy.

🧩 Management Sub-Interfaces

Adapters may optionally implement management interfaces for richer platform integration:
InterfaceMethodsUsed by
AgentManagerlistAgents, createAgent, updateAgent, deleteAgent, file/binding managementOpenClaw
SkillManagerlistSkills, readSkill, writeSkill, deleteSkill, dependency installationOpenClaw
SystemManagerreloadConfig, getModelCatalog, getSecurityPostureOpenClaw
Bridge detects these interfaces via type guards (isAgentManager(), isSkillManager(), isSystemManager()) and exposes the corresponding gateway API routes only when the loaded adapter supports them. See also: System Overview | Gateways | Workflow Execution Flow