opencode-a2a-server 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/.secrets.baseline +2 -12
- opencode_a2a_server-0.2.2/CONTRIBUTING.md +79 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/PKG-INFO +96 -55
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/README.md +94 -53
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/SECURITY.md +4 -4
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/docs/guide.md +125 -14
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/pyproject.toml +2 -2
- opencode_a2a_server-0.2.2/scripts/README.md +22 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/agent.py +23 -8
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/app.py +205 -84
- opencode_a2a_server-0.2.2/src/opencode_a2a_server/cli.py +53 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/config.py +3 -26
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/extension_contracts.py +237 -21
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/jsonrpc_ext.py +57 -116
- opencode_a2a_server-0.2.2/src/opencode_a2a_server/jsonrpc_models.py +123 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/opencode_client.py +1 -1
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/PKG-INFO +96 -55
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/SOURCES.txt +7 -24
- opencode_a2a_server-0.2.2/src/opencode_a2a_server.egg-info/entry_points.txt +2 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/requires.txt +1 -1
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/helpers.py +1 -1
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_agent_card.py +96 -17
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_cancel_contract.py +61 -0
- opencode_a2a_server-0.2.2/tests/test_cli.py +58 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_directory_validation.py +1 -1
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_extension_contract_consistency.py +54 -4
- opencode_a2a_server-0.2.2/tests/test_jsonrpc_models.py +57 -0
- opencode_a2a_server-0.2.2/tests/test_jsonrpc_unsupported_method.py +85 -0
- opencode_a2a_server-0.2.2/tests/test_metrics.py +201 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_opencode_client_params.py +7 -7
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_opencode_session_extension.py +215 -20
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_settings.py +7 -4
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_transport_contract.py +4 -2
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/uv.lock +4 -4
- opencode_a2a_server-0.2.0/docs/agent_deploy_sop.md +0 -292
- opencode_a2a_server-0.2.0/docs/release_deploy_smoke_test.md +0 -188
- opencode_a2a_server-0.2.0/scripts/README.md +0 -34
- opencode_a2a_server-0.2.0/scripts/deploy/enable_instance.sh +0 -135
- opencode_a2a_server-0.2.0/scripts/deploy/install_release_runtime.sh +0 -52
- opencode_a2a_server-0.2.0/scripts/deploy/install_units.sh +0 -110
- opencode_a2a_server-0.2.0/scripts/deploy/provider_secret_env_keys.sh +0 -69
- opencode_a2a_server-0.2.0/scripts/deploy/run_a2a.sh +0 -18
- opencode_a2a_server-0.2.0/scripts/deploy/run_opencode.sh +0 -80
- opencode_a2a_server-0.2.0/scripts/deploy/setup_instance.sh +0 -485
- opencode_a2a_server-0.2.0/scripts/deploy/update_a2a.sh +0 -27
- opencode_a2a_server-0.2.0/scripts/deploy.sh +0 -350
- opencode_a2a_server-0.2.0/scripts/deploy_readme.md +0 -332
- opencode_a2a_server-0.2.0/scripts/deploy_release.sh +0 -8
- opencode_a2a_server-0.2.0/scripts/deploy_release_readme.md +0 -72
- opencode_a2a_server-0.2.0/scripts/init_release_system.sh +0 -15
- opencode_a2a_server-0.2.0/scripts/init_release_system_readme.md +0 -41
- opencode_a2a_server-0.2.0/scripts/init_system.sh +0 -843
- opencode_a2a_server-0.2.0/scripts/init_system_readme.md +0 -69
- opencode_a2a_server-0.2.0/scripts/init_system_uv_release_manifest.sh +0 -17
- opencode_a2a_server-0.2.0/scripts/shell_helpers.sh +0 -28
- opencode_a2a_server-0.2.0/scripts/uninstall.sh +0 -378
- opencode_a2a_server-0.2.0/scripts/uninstall_readme.md +0 -39
- opencode_a2a_server-0.2.0/src/opencode_a2a_server.egg-info/entry_points.txt +0 -2
- opencode_a2a_server-0.2.0/tests/test_deploy_security_contract.py +0 -148
- opencode_a2a_server-0.2.0/tests/test_init_system_security.py +0 -101
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/.github/workflows/ci.yml +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/.github/workflows/dependency-health.yml +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/.github/workflows/publish.yml +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/.gitignore +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/.pre-commit-config.yaml +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/AGENTS.md +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/LICENSE +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/scripts/dependency_health.sh +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/scripts/doctor.sh +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/scripts/health_common.sh +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/scripts/lint.sh +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/scripts/smoke_test_built_cli.sh +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/setup.cfg +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/__init__.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/parts_mapper.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/text_parts.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/dependency_links.txt +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/top_level.txt +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/__init__.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_agent_errors.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_call_context_builder.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_cancellation.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_multipart_input.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_opencode_agent_session_binding.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_script_health_contract.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_session_ownership.py +0 -0
- {opencode_a2a_server-0.2.0 → opencode_a2a_server-0.2.2}/tests/test_streaming_output_contract.py +0 -0
|
@@ -126,16 +126,6 @@
|
|
|
126
126
|
"path": "detect_secrets.filters.heuristic.is_templated_secret"
|
|
127
127
|
}
|
|
128
128
|
],
|
|
129
|
-
"results": {
|
|
130
|
-
|
|
131
|
-
{
|
|
132
|
-
"type": "Hex High Entropy String",
|
|
133
|
-
"filename": "scripts/init_system.sh",
|
|
134
|
-
"hashed_secret": "96183ea4ff07d786ed3233777364ddbf14eb74cc",
|
|
135
|
-
"is_verified": false,
|
|
136
|
-
"line_number": 25
|
|
137
|
-
}
|
|
138
|
-
]
|
|
139
|
-
},
|
|
140
|
-
"generated_at": "2026-03-17T13:35:29Z"
|
|
129
|
+
"results": {},
|
|
130
|
+
"generated_at": "2026-03-19T03:57:43Z"
|
|
141
131
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for contributing to `opencode-a2a-server`.
|
|
4
|
+
|
|
5
|
+
This repository is maintained as a streaming-first A2A wrapper around OpenCode.
|
|
6
|
+
Changes should keep runtime behavior, Agent Card declarations, OpenAPI examples,
|
|
7
|
+
and machine-readable extension contracts aligned.
|
|
8
|
+
|
|
9
|
+
## Before You Start
|
|
10
|
+
|
|
11
|
+
- Read [README.md](README.md) for project scope and user/operator paths.
|
|
12
|
+
- Read [docs/guide.md](docs/guide.md) for runtime contracts and compatibility guidance.
|
|
13
|
+
- Read [SECURITY.md](SECURITY.md) before changing auth, deployment, or secret handling.
|
|
14
|
+
|
|
15
|
+
## Development Setup
|
|
16
|
+
|
|
17
|
+
Requirements:
|
|
18
|
+
|
|
19
|
+
- Python 3.11, 3.12, or 3.13
|
|
20
|
+
- `uv`
|
|
21
|
+
- A reachable OpenCode runtime if you need end-to-end manual checks
|
|
22
|
+
|
|
23
|
+
Install dependencies:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
uv sync --all-extras
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Run the local development server:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
A2A_BEARER_TOKEN=dev-token \
|
|
33
|
+
OPENCODE_DIRECTORY=/abs/path/to/workspace \
|
|
34
|
+
uv run opencode-a2a-server
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Validation
|
|
38
|
+
|
|
39
|
+
Run the default validation baseline before opening a PR:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uv run pre-commit run --all-files
|
|
43
|
+
uv run pytest
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
If you change shell or deployment scripts, also run:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
bash -n scripts/deploy.sh
|
|
50
|
+
bash -n scripts/deploy/setup_instance.sh
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Change Expectations
|
|
54
|
+
|
|
55
|
+
- Keep code, comments, and docs in English.
|
|
56
|
+
- Keep issue / PR discussion in Simplified Chinese when collaborating in this repository.
|
|
57
|
+
- Do not drift Agent Card, OpenAPI examples, wire contract metadata, and runtime behavior.
|
|
58
|
+
- Prefer additive, explicit compatibility changes over silent behavior changes.
|
|
59
|
+
- Treat `opencode.*` surfaces as provider-private unless the repository already defines them as shared A2A contracts.
|
|
60
|
+
|
|
61
|
+
## Git and PR Workflow
|
|
62
|
+
|
|
63
|
+
- Branch from the latest `main`.
|
|
64
|
+
- Use `git fetch` and `git merge --ff-only` to sync mainline.
|
|
65
|
+
- Do not push directly to protected branches.
|
|
66
|
+
- Link the relevant issue in commits and PR descriptions when applicable.
|
|
67
|
+
- Open PRs as Draft by default when the change still needs review or iteration.
|
|
68
|
+
|
|
69
|
+
## Documentation
|
|
70
|
+
|
|
71
|
+
Update docs together with code whenever you change:
|
|
72
|
+
|
|
73
|
+
- authentication or deployment behavior
|
|
74
|
+
- extension contracts or compatibility expectations
|
|
75
|
+
- user-facing request or response shapes
|
|
76
|
+
- operational scripts
|
|
77
|
+
|
|
78
|
+
Keep compatibility guidance centralized in [docs/guide.md](docs/guide.md) unless a
|
|
79
|
+
new standalone document is clearly necessary.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencode-a2a-server
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A2A wrapper service for opencode
|
|
5
5
|
Author: liujuanjuan1984@Intelligent-Internet
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -19,7 +19,7 @@ Classifier: Topic :: Internet :: WWW/HTTP
|
|
|
19
19
|
Requires-Python: >=3.11
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
-
Requires-Dist: a2a-sdk==0.3.
|
|
22
|
+
Requires-Dist: a2a-sdk==0.3.25
|
|
23
23
|
Requires-Dist: fastapi>=0.110
|
|
24
24
|
Requires-Dist: httpx>=0.27
|
|
25
25
|
Requires-Dist: pydantic>=2.6
|
|
@@ -38,12 +38,12 @@ Dynamic: license-file
|
|
|
38
38
|
|
|
39
39
|
# opencode-a2a-server
|
|
40
40
|
|
|
41
|
-
> Turn OpenCode into a stateful A2A service with a clear runtime boundary
|
|
41
|
+
> Turn OpenCode into a stateful A2A service with a clear runtime boundary.
|
|
42
42
|
|
|
43
43
|
`opencode-a2a-server` exposes OpenCode through standard A2A interfaces and adds
|
|
44
|
-
the
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
the runtime pieces that raw agent runtimes usually do not provide by default:
|
|
45
|
+
authentication, session continuity, streaming contracts, interrupt handling,
|
|
46
|
+
and explicit security guidance.
|
|
47
47
|
|
|
48
48
|
## Why This Project Exists
|
|
49
49
|
|
|
@@ -52,7 +52,8 @@ need a stable service layer around it. This repository provides that layer by:
|
|
|
52
52
|
|
|
53
53
|
- bridging A2A transport contracts to OpenCode session/message/event APIs
|
|
54
54
|
- making session and interrupt behavior explicit and auditable
|
|
55
|
-
-
|
|
55
|
+
- keeping the server/runtime contract explicit while leaving deployment
|
|
56
|
+
supervision to the operator
|
|
56
57
|
|
|
57
58
|
## What It Already Provides
|
|
58
59
|
|
|
@@ -64,7 +65,7 @@ need a stable service layer around it. This repository provides that layer by:
|
|
|
64
65
|
- session continuation via `metadata.shared.session.id`
|
|
65
66
|
- request-scoped model selection via `metadata.shared.model`
|
|
66
67
|
- OpenCode session query/control extensions and provider/model discovery
|
|
67
|
-
- released CLI install/upgrade flow and
|
|
68
|
+
- released CLI install/upgrade flow and a foreground runtime entrypoint
|
|
68
69
|
|
|
69
70
|
## Extension Capability Overview
|
|
70
71
|
|
|
@@ -88,13 +89,17 @@ Detailed consumption guidance:
|
|
|
88
89
|
- Shared stream hints: [`docs/guide.md#shared-stream-hints-contract`](docs/guide.md#shared-stream-hints-contract)
|
|
89
90
|
- OpenCode session query and provider discovery: [`docs/guide.md#opencode-session-query--provider-discovery-a2a-extensions`](docs/guide.md#opencode-session-query--provider-discovery-a2a-extensions)
|
|
90
91
|
- Shared interrupt callback: [`docs/guide.md#shared-interrupt-callback-a2a-extension`](docs/guide.md#shared-interrupt-callback-a2a-extension)
|
|
92
|
+
- Compatibility profile and retention guidance:
|
|
93
|
+
[`docs/guide.md#compatibility-profile`](docs/guide.md#compatibility-profile)
|
|
91
94
|
|
|
92
95
|
## Design Principle
|
|
93
96
|
|
|
94
97
|
One `OpenCode + opencode-a2a-server` instance pair is treated as a
|
|
95
98
|
single-tenant trust boundary.
|
|
96
99
|
|
|
97
|
-
This repository's intended scaling model is parameterized self-deployment:
|
|
100
|
+
This repository's intended scaling model is parameterized self-deployment:
|
|
101
|
+
consumers should launch their own isolated instance pairs instead of sharing
|
|
102
|
+
one runtime across mutually untrusted tenants.
|
|
98
103
|
|
|
99
104
|
- OpenCode may manage multiple projects/directories, but one deployed instance
|
|
100
105
|
is not a secure multi-tenant runtime.
|
|
@@ -113,7 +118,6 @@ flowchart TD
|
|
|
113
118
|
Mapping --> Runtime["OpenCode HTTP runtime"]
|
|
114
119
|
|
|
115
120
|
Api --> Auth["Bearer auth + request logging controls"]
|
|
116
|
-
Api --> Deploy["release-based deployment tooling"]
|
|
117
121
|
Runtime --> Workspace["Shared workspace / environment boundary"]
|
|
118
122
|
```
|
|
119
123
|
|
|
@@ -139,13 +143,14 @@ hard multi-tenant isolation layer.
|
|
|
139
143
|
isolation boundary inside one deployed instance.
|
|
140
144
|
- LLM provider keys are consumed by the OpenCode process. Prompt injection or
|
|
141
145
|
indirect exfiltration attempts may still expose sensitive values.
|
|
142
|
-
-
|
|
143
|
-
|
|
146
|
+
- Deployment supervision is intentionally BYO. If you wrap this runtime with
|
|
147
|
+
`systemd`, Docker, Kubernetes, or another supervisor, you own the service
|
|
148
|
+
user, secret storage, restart policy, and hardening choices.
|
|
144
149
|
|
|
145
150
|
Read before deployment:
|
|
146
151
|
|
|
147
152
|
- [SECURITY.md](SECURITY.md)
|
|
148
|
-
- [
|
|
153
|
+
- [docs/guide.md](docs/guide.md)
|
|
149
154
|
|
|
150
155
|
## User Paths
|
|
151
156
|
|
|
@@ -182,12 +187,36 @@ opencode serve
|
|
|
182
187
|
|
|
183
188
|
A2A_BEARER_TOKEN=prod-token \
|
|
184
189
|
A2A_PUBLIC_URL=http://127.0.0.1:8000 \
|
|
185
|
-
|
|
186
|
-
opencode-a2a-server
|
|
190
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
191
|
+
opencode-a2a-server serve
|
|
187
192
|
```
|
|
188
193
|
|
|
194
|
+
`OPENCODE_WORKSPACE_ROOT` is the default workspace root that this runtime
|
|
195
|
+
exposes to OpenCode.
|
|
196
|
+
|
|
189
197
|
Default address: `http://127.0.0.1:8000`
|
|
190
198
|
|
|
199
|
+
Common runtime variables:
|
|
200
|
+
|
|
201
|
+
| Variable | Required | Default | Purpose |
|
|
202
|
+
| --- | --- | --- | --- |
|
|
203
|
+
| `A2A_BEARER_TOKEN` | Yes | None | Bearer token required for authenticated runtime requests. |
|
|
204
|
+
| `OPENCODE_BASE_URL` | No | `http://127.0.0.1:4096` | Upstream OpenCode HTTP endpoint. |
|
|
205
|
+
| `OPENCODE_WORKSPACE_ROOT` | No | None | Default workspace root exposed to OpenCode. |
|
|
206
|
+
| `OPENCODE_PROVIDER_ID` | No | None | Default provider for the upstream runtime. |
|
|
207
|
+
| `OPENCODE_MODEL_ID` | No | None | Default model for the upstream runtime. Set together with `OPENCODE_PROVIDER_ID`. |
|
|
208
|
+
| `A2A_HOST` | No | `127.0.0.1` | Bind host for the A2A server. |
|
|
209
|
+
| `A2A_PORT` | No | `8000` | Bind port for the A2A server. |
|
|
210
|
+
| `A2A_PUBLIC_URL` | No | `http://127.0.0.1:8000` | Public base URL advertised by the Agent Card. |
|
|
211
|
+
| `A2A_LOG_LEVEL` | No | `WARNING` | Server log level. |
|
|
212
|
+
| `A2A_LOG_PAYLOADS` | No | `false` | Enable request/response payload logging. |
|
|
213
|
+
| `A2A_LOG_BODY_LIMIT` | No | `0` | Payload preview size used when payload logging is enabled. |
|
|
214
|
+
| `A2A_MAX_REQUEST_BODY_BYTES` | No | `1048576` | Maximum accepted request size. |
|
|
215
|
+
| `A2A_ALLOW_DIRECTORY_OVERRIDE` | No | `true` | Allow request-level `metadata.opencode.directory` overrides. |
|
|
216
|
+
| `A2A_ENABLE_SESSION_SHELL` | No | `false` | Enable high-risk `opencode.sessions.shell`. |
|
|
217
|
+
| `OPENCODE_TIMEOUT` | No | `120` | Upstream OpenCode request timeout in seconds. |
|
|
218
|
+
| `OPENCODE_TIMEOUT_STREAM` | No | None | Upstream OpenCode stream timeout override in seconds. |
|
|
219
|
+
|
|
191
220
|
If you omit `OPENCODE_PROVIDER_ID` / `OPENCODE_MODEL_ID`, `opencode serve`
|
|
192
221
|
uses your local OpenCode defaults (for example `~/.config/opencode/opencode.json`).
|
|
193
222
|
|
|
@@ -199,36 +228,63 @@ official docs and CLI:
|
|
|
199
228
|
- Local checks: `opencode auth list`, `opencode models`, `opencode models <provider>`
|
|
200
229
|
|
|
201
230
|
This path is for users who already manage their own shell, workspace, and
|
|
202
|
-
process lifecycle.
|
|
231
|
+
process lifecycle.
|
|
232
|
+
|
|
233
|
+
Use any supervisor you prefer for long-running operation:
|
|
203
234
|
|
|
204
|
-
|
|
235
|
+
- `systemd`
|
|
236
|
+
- Docker / container runtimes
|
|
237
|
+
- Kubernetes
|
|
238
|
+
- `supervisord`, `pm2`, or similar process managers
|
|
205
239
|
|
|
206
|
-
|
|
240
|
+
The project no longer ships built-in host bootstrap or process-manager
|
|
241
|
+
wrappers. The official product surface is the runtime entrypoint itself.
|
|
242
|
+
|
|
243
|
+
Minimal `systemd` example:
|
|
244
|
+
|
|
245
|
+
1. Create an env file such as `/etc/opencode-a2a/alpha.env`:
|
|
207
246
|
|
|
208
247
|
```bash
|
|
209
|
-
|
|
210
|
-
|
|
248
|
+
A2A_BEARER_TOKEN=replace-me
|
|
249
|
+
A2A_HOST=127.0.0.1
|
|
250
|
+
A2A_PORT=8000
|
|
251
|
+
A2A_PUBLIC_URL=https://a2a.example.com
|
|
252
|
+
OPENCODE_BASE_URL=http://127.0.0.1:4096
|
|
253
|
+
OPENCODE_WORKSPACE_ROOT=/srv/my-workspace
|
|
211
254
|
```
|
|
212
255
|
|
|
213
|
-
|
|
256
|
+
2. Create a unit file such as `/etc/systemd/system/opencode-a2a-server.service`:
|
|
257
|
+
|
|
258
|
+
```ini
|
|
259
|
+
[Unit]
|
|
260
|
+
Description=OpenCode A2A Server
|
|
261
|
+
After=network-online.target
|
|
262
|
+
Wants=network-online.target
|
|
214
263
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
-
|
|
218
|
-
-
|
|
264
|
+
[Service]
|
|
265
|
+
Type=simple
|
|
266
|
+
WorkingDirectory=/srv/my-workspace
|
|
267
|
+
EnvironmentFile=/etc/opencode-a2a/alpha.env
|
|
268
|
+
ExecStart=/home/dev/.local/bin/opencode-a2a-server serve
|
|
269
|
+
Restart=on-failure
|
|
270
|
+
RestartSec=2
|
|
219
271
|
|
|
220
|
-
|
|
272
|
+
[Install]
|
|
273
|
+
WantedBy=multi-user.target
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Replace `ExecStart` with the absolute path returned by `command -v opencode-a2a-server`.
|
|
221
277
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
-
|
|
225
|
-
-
|
|
278
|
+
Migration notes:
|
|
279
|
+
|
|
280
|
+
- `OPENCODE_DIRECTORY` has been removed. Use `OPENCODE_WORKSPACE_ROOT`.
|
|
281
|
+
- Built-in `init-release-system`, `deploy-release`, and `uninstall-instance` have been removed.
|
|
282
|
+
- Secret storage, service users, restart policy, and supervisor configuration are now operator-managed.
|
|
226
283
|
|
|
227
284
|
## Contributor Paths
|
|
228
285
|
|
|
229
286
|
Use the repository checkout directly only for development, local debugging, or
|
|
230
|
-
validation against unreleased changes.
|
|
231
|
-
kept for contributors and internal debugging, not as the recommended user path.
|
|
287
|
+
validation against unreleased changes.
|
|
232
288
|
|
|
233
289
|
Quick source run:
|
|
234
290
|
|
|
@@ -241,8 +297,8 @@ OPENCODE_MODEL_ID=gemini-3.1-pro-preview \
|
|
|
241
297
|
opencode serve
|
|
242
298
|
|
|
243
299
|
A2A_BEARER_TOKEN=dev-token \
|
|
244
|
-
|
|
245
|
-
uv run opencode-a2a-server
|
|
300
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
301
|
+
uv run opencode-a2a-server serve
|
|
246
302
|
```
|
|
247
303
|
|
|
248
304
|
Baseline validation:
|
|
@@ -254,32 +310,17 @@ uv run pytest
|
|
|
254
310
|
|
|
255
311
|
## Documentation Map
|
|
256
312
|
|
|
257
|
-
### User
|
|
313
|
+
### User Docs
|
|
258
314
|
|
|
259
315
|
- [docs/guide.md](docs/guide.md)
|
|
260
316
|
Product behavior, API contracts, and detailed streaming/session/interrupt
|
|
261
317
|
consumption guidance.
|
|
262
|
-
- [docs/agent_deploy_sop.md](docs/agent_deploy_sop.md)
|
|
263
|
-
Operator-facing SOP for release-based deployment, verification, and uninstall.
|
|
264
|
-
- [docs/release_deploy_smoke_test.md](docs/release_deploy_smoke_test.md)
|
|
265
|
-
Real-host smoke test checklist for release-based systemd deployment.
|
|
266
|
-
- [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
|
|
267
|
-
Release-based systemd deployment guide for published package versions.
|
|
268
|
-
- [scripts/init_release_system_readme.md](scripts/init_release_system_readme.md)
|
|
269
|
-
Release-based host bootstrap guide that avoids source checkout.
|
|
270
|
-
- [scripts/uninstall_readme.md](scripts/uninstall_readme.md)
|
|
271
|
-
Preview-first uninstall flow for deployed instances.
|
|
272
|
-
- [scripts/README.md](scripts/README.md)
|
|
273
|
-
Full script index, including contributor/internal paths.
|
|
274
|
-
|
|
275
|
-
### Contributor / Internal Docs
|
|
276
|
-
|
|
277
|
-
- [scripts/deploy_readme.md](scripts/deploy_readme.md)
|
|
278
|
-
Source-based systemd deployment for development/debugging only.
|
|
279
|
-
- [scripts/init_system_readme.md](scripts/init_system_readme.md)
|
|
280
|
-
Source-based host bootstrap for contributor/internal workflows.
|
|
281
318
|
- [SECURITY.md](SECURITY.md)
|
|
282
|
-
|
|
319
|
+
Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
320
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
321
|
+
Contributor workflow, validation baseline, and documentation expectations.
|
|
322
|
+
- [scripts/README.md](scripts/README.md)
|
|
323
|
+
Contributor helper script index.
|
|
283
324
|
|
|
284
325
|
## License
|
|
285
326
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# opencode-a2a-server
|
|
2
2
|
|
|
3
|
-
> Turn OpenCode into a stateful A2A service with a clear runtime boundary
|
|
3
|
+
> Turn OpenCode into a stateful A2A service with a clear runtime boundary.
|
|
4
4
|
|
|
5
5
|
`opencode-a2a-server` exposes OpenCode through standard A2A interfaces and adds
|
|
6
|
-
the
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
the runtime pieces that raw agent runtimes usually do not provide by default:
|
|
7
|
+
authentication, session continuity, streaming contracts, interrupt handling,
|
|
8
|
+
and explicit security guidance.
|
|
9
9
|
|
|
10
10
|
## Why This Project Exists
|
|
11
11
|
|
|
@@ -14,7 +14,8 @@ need a stable service layer around it. This repository provides that layer by:
|
|
|
14
14
|
|
|
15
15
|
- bridging A2A transport contracts to OpenCode session/message/event APIs
|
|
16
16
|
- making session and interrupt behavior explicit and auditable
|
|
17
|
-
-
|
|
17
|
+
- keeping the server/runtime contract explicit while leaving deployment
|
|
18
|
+
supervision to the operator
|
|
18
19
|
|
|
19
20
|
## What It Already Provides
|
|
20
21
|
|
|
@@ -26,7 +27,7 @@ need a stable service layer around it. This repository provides that layer by:
|
|
|
26
27
|
- session continuation via `metadata.shared.session.id`
|
|
27
28
|
- request-scoped model selection via `metadata.shared.model`
|
|
28
29
|
- OpenCode session query/control extensions and provider/model discovery
|
|
29
|
-
- released CLI install/upgrade flow and
|
|
30
|
+
- released CLI install/upgrade flow and a foreground runtime entrypoint
|
|
30
31
|
|
|
31
32
|
## Extension Capability Overview
|
|
32
33
|
|
|
@@ -50,13 +51,17 @@ Detailed consumption guidance:
|
|
|
50
51
|
- Shared stream hints: [`docs/guide.md#shared-stream-hints-contract`](docs/guide.md#shared-stream-hints-contract)
|
|
51
52
|
- OpenCode session query and provider discovery: [`docs/guide.md#opencode-session-query--provider-discovery-a2a-extensions`](docs/guide.md#opencode-session-query--provider-discovery-a2a-extensions)
|
|
52
53
|
- Shared interrupt callback: [`docs/guide.md#shared-interrupt-callback-a2a-extension`](docs/guide.md#shared-interrupt-callback-a2a-extension)
|
|
54
|
+
- Compatibility profile and retention guidance:
|
|
55
|
+
[`docs/guide.md#compatibility-profile`](docs/guide.md#compatibility-profile)
|
|
53
56
|
|
|
54
57
|
## Design Principle
|
|
55
58
|
|
|
56
59
|
One `OpenCode + opencode-a2a-server` instance pair is treated as a
|
|
57
60
|
single-tenant trust boundary.
|
|
58
61
|
|
|
59
|
-
This repository's intended scaling model is parameterized self-deployment:
|
|
62
|
+
This repository's intended scaling model is parameterized self-deployment:
|
|
63
|
+
consumers should launch their own isolated instance pairs instead of sharing
|
|
64
|
+
one runtime across mutually untrusted tenants.
|
|
60
65
|
|
|
61
66
|
- OpenCode may manage multiple projects/directories, but one deployed instance
|
|
62
67
|
is not a secure multi-tenant runtime.
|
|
@@ -75,7 +80,6 @@ flowchart TD
|
|
|
75
80
|
Mapping --> Runtime["OpenCode HTTP runtime"]
|
|
76
81
|
|
|
77
82
|
Api --> Auth["Bearer auth + request logging controls"]
|
|
78
|
-
Api --> Deploy["release-based deployment tooling"]
|
|
79
83
|
Runtime --> Workspace["Shared workspace / environment boundary"]
|
|
80
84
|
```
|
|
81
85
|
|
|
@@ -101,13 +105,14 @@ hard multi-tenant isolation layer.
|
|
|
101
105
|
isolation boundary inside one deployed instance.
|
|
102
106
|
- LLM provider keys are consumed by the OpenCode process. Prompt injection or
|
|
103
107
|
indirect exfiltration attempts may still expose sensitive values.
|
|
104
|
-
-
|
|
105
|
-
|
|
108
|
+
- Deployment supervision is intentionally BYO. If you wrap this runtime with
|
|
109
|
+
`systemd`, Docker, Kubernetes, or another supervisor, you own the service
|
|
110
|
+
user, secret storage, restart policy, and hardening choices.
|
|
106
111
|
|
|
107
112
|
Read before deployment:
|
|
108
113
|
|
|
109
114
|
- [SECURITY.md](SECURITY.md)
|
|
110
|
-
- [
|
|
115
|
+
- [docs/guide.md](docs/guide.md)
|
|
111
116
|
|
|
112
117
|
## User Paths
|
|
113
118
|
|
|
@@ -144,12 +149,36 @@ opencode serve
|
|
|
144
149
|
|
|
145
150
|
A2A_BEARER_TOKEN=prod-token \
|
|
146
151
|
A2A_PUBLIC_URL=http://127.0.0.1:8000 \
|
|
147
|
-
|
|
148
|
-
opencode-a2a-server
|
|
152
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
153
|
+
opencode-a2a-server serve
|
|
149
154
|
```
|
|
150
155
|
|
|
156
|
+
`OPENCODE_WORKSPACE_ROOT` is the default workspace root that this runtime
|
|
157
|
+
exposes to OpenCode.
|
|
158
|
+
|
|
151
159
|
Default address: `http://127.0.0.1:8000`
|
|
152
160
|
|
|
161
|
+
Common runtime variables:
|
|
162
|
+
|
|
163
|
+
| Variable | Required | Default | Purpose |
|
|
164
|
+
| --- | --- | --- | --- |
|
|
165
|
+
| `A2A_BEARER_TOKEN` | Yes | None | Bearer token required for authenticated runtime requests. |
|
|
166
|
+
| `OPENCODE_BASE_URL` | No | `http://127.0.0.1:4096` | Upstream OpenCode HTTP endpoint. |
|
|
167
|
+
| `OPENCODE_WORKSPACE_ROOT` | No | None | Default workspace root exposed to OpenCode. |
|
|
168
|
+
| `OPENCODE_PROVIDER_ID` | No | None | Default provider for the upstream runtime. |
|
|
169
|
+
| `OPENCODE_MODEL_ID` | No | None | Default model for the upstream runtime. Set together with `OPENCODE_PROVIDER_ID`. |
|
|
170
|
+
| `A2A_HOST` | No | `127.0.0.1` | Bind host for the A2A server. |
|
|
171
|
+
| `A2A_PORT` | No | `8000` | Bind port for the A2A server. |
|
|
172
|
+
| `A2A_PUBLIC_URL` | No | `http://127.0.0.1:8000` | Public base URL advertised by the Agent Card. |
|
|
173
|
+
| `A2A_LOG_LEVEL` | No | `WARNING` | Server log level. |
|
|
174
|
+
| `A2A_LOG_PAYLOADS` | No | `false` | Enable request/response payload logging. |
|
|
175
|
+
| `A2A_LOG_BODY_LIMIT` | No | `0` | Payload preview size used when payload logging is enabled. |
|
|
176
|
+
| `A2A_MAX_REQUEST_BODY_BYTES` | No | `1048576` | Maximum accepted request size. |
|
|
177
|
+
| `A2A_ALLOW_DIRECTORY_OVERRIDE` | No | `true` | Allow request-level `metadata.opencode.directory` overrides. |
|
|
178
|
+
| `A2A_ENABLE_SESSION_SHELL` | No | `false` | Enable high-risk `opencode.sessions.shell`. |
|
|
179
|
+
| `OPENCODE_TIMEOUT` | No | `120` | Upstream OpenCode request timeout in seconds. |
|
|
180
|
+
| `OPENCODE_TIMEOUT_STREAM` | No | None | Upstream OpenCode stream timeout override in seconds. |
|
|
181
|
+
|
|
153
182
|
If you omit `OPENCODE_PROVIDER_ID` / `OPENCODE_MODEL_ID`, `opencode serve`
|
|
154
183
|
uses your local OpenCode defaults (for example `~/.config/opencode/opencode.json`).
|
|
155
184
|
|
|
@@ -161,36 +190,63 @@ official docs and CLI:
|
|
|
161
190
|
- Local checks: `opencode auth list`, `opencode models`, `opencode models <provider>`
|
|
162
191
|
|
|
163
192
|
This path is for users who already manage their own shell, workspace, and
|
|
164
|
-
process lifecycle.
|
|
193
|
+
process lifecycle.
|
|
194
|
+
|
|
195
|
+
Use any supervisor you prefer for long-running operation:
|
|
165
196
|
|
|
166
|
-
|
|
197
|
+
- `systemd`
|
|
198
|
+
- Docker / container runtimes
|
|
199
|
+
- Kubernetes
|
|
200
|
+
- `supervisord`, `pm2`, or similar process managers
|
|
167
201
|
|
|
168
|
-
|
|
202
|
+
The project no longer ships built-in host bootstrap or process-manager
|
|
203
|
+
wrappers. The official product surface is the runtime entrypoint itself.
|
|
204
|
+
|
|
205
|
+
Minimal `systemd` example:
|
|
206
|
+
|
|
207
|
+
1. Create an env file such as `/etc/opencode-a2a/alpha.env`:
|
|
169
208
|
|
|
170
209
|
```bash
|
|
171
|
-
|
|
172
|
-
|
|
210
|
+
A2A_BEARER_TOKEN=replace-me
|
|
211
|
+
A2A_HOST=127.0.0.1
|
|
212
|
+
A2A_PORT=8000
|
|
213
|
+
A2A_PUBLIC_URL=https://a2a.example.com
|
|
214
|
+
OPENCODE_BASE_URL=http://127.0.0.1:4096
|
|
215
|
+
OPENCODE_WORKSPACE_ROOT=/srv/my-workspace
|
|
173
216
|
```
|
|
174
217
|
|
|
175
|
-
|
|
218
|
+
2. Create a unit file such as `/etc/systemd/system/opencode-a2a-server.service`:
|
|
219
|
+
|
|
220
|
+
```ini
|
|
221
|
+
[Unit]
|
|
222
|
+
Description=OpenCode A2A Server
|
|
223
|
+
After=network-online.target
|
|
224
|
+
Wants=network-online.target
|
|
176
225
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
-
|
|
180
|
-
-
|
|
226
|
+
[Service]
|
|
227
|
+
Type=simple
|
|
228
|
+
WorkingDirectory=/srv/my-workspace
|
|
229
|
+
EnvironmentFile=/etc/opencode-a2a/alpha.env
|
|
230
|
+
ExecStart=/home/dev/.local/bin/opencode-a2a-server serve
|
|
231
|
+
Restart=on-failure
|
|
232
|
+
RestartSec=2
|
|
181
233
|
|
|
182
|
-
|
|
234
|
+
[Install]
|
|
235
|
+
WantedBy=multi-user.target
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Replace `ExecStart` with the absolute path returned by `command -v opencode-a2a-server`.
|
|
183
239
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
-
|
|
187
|
-
-
|
|
240
|
+
Migration notes:
|
|
241
|
+
|
|
242
|
+
- `OPENCODE_DIRECTORY` has been removed. Use `OPENCODE_WORKSPACE_ROOT`.
|
|
243
|
+
- Built-in `init-release-system`, `deploy-release`, and `uninstall-instance` have been removed.
|
|
244
|
+
- Secret storage, service users, restart policy, and supervisor configuration are now operator-managed.
|
|
188
245
|
|
|
189
246
|
## Contributor Paths
|
|
190
247
|
|
|
191
248
|
Use the repository checkout directly only for development, local debugging, or
|
|
192
|
-
validation against unreleased changes.
|
|
193
|
-
kept for contributors and internal debugging, not as the recommended user path.
|
|
249
|
+
validation against unreleased changes.
|
|
194
250
|
|
|
195
251
|
Quick source run:
|
|
196
252
|
|
|
@@ -203,8 +259,8 @@ OPENCODE_MODEL_ID=gemini-3.1-pro-preview \
|
|
|
203
259
|
opencode serve
|
|
204
260
|
|
|
205
261
|
A2A_BEARER_TOKEN=dev-token \
|
|
206
|
-
|
|
207
|
-
uv run opencode-a2a-server
|
|
262
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
263
|
+
uv run opencode-a2a-server serve
|
|
208
264
|
```
|
|
209
265
|
|
|
210
266
|
Baseline validation:
|
|
@@ -216,32 +272,17 @@ uv run pytest
|
|
|
216
272
|
|
|
217
273
|
## Documentation Map
|
|
218
274
|
|
|
219
|
-
### User
|
|
275
|
+
### User Docs
|
|
220
276
|
|
|
221
277
|
- [docs/guide.md](docs/guide.md)
|
|
222
278
|
Product behavior, API contracts, and detailed streaming/session/interrupt
|
|
223
279
|
consumption guidance.
|
|
224
|
-
- [docs/agent_deploy_sop.md](docs/agent_deploy_sop.md)
|
|
225
|
-
Operator-facing SOP for release-based deployment, verification, and uninstall.
|
|
226
|
-
- [docs/release_deploy_smoke_test.md](docs/release_deploy_smoke_test.md)
|
|
227
|
-
Real-host smoke test checklist for release-based systemd deployment.
|
|
228
|
-
- [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
|
|
229
|
-
Release-based systemd deployment guide for published package versions.
|
|
230
|
-
- [scripts/init_release_system_readme.md](scripts/init_release_system_readme.md)
|
|
231
|
-
Release-based host bootstrap guide that avoids source checkout.
|
|
232
|
-
- [scripts/uninstall_readme.md](scripts/uninstall_readme.md)
|
|
233
|
-
Preview-first uninstall flow for deployed instances.
|
|
234
|
-
- [scripts/README.md](scripts/README.md)
|
|
235
|
-
Full script index, including contributor/internal paths.
|
|
236
|
-
|
|
237
|
-
### Contributor / Internal Docs
|
|
238
|
-
|
|
239
|
-
- [scripts/deploy_readme.md](scripts/deploy_readme.md)
|
|
240
|
-
Source-based systemd deployment for development/debugging only.
|
|
241
|
-
- [scripts/init_system_readme.md](scripts/init_system_readme.md)
|
|
242
|
-
Source-based host bootstrap for contributor/internal workflows.
|
|
243
280
|
- [SECURITY.md](SECURITY.md)
|
|
244
|
-
|
|
281
|
+
Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
282
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
283
|
+
Contributor workflow, validation baseline, and documentation expectations.
|
|
284
|
+
- [scripts/README.md](scripts/README.md)
|
|
285
|
+
Contributor helper script index.
|
|
245
286
|
|
|
246
287
|
## License
|
|
247
288
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
This repository is an adapter layer that exposes OpenCode through A2A
|
|
6
6
|
HTTP+JSON and JSON-RPC interfaces. It adds authentication, task/session
|
|
7
|
-
contracts, streaming, interrupt handling, and
|
|
7
|
+
contracts, streaming, interrupt handling, and runtime guidance, but it does
|
|
8
8
|
not fully isolate upstream model credentials from OpenCode runtime behavior.
|
|
9
9
|
|
|
10
10
|
## Security Boundary
|
|
@@ -20,9 +20,9 @@ not fully isolate upstream model credentials from OpenCode runtime behavior.
|
|
|
20
20
|
indirect exfiltration attempts may still expose sensitive values.
|
|
21
21
|
- Payload logging is opt-in. When `A2A_LOG_PAYLOADS=true`, operators should
|
|
22
22
|
treat logs as potentially sensitive operational data.
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
- This project does not ship host bootstrap or process-manager wrappers as an
|
|
24
|
+
official product capability. Operators remain responsible for file
|
|
25
|
+
permissions, secret storage, service users, and supervisor-specific hardening.
|
|
26
26
|
|
|
27
27
|
## Threat Model
|
|
28
28
|
|