opencode-a2a-server 0.2.1__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.1 → opencode_a2a_server-0.2.2}/.secrets.baseline +2 -12
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/PKG-INFO +91 -54
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/README.md +90 -53
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/SECURITY.md +4 -4
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/docs/guide.md +31 -3
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/pyproject.toml +1 -1
- opencode_a2a_server-0.2.2/scripts/README.md +22 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/app.py +2 -2
- opencode_a2a_server-0.2.2/src/opencode_a2a_server/cli.py +53 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/config.py +1 -1
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/opencode_client.py +1 -1
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/PKG-INFO +91 -54
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/SOURCES.txt +2 -24
- opencode_a2a_server-0.2.2/src/opencode_a2a_server.egg-info/entry_points.txt +2 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/helpers.py +1 -1
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_agent_card.py +1 -1
- opencode_a2a_server-0.2.2/tests/test_cli.py +58 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_directory_validation.py +1 -1
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_opencode_client_params.py +7 -7
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_opencode_session_extension.py +26 -26
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_settings.py +13 -0
- opencode_a2a_server-0.2.1/docs/agent_deploy_sop.md +0 -292
- opencode_a2a_server-0.2.1/docs/release_deploy_smoke_test.md +0 -188
- opencode_a2a_server-0.2.1/scripts/README.md +0 -34
- opencode_a2a_server-0.2.1/scripts/deploy/enable_instance.sh +0 -175
- opencode_a2a_server-0.2.1/scripts/deploy/install_release_runtime.sh +0 -52
- opencode_a2a_server-0.2.1/scripts/deploy/install_units.sh +0 -110
- opencode_a2a_server-0.2.1/scripts/deploy/provider_secret_env_keys.sh +0 -69
- opencode_a2a_server-0.2.1/scripts/deploy/run_a2a.sh +0 -18
- opencode_a2a_server-0.2.1/scripts/deploy/run_opencode.sh +0 -80
- opencode_a2a_server-0.2.1/scripts/deploy/setup_instance.sh +0 -483
- opencode_a2a_server-0.2.1/scripts/deploy/update_a2a.sh +0 -27
- opencode_a2a_server-0.2.1/scripts/deploy.sh +0 -344
- opencode_a2a_server-0.2.1/scripts/deploy_readme.md +0 -333
- opencode_a2a_server-0.2.1/scripts/deploy_release.sh +0 -8
- opencode_a2a_server-0.2.1/scripts/deploy_release_readme.md +0 -72
- opencode_a2a_server-0.2.1/scripts/init_release_system.sh +0 -15
- opencode_a2a_server-0.2.1/scripts/init_release_system_readme.md +0 -41
- opencode_a2a_server-0.2.1/scripts/init_system.sh +0 -852
- opencode_a2a_server-0.2.1/scripts/init_system_readme.md +0 -69
- opencode_a2a_server-0.2.1/scripts/init_system_uv_release_manifest.sh +0 -17
- opencode_a2a_server-0.2.1/scripts/shell_helpers.sh +0 -34
- opencode_a2a_server-0.2.1/scripts/uninstall.sh +0 -383
- opencode_a2a_server-0.2.1/scripts/uninstall_readme.md +0 -39
- opencode_a2a_server-0.2.1/src/opencode_a2a_server.egg-info/entry_points.txt +0 -2
- opencode_a2a_server-0.2.1/tests/test_deploy_security_contract.py +0 -164
- opencode_a2a_server-0.2.1/tests/test_init_system_security.py +0 -101
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.github/workflows/ci.yml +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.github/workflows/dependency-health.yml +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.github/workflows/publish.yml +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.gitignore +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/.pre-commit-config.yaml +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/AGENTS.md +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/CONTRIBUTING.md +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/LICENSE +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/dependency_health.sh +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/doctor.sh +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/health_common.sh +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/lint.sh +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/scripts/smoke_test_built_cli.sh +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/setup.cfg +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/__init__.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/agent.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/extension_contracts.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/jsonrpc_ext.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/jsonrpc_models.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/parts_mapper.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server/text_parts.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/dependency_links.txt +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/requires.txt +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/src/opencode_a2a_server.egg-info/top_level.txt +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/__init__.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_agent_errors.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_call_context_builder.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_cancel_contract.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_cancellation.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_extension_contract_consistency.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_jsonrpc_models.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_jsonrpc_unsupported_method.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_metrics.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_multipart_input.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_opencode_agent_session_binding.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_script_health_contract.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_session_ownership.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_streaming_output_contract.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/tests/test_transport_contract.py +0 -0
- {opencode_a2a_server-0.2.1 → opencode_a2a_server-0.2.2}/uv.lock +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
|
}
|
|
@@ -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
|
|
@@ -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
|
|
|
@@ -96,7 +97,9 @@ Detailed consumption guidance:
|
|
|
96
97
|
One `OpenCode + opencode-a2a-server` instance pair is treated as a
|
|
97
98
|
single-tenant trust boundary.
|
|
98
99
|
|
|
99
|
-
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.
|
|
100
103
|
|
|
101
104
|
- OpenCode may manage multiple projects/directories, but one deployed instance
|
|
102
105
|
is not a secure multi-tenant runtime.
|
|
@@ -115,7 +118,6 @@ flowchart TD
|
|
|
115
118
|
Mapping --> Runtime["OpenCode HTTP runtime"]
|
|
116
119
|
|
|
117
120
|
Api --> Auth["Bearer auth + request logging controls"]
|
|
118
|
-
Api --> Deploy["release-based deployment tooling"]
|
|
119
121
|
Runtime --> Workspace["Shared workspace / environment boundary"]
|
|
120
122
|
```
|
|
121
123
|
|
|
@@ -141,13 +143,14 @@ hard multi-tenant isolation layer.
|
|
|
141
143
|
isolation boundary inside one deployed instance.
|
|
142
144
|
- LLM provider keys are consumed by the OpenCode process. Prompt injection or
|
|
143
145
|
indirect exfiltration attempts may still expose sensitive values.
|
|
144
|
-
-
|
|
145
|
-
|
|
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.
|
|
146
149
|
|
|
147
150
|
Read before deployment:
|
|
148
151
|
|
|
149
152
|
- [SECURITY.md](SECURITY.md)
|
|
150
|
-
- [
|
|
153
|
+
- [docs/guide.md](docs/guide.md)
|
|
151
154
|
|
|
152
155
|
## User Paths
|
|
153
156
|
|
|
@@ -184,12 +187,36 @@ opencode serve
|
|
|
184
187
|
|
|
185
188
|
A2A_BEARER_TOKEN=prod-token \
|
|
186
189
|
A2A_PUBLIC_URL=http://127.0.0.1:8000 \
|
|
187
|
-
|
|
188
|
-
opencode-a2a-server
|
|
190
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
191
|
+
opencode-a2a-server serve
|
|
189
192
|
```
|
|
190
193
|
|
|
194
|
+
`OPENCODE_WORKSPACE_ROOT` is the default workspace root that this runtime
|
|
195
|
+
exposes to OpenCode.
|
|
196
|
+
|
|
191
197
|
Default address: `http://127.0.0.1:8000`
|
|
192
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
|
+
|
|
193
220
|
If you omit `OPENCODE_PROVIDER_ID` / `OPENCODE_MODEL_ID`, `opencode serve`
|
|
194
221
|
uses your local OpenCode defaults (for example `~/.config/opencode/opencode.json`).
|
|
195
222
|
|
|
@@ -201,36 +228,63 @@ official docs and CLI:
|
|
|
201
228
|
- Local checks: `opencode auth list`, `opencode models`, `opencode models <provider>`
|
|
202
229
|
|
|
203
230
|
This path is for users who already manage their own shell, workspace, and
|
|
204
|
-
process lifecycle.
|
|
231
|
+
process lifecycle.
|
|
232
|
+
|
|
233
|
+
Use any supervisor you prefer for long-running operation:
|
|
205
234
|
|
|
206
|
-
|
|
235
|
+
- `systemd`
|
|
236
|
+
- Docker / container runtimes
|
|
237
|
+
- Kubernetes
|
|
238
|
+
- `supervisord`, `pm2`, or similar process managers
|
|
207
239
|
|
|
208
|
-
|
|
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`:
|
|
209
246
|
|
|
210
247
|
```bash
|
|
211
|
-
|
|
212
|
-
|
|
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
|
|
213
254
|
```
|
|
214
255
|
|
|
215
|
-
|
|
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
|
|
216
263
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
-
|
|
220
|
-
-
|
|
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
|
|
221
271
|
|
|
222
|
-
|
|
272
|
+
[Install]
|
|
273
|
+
WantedBy=multi-user.target
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Replace `ExecStart` with the absolute path returned by `command -v opencode-a2a-server`.
|
|
223
277
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
-
|
|
227
|
-
-
|
|
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.
|
|
228
283
|
|
|
229
284
|
## Contributor Paths
|
|
230
285
|
|
|
231
286
|
Use the repository checkout directly only for development, local debugging, or
|
|
232
|
-
validation against unreleased changes.
|
|
233
|
-
kept for contributors and internal debugging, not as the recommended user path.
|
|
287
|
+
validation against unreleased changes.
|
|
234
288
|
|
|
235
289
|
Quick source run:
|
|
236
290
|
|
|
@@ -243,8 +297,8 @@ OPENCODE_MODEL_ID=gemini-3.1-pro-preview \
|
|
|
243
297
|
opencode serve
|
|
244
298
|
|
|
245
299
|
A2A_BEARER_TOKEN=dev-token \
|
|
246
|
-
|
|
247
|
-
uv run opencode-a2a-server
|
|
300
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
301
|
+
uv run opencode-a2a-server serve
|
|
248
302
|
```
|
|
249
303
|
|
|
250
304
|
Baseline validation:
|
|
@@ -256,34 +310,17 @@ uv run pytest
|
|
|
256
310
|
|
|
257
311
|
## Documentation Map
|
|
258
312
|
|
|
259
|
-
### User
|
|
313
|
+
### User Docs
|
|
260
314
|
|
|
261
315
|
- [docs/guide.md](docs/guide.md)
|
|
262
316
|
Product behavior, API contracts, and detailed streaming/session/interrupt
|
|
263
317
|
consumption guidance.
|
|
318
|
+
- [SECURITY.md](SECURITY.md)
|
|
319
|
+
Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
264
320
|
- [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
265
321
|
Contributor workflow, validation baseline, and documentation expectations.
|
|
266
|
-
- [docs/agent_deploy_sop.md](docs/agent_deploy_sop.md)
|
|
267
|
-
Operator-facing SOP for release-based deployment, verification, and uninstall.
|
|
268
|
-
- [docs/release_deploy_smoke_test.md](docs/release_deploy_smoke_test.md)
|
|
269
|
-
Real-host smoke test checklist for release-based systemd deployment.
|
|
270
|
-
- [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
|
|
271
|
-
Release-based systemd deployment guide for published package versions.
|
|
272
|
-
- [scripts/init_release_system_readme.md](scripts/init_release_system_readme.md)
|
|
273
|
-
Release-based host bootstrap guide that avoids source checkout.
|
|
274
|
-
- [scripts/uninstall_readme.md](scripts/uninstall_readme.md)
|
|
275
|
-
Preview-first uninstall flow for deployed instances.
|
|
276
322
|
- [scripts/README.md](scripts/README.md)
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
### Contributor / Internal Docs
|
|
280
|
-
|
|
281
|
-
- [scripts/deploy_readme.md](scripts/deploy_readme.md)
|
|
282
|
-
Source-based systemd deployment for development/debugging only.
|
|
283
|
-
- [scripts/init_system_readme.md](scripts/init_system_readme.md)
|
|
284
|
-
Source-based host bootstrap for contributor/internal workflows.
|
|
285
|
-
- [SECURITY.md](SECURITY.md)
|
|
286
|
-
threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
323
|
+
Contributor helper script index.
|
|
287
324
|
|
|
288
325
|
## License
|
|
289
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
|
|
|
@@ -58,7 +59,9 @@ Detailed consumption guidance:
|
|
|
58
59
|
One `OpenCode + opencode-a2a-server` instance pair is treated as a
|
|
59
60
|
single-tenant trust boundary.
|
|
60
61
|
|
|
61
|
-
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.
|
|
62
65
|
|
|
63
66
|
- OpenCode may manage multiple projects/directories, but one deployed instance
|
|
64
67
|
is not a secure multi-tenant runtime.
|
|
@@ -77,7 +80,6 @@ flowchart TD
|
|
|
77
80
|
Mapping --> Runtime["OpenCode HTTP runtime"]
|
|
78
81
|
|
|
79
82
|
Api --> Auth["Bearer auth + request logging controls"]
|
|
80
|
-
Api --> Deploy["release-based deployment tooling"]
|
|
81
83
|
Runtime --> Workspace["Shared workspace / environment boundary"]
|
|
82
84
|
```
|
|
83
85
|
|
|
@@ -103,13 +105,14 @@ hard multi-tenant isolation layer.
|
|
|
103
105
|
isolation boundary inside one deployed instance.
|
|
104
106
|
- LLM provider keys are consumed by the OpenCode process. Prompt injection or
|
|
105
107
|
indirect exfiltration attempts may still expose sensitive values.
|
|
106
|
-
-
|
|
107
|
-
|
|
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.
|
|
108
111
|
|
|
109
112
|
Read before deployment:
|
|
110
113
|
|
|
111
114
|
- [SECURITY.md](SECURITY.md)
|
|
112
|
-
- [
|
|
115
|
+
- [docs/guide.md](docs/guide.md)
|
|
113
116
|
|
|
114
117
|
## User Paths
|
|
115
118
|
|
|
@@ -146,12 +149,36 @@ opencode serve
|
|
|
146
149
|
|
|
147
150
|
A2A_BEARER_TOKEN=prod-token \
|
|
148
151
|
A2A_PUBLIC_URL=http://127.0.0.1:8000 \
|
|
149
|
-
|
|
150
|
-
opencode-a2a-server
|
|
152
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
153
|
+
opencode-a2a-server serve
|
|
151
154
|
```
|
|
152
155
|
|
|
156
|
+
`OPENCODE_WORKSPACE_ROOT` is the default workspace root that this runtime
|
|
157
|
+
exposes to OpenCode.
|
|
158
|
+
|
|
153
159
|
Default address: `http://127.0.0.1:8000`
|
|
154
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
|
+
|
|
155
182
|
If you omit `OPENCODE_PROVIDER_ID` / `OPENCODE_MODEL_ID`, `opencode serve`
|
|
156
183
|
uses your local OpenCode defaults (for example `~/.config/opencode/opencode.json`).
|
|
157
184
|
|
|
@@ -163,36 +190,63 @@ official docs and CLI:
|
|
|
163
190
|
- Local checks: `opencode auth list`, `opencode models`, `opencode models <provider>`
|
|
164
191
|
|
|
165
192
|
This path is for users who already manage their own shell, workspace, and
|
|
166
|
-
process lifecycle.
|
|
193
|
+
process lifecycle.
|
|
194
|
+
|
|
195
|
+
Use any supervisor you prefer for long-running operation:
|
|
167
196
|
|
|
168
|
-
|
|
197
|
+
- `systemd`
|
|
198
|
+
- Docker / container runtimes
|
|
199
|
+
- Kubernetes
|
|
200
|
+
- `supervisord`, `pm2`, or similar process managers
|
|
169
201
|
|
|
170
|
-
|
|
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`:
|
|
171
208
|
|
|
172
209
|
```bash
|
|
173
|
-
|
|
174
|
-
|
|
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
|
|
175
216
|
```
|
|
176
217
|
|
|
177
|
-
|
|
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
|
|
178
225
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
-
|
|
182
|
-
-
|
|
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
|
|
183
233
|
|
|
184
|
-
|
|
234
|
+
[Install]
|
|
235
|
+
WantedBy=multi-user.target
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Replace `ExecStart` with the absolute path returned by `command -v opencode-a2a-server`.
|
|
185
239
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
-
|
|
189
|
-
-
|
|
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.
|
|
190
245
|
|
|
191
246
|
## Contributor Paths
|
|
192
247
|
|
|
193
248
|
Use the repository checkout directly only for development, local debugging, or
|
|
194
|
-
validation against unreleased changes.
|
|
195
|
-
kept for contributors and internal debugging, not as the recommended user path.
|
|
249
|
+
validation against unreleased changes.
|
|
196
250
|
|
|
197
251
|
Quick source run:
|
|
198
252
|
|
|
@@ -205,8 +259,8 @@ OPENCODE_MODEL_ID=gemini-3.1-pro-preview \
|
|
|
205
259
|
opencode serve
|
|
206
260
|
|
|
207
261
|
A2A_BEARER_TOKEN=dev-token \
|
|
208
|
-
|
|
209
|
-
uv run opencode-a2a-server
|
|
262
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
263
|
+
uv run opencode-a2a-server serve
|
|
210
264
|
```
|
|
211
265
|
|
|
212
266
|
Baseline validation:
|
|
@@ -218,34 +272,17 @@ uv run pytest
|
|
|
218
272
|
|
|
219
273
|
## Documentation Map
|
|
220
274
|
|
|
221
|
-
### User
|
|
275
|
+
### User Docs
|
|
222
276
|
|
|
223
277
|
- [docs/guide.md](docs/guide.md)
|
|
224
278
|
Product behavior, API contracts, and detailed streaming/session/interrupt
|
|
225
279
|
consumption guidance.
|
|
280
|
+
- [SECURITY.md](SECURITY.md)
|
|
281
|
+
Threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
226
282
|
- [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
227
283
|
Contributor workflow, validation baseline, and documentation expectations.
|
|
228
|
-
- [docs/agent_deploy_sop.md](docs/agent_deploy_sop.md)
|
|
229
|
-
Operator-facing SOP for release-based deployment, verification, and uninstall.
|
|
230
|
-
- [docs/release_deploy_smoke_test.md](docs/release_deploy_smoke_test.md)
|
|
231
|
-
Real-host smoke test checklist for release-based systemd deployment.
|
|
232
|
-
- [scripts/deploy_release_readme.md](scripts/deploy_release_readme.md)
|
|
233
|
-
Release-based systemd deployment guide for published package versions.
|
|
234
|
-
- [scripts/init_release_system_readme.md](scripts/init_release_system_readme.md)
|
|
235
|
-
Release-based host bootstrap guide that avoids source checkout.
|
|
236
|
-
- [scripts/uninstall_readme.md](scripts/uninstall_readme.md)
|
|
237
|
-
Preview-first uninstall flow for deployed instances.
|
|
238
284
|
- [scripts/README.md](scripts/README.md)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
### Contributor / Internal Docs
|
|
242
|
-
|
|
243
|
-
- [scripts/deploy_readme.md](scripts/deploy_readme.md)
|
|
244
|
-
Source-based systemd deployment for development/debugging only.
|
|
245
|
-
- [scripts/init_system_readme.md](scripts/init_system_readme.md)
|
|
246
|
-
Source-based host bootstrap for contributor/internal workflows.
|
|
247
|
-
- [SECURITY.md](SECURITY.md)
|
|
248
|
-
threat model, deployment caveats, and vulnerability disclosure guidance.
|
|
285
|
+
Contributor helper script index.
|
|
249
286
|
|
|
250
287
|
## License
|
|
251
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
|
|
|
@@ -19,16 +19,28 @@ and JSON-RPC extension details (README stays at overview level).
|
|
|
19
19
|
This section keeps only the protocol-relevant variables.
|
|
20
20
|
For the full runtime variable catalog and defaults, see
|
|
21
21
|
[`../src/opencode_a2a_server/config.py`](../src/opencode_a2a_server/config.py).
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
Deployment supervision is intentionally out of scope for this project; use your
|
|
23
|
+
own process manager, container runtime, or host orchestration.
|
|
24
24
|
|
|
25
25
|
Key variables to understand protocol behavior:
|
|
26
26
|
|
|
27
27
|
- `A2A_BEARER_TOKEN`: required for all authenticated runtime requests.
|
|
28
|
+
- `OPENCODE_BASE_URL`: upstream OpenCode HTTP endpoint. Default:
|
|
29
|
+
`http://127.0.0.1:4096`.
|
|
30
|
+
- `OPENCODE_WORKSPACE_ROOT`: service-level default workspace root exposed to
|
|
31
|
+
OpenCode when clients do not request a narrower directory override.
|
|
32
|
+
- `OPENCODE_PROVIDER_ID` / `OPENCODE_MODEL_ID`: default upstream model
|
|
33
|
+
selection. Set them together when you want the service to pin a specific
|
|
34
|
+
provider/model instead of using OpenCode's local defaults.
|
|
28
35
|
- `A2A_ALLOW_DIRECTORY_OVERRIDE`: controls whether clients may pass
|
|
29
36
|
`metadata.opencode.directory`.
|
|
30
37
|
- `A2A_ENABLE_SESSION_SHELL`: gates high-risk JSON-RPC method
|
|
31
38
|
`opencode.sessions.shell`.
|
|
39
|
+
- `A2A_HOST` / `A2A_PORT`: runtime bind address. Defaults:
|
|
40
|
+
`127.0.0.1:8000`.
|
|
41
|
+
- `A2A_PUBLIC_URL`: public base URL advertised by the Agent Card. Default:
|
|
42
|
+
`http://127.0.0.1:8000`.
|
|
43
|
+
- `A2A_LOG_LEVEL`: runtime log level. Default: `WARNING`.
|
|
32
44
|
- `A2A_LOG_PAYLOADS` / `A2A_LOG_BODY_LIMIT`: payload logging behavior and
|
|
33
45
|
truncation. When `A2A_LOG_LEVEL=DEBUG`, upstream OpenCode stream events are
|
|
34
46
|
also logged with preview truncation controlled by `A2A_LOG_BODY_LIMIT`.
|
|
@@ -38,8 +50,22 @@ Key variables to understand protocol behavior:
|
|
|
38
50
|
behavior for `(identity, contextId) -> session_id`.
|
|
39
51
|
- `A2A_CANCEL_ABORT_TIMEOUT_SECONDS`: best-effort timeout for upstream
|
|
40
52
|
`session.abort` in cancel flow.
|
|
53
|
+
- `OPENCODE_TIMEOUT` / `OPENCODE_TIMEOUT_STREAM`: upstream request timeout and
|
|
54
|
+
optional stream timeout override.
|
|
41
55
|
- Runtime authentication is bearer-token only via `A2A_BEARER_TOKEN`.
|
|
42
56
|
|
|
57
|
+
Minimal runtime example:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
A2A_BEARER_TOKEN=dev-token \
|
|
61
|
+
A2A_HOST=127.0.0.1 \
|
|
62
|
+
A2A_PORT=8000 \
|
|
63
|
+
A2A_PUBLIC_URL=http://127.0.0.1:8000 \
|
|
64
|
+
OPENCODE_BASE_URL=http://127.0.0.1:4096 \
|
|
65
|
+
OPENCODE_WORKSPACE_ROOT=/abs/path/to/workspace \
|
|
66
|
+
opencode-a2a-server serve
|
|
67
|
+
```
|
|
68
|
+
|
|
43
69
|
## Service Behavior
|
|
44
70
|
|
|
45
71
|
- The service forwards A2A `message:send` to OpenCode session/message calls.
|
|
@@ -106,7 +132,9 @@ Key variables to understand protocol behavior:
|
|
|
106
132
|
- Failure events include concrete error details with `failed` state.
|
|
107
133
|
- Directory validation and normalization:
|
|
108
134
|
- Clients can pass `metadata.opencode.directory`, but it must stay inside
|
|
109
|
-
`${
|
|
135
|
+
`${OPENCODE_WORKSPACE_ROOT}` (or service runtime root if not configured).
|
|
136
|
+
- `OPENCODE_WORKSPACE_ROOT` is the service-level default workspace root used
|
|
137
|
+
when clients do not request a narrower directory override.
|
|
110
138
|
- All paths are normalized with `realpath` to prevent `..` or symlink
|
|
111
139
|
boundary bypass.
|
|
112
140
|
- If `A2A_ALLOW_DIRECTORY_OVERRIDE=false`, only the default directory is
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# scripts
|
|
2
|
+
|
|
3
|
+
Executable scripts live in this directory. This file is the entry index for the
|
|
4
|
+
remaining repository-maintenance helpers.
|
|
5
|
+
|
|
6
|
+
## Product Contract vs Script Docs
|
|
7
|
+
|
|
8
|
+
- Product/API behavior (transport, protocol contracts, extension semantics):
|
|
9
|
+
- [`../docs/guide.md`](../docs/guide.md)
|
|
10
|
+
- Security boundary and disclosure guidance:
|
|
11
|
+
- [`../SECURITY.md`](../SECURITY.md)
|
|
12
|
+
|
|
13
|
+
## Other Scripts
|
|
14
|
+
|
|
15
|
+
- [`doctor.sh`](./doctor.sh): local development regression entrypoint (`sync`/`pip check` + lint + tests)
|
|
16
|
+
- [`dependency_health.sh`](./dependency_health.sh): dependency review entrypoint (`sync`/`pip check` + outdated + audit)
|
|
17
|
+
- [`lint.sh`](./lint.sh): lint helper
|
|
18
|
+
- [`smoke_test_built_cli.sh`](./smoke_test_built_cli.sh): wheel-install smoke test for the released CLI runtime
|
|
19
|
+
|
|
20
|
+
## Notes
|
|
21
|
+
|
|
22
|
+
- `doctor.sh` and `dependency_health.sh` intentionally remain separate entrypoints and share common prerequisites through [`health_common.sh`](./health_common.sh).
|
|
@@ -276,8 +276,8 @@ def _build_deployment_context(settings: Settings) -> dict[str, str | bool]:
|
|
|
276
276
|
}
|
|
277
277
|
if settings.a2a_project:
|
|
278
278
|
context["project"] = settings.a2a_project
|
|
279
|
-
if settings.
|
|
280
|
-
context["workspace_root"] = settings.
|
|
279
|
+
if settings.opencode_workspace_root:
|
|
280
|
+
context["workspace_root"] = settings.opencode_workspace_root
|
|
281
281
|
if settings.opencode_provider_id:
|
|
282
282
|
context["provider_id"] = settings.opencode_provider_id
|
|
283
283
|
if settings.opencode_model_id:
|