This document describes the internal structure, module boundaries, and main request call chains of opencode-a2a. It is intended for maintainers and contributors. Use architecture.md for the higher-level service boundary view and guide.md for deployment-facing runtime configuration.
flowchart TD
subgraph Inbound["Server Layer (src/opencode_a2a/server/)"]
App["application.py (FastAPI assembly)"]
Middleware["middleware.py"]
AgentCard["agent_card.py / openapi.py"]
end
subgraph Execution["Execution Layer (src/opencode_a2a/execution/)"]
Executor["executor.py"]
Coordinator["coordinator.py"]
StreamRuntime["stream_runtime.py"]
ToolOrch["tool_orchestration.py"]
end
subgraph Upstream["OpenCode Upstream Layer"]
UpstreamClient["opencode_upstream_client.py"]
Invocation["invocation.py"]
end
subgraph Extensions["Extension / Contract Layer"]
Jsonrpc["jsonrpc/"]
Contracts["contracts/extensions.py"]
Profile["profile/runtime.py"]
end
subgraph Persistence["Persistence Layer"]
TaskStore["server/task_store.py"]
StateStore["server/state_store.py"]
Migrations["server/migrations.py"]
end
Inbound --> Execution
Inbound --> Extensions
Execution --> Upstream
Inbound --> Persistence
Execution --> Persistence
server/application.pyassembles the FastAPI app, SDK adapters, and middleware stack.server/middleware.pyhandles auth, request sizing, protocol negotiation, logging, and response headers.- The SDK-backed handler delegates execution to
execution/executor.py. - The execution layer coordinates session continuity, stream handling, tool calls, and error translation through:
execution/coordinator.pyexecution/stream_runtime.pyexecution/tool_orchestration.py
opencode_upstream_client.pysends requests to the upstream OpenCode runtime.- The adapter maps upstream responses back into A2A tasks, messages, artifacts, and stream events.
jsonrpc/application.pyowns the adapter-specific JSON-RPC application boundary.jsonrpc/dispatch.pyand handler modules underjsonrpc/handlers/route provider-private methods.contracts/extensions.pyremains the SSOT for extension metadata exposed through Agent Card and OpenAPI.- Tests under
tests/contracts/andtests/jsonrpc/guard contract drift.
- CLI or server-side tool execution asks
server/client_manager.pyfor an outbound client. client/builds and configures the embedded A2A client facade.- Outbound peer responses are normalized before being reintroduced into the local runtime surface.
server/application.py: app assembly, route wiring, request handler customization, and top-level lifecycle integrationserver/middleware.py: auth, protocol negotiation, payload/body guards, logging, and response decorationserver/agent_card.py/server/openapi.py: machine-readable contract publicationserver/rest_tasks.py: SDK-owned REST task routes plus adapter-specific list behavior
execution/executor.py: main orchestration entrypointexecution/coordinator.py: OpenCode session coordination and request shapingexecution/stream_runtime.py/execution/stream_events.py: stream normalization and event conversionexecution/tool_orchestration.py: embedded peer-call tool handlingexecution/upstream_error_translator.py/execution/tool_error_mapping.py: upstream-facing error normalization
contracts/extensions.py: SSOT for extension metadata, compatibility profile, and wire-contract payloadsjsonrpc/: provider-private JSON-RPC extension surfaceprofile/runtime.py: runtime profile that feeds Agent Card, OpenAPI, and compatibility metadataprotocol_versions.py: protocol normalization and negotiation helpers
server/task_store.py: SDK task store construction plus adapter policy wrappersserver/state_store.py: session binding and interrupt repositoriesserver/migrations.py: adapter-managed state schema migrations
client/: outbound peer card discovery, request context, auth handling, polling fallback, and error mapping
- SDK task rows stored through the configured task store backend
- adapter-managed session binding / ownership state
- interrupt request bindings and tombstones
- pending preferred-session claims
The custom migration runner owns only adapter-managed state tables; SDK-managed task schema still follows the SDK path.
Configuration is handled in config.py with pydantic-settings.
A2A_*: inbound runtime, outbound peer client, protocol, persistence, and deployment metadataOPENCODE_*: upstream OpenCode connection and request behavior
For maintainers new to the codebase, this order usually gives the fastest payoff:
README.mddocs/architecture.mdsrc/opencode_a2a/server/application.pysrc/opencode_a2a/execution/executor.pysrc/opencode_a2a/contracts/extensions.pydocs/guide.md