Skip to content

Commit bdc2461

Browse files
authored
Merge branch 'main' into dependabot/github_actions/github/codeql-action/upload-sarif-4.37.4
2 parents f675edd + ed905cf commit bdc2461

39 files changed

Lines changed: 1138 additions & 28 deletions

apps/server/openapi.json

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1300,6 +1300,33 @@
13001300
},
13011301
"required": ["type", "name", "provider"]
13021302
},
1303+
"previousAddress": {
1304+
"type": "object",
1305+
"properties": {
1306+
"type": {
1307+
"type": "string",
1308+
"enum": [
1309+
"environment",
1310+
"vault",
1311+
"memory_store",
1312+
"skill",
1313+
"agent",
1314+
"template",
1315+
"deployment",
1316+
"file",
1317+
"identity",
1318+
"channel"
1319+
]
1320+
},
1321+
"name": {
1322+
"type": "string"
1323+
},
1324+
"provider": {
1325+
"type": "string"
1326+
}
1327+
},
1328+
"required": ["type", "name", "provider"]
1329+
},
13031330
"reason": {
13041331
"type": "string"
13051332
},

apps/webui/src/lib/api/generated/schema.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,22 @@ export interface paths {
731731
name: string;
732732
provider: string;
733733
};
734+
previousAddress?: {
735+
/** @enum {string} */
736+
type:
737+
| "environment"
738+
| "vault"
739+
| "memory_store"
740+
| "skill"
741+
| "agent"
742+
| "template"
743+
| "deployment"
744+
| "file"
745+
| "identity"
746+
| "channel";
747+
name: string;
748+
provider: string;
749+
};
734750
reason: string;
735751
/** @enum {string} */
736752
driftKind?: "none" | "local" | "remote" | "both";

bun.lock

Lines changed: 8 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/guides/configure-an-agent.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,16 @@ environments:
5959
packages:
6060
apt: [git, curl]
6161
npm: [typescript]
62+
setup_script: |
63+
set -euo pipefail
64+
install -d /data/workspace/.openagentpack
65+
test -f /data/workspace/.openagentpack/ready || date -u > /data/workspace/.openagentpack/ready
6266
```
6367

6468
Reference an environment from an agent with `environment: dev`.
6569

70+
Qoder supports `config.setup_script` for both cloud and self-hosted environments. It runs the script with `/bin/bash -lc` after declared packages are installed. The UTF-8 limit is 64 KB and the timeout is 10 minutes; a non-zero exit prevents the Session from starting. The script runs once per sandbox and runs again when that sandbox is rebuilt, so make it idempotent. Do not embed credentials—use vaults or environment-backed secret references. Other providers currently reject `setup_script` rather than silently ignoring it.
71+
6672
## Instructions
6773

6874
`instructions` accepts either an inline string or a path to a file:

docs/guides/configure-an-agent.zh-CN.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ environments:
9595
packages:
9696
apt: [git, curl]
9797
npm: [typescript]
98+
setup_script: |
99+
set -euo pipefail
100+
install -d /data/workspace/.openagentpack
101+
test -f /data/workspace/.openagentpack/ready || date -u > /data/workspace/.openagentpack/ready
98102
metadata:
99103
team: platform
100104
```
@@ -122,6 +126,14 @@ packages:
122126
go: [golang.org/x/tools/gopls@latest]
123127
```
124128

129+
Qoder 请求目前只支持 `apt`、`npm` 和 `pip`。`cargo`、`gem`、`go` 是 Qoder 响应中的保留字段,不能在投向 Qoder 的配置中声明非空值;如有需要,可通过 `setup_script` 安装。
130+
131+
### 启动脚本(Qoder)
132+
133+
Qoder 的 cloud 与 self-hosted Environment 都支持 `config.setup_script`。依赖包安装完成后,脚本会通过 `/bin/bash -lc` 执行;UTF-8 最大 64 KB,超时 10 分钟,非零退出会导致 Session 启动失败。脚本在同一 sandbox 中只执行一次,sandbox 重建后会再次执行,因此必须保持幂等。不要把令牌或密码写入脚本,应使用 Vault 或环境变量引用。其他 Provider 当前会明确拒绝 `setup_script`,不会静默忽略。
134+
135+
受管理的 Qoder `self_hosted` Environment,其 `config` 只能包含 `type` 和可选的 `setup_script`;网络与预装包配置仅适用于 cloud Environment。带 `environment_id` 的外部引用仍不由 OpenAgentPack 修改。
136+
125137
---
126138

127139
## 挂载技能包

docs/guides/deploy-to-qoder.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ providers:
2727

2828
A `deployment run` on Qoder creates a native Deployment Run and associated Session. Cron schedules run server-side.
2929

30+
## Runtime environment variables
31+
32+
Declare `environment_variables` on an Agent to inject variables into its Qoder runtime:
33+
34+
```yaml
35+
agents:
36+
assistant:
37+
model: { qoder: auto }
38+
instructions: Help the user.
39+
environment: dev
40+
environment_variables:
41+
FEATURE_FLAG: "on"
42+
LOG_LEVEL: debug
43+
```
44+
45+
OpenAgentPack maps this to each Qoder API's native shape: a top-level object on Forward Templates, `config.environment_variables` on Forward Sessions, and the required `KEY=VALUE;...` string on managed Sessions. Other providers reject this Qoder-specific field during validation.
46+
3047
## Tool naming
3148

3249
Qoder uses PascalCase tool names natively (`Read`, `Glob`, `Grep`, `WebFetch`, `WebSearch`, `Write`, `Edit`, `Bash`). Write tools **lowercase** in config and OpenAgentPack converts them automatically when applying to Qoder — this keeps the same config portable to Bailian, Claude, and Volcengine Ark.
@@ -61,6 +78,12 @@ environments:
6178
type: cloud
6279
networking:
6380
type: unrestricted
81+
packages:
82+
npm: ["pnpm@9"]
83+
setup_script: |
84+
set -euo pipefail
85+
install -d /data/workspace/.openagentpack
86+
test -f /data/workspace/.openagentpack/ready || printf 'ready\n' > /data/workspace/.openagentpack/ready
6487
6588
agents:
6689
assistant:
@@ -73,6 +96,8 @@ agents:
7396
builtin: [read, glob, grep, web_search, web_fetch]
7497
```
7598

99+
Qoder runs `setup_script` after package installation with `/bin/bash -lc`. Scripts are limited to 64 KB of UTF-8 text and 10 minutes, and a non-zero exit prevents Session startup. Make them idempotent because they run again whenever the sandbox is rebuilt. Use vaults for credentials; never place secrets directly in a script. Qoder package declarations accept `apt`, `npm`, and `pip` only.
100+
76101
## What Qoder uniquely supports
77102

78103
- **Memory stores** — persistent context for an agent. See [`examples/qoder/with-memory/`](../../examples/qoder/with-memory/).

docs/reference/configuration.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ environments:
133133
type: cloud | self_hosted
134134
networking: { ... }
135135
packages: { ... }
136+
setup_script: <string>
136137
metadata: { <key>: <string> }
137138
```
138139

@@ -145,8 +146,13 @@ environments:
145146
| `config.networking.allow_package_managers` | boolean | no | Allow package managers. |
146147
| `config.networking.allowed_hosts` | string[] | no | Allow-list for `limited` networks. |
147148
| `config.packages.apt` \| `pip` \| `npm` \| `cargo` \| `gem` \| `go` | string[] | no | Preinstalled packages. |
149+
| `config.setup_script` | string | no | Sandbox setup script. Qoder runs it with `/bin/bash -lc` after package installation; maximum UTF-8 size is 64 KB. Other providers currently reject this field. |
148150
| `metadata` | map<string,string> | no | Free-form metadata. |
149151

152+
Qoder accepts only `apt`, `npm`, and `pip` in package requests. Its API may return empty `cargo`, `gem`, and `go` arrays as reserved response fields, but declaring non-empty values for them is rejected locally. Setup scripts run while a new sandbox is prepared, time out after 10 minutes, and a non-zero exit prevents the Session from starting. Keep scripts idempotent and use vault-backed credentials instead of embedding secrets.
153+
154+
For a managed Qoder `self_hosted` environment, `config` accepts only `type` and optional `setup_script`; networking and packages belong to cloud environments. External `environment_id` references remain unmanaged.
155+
150156
## Tunnel (Qoder BYOC)
151157

152158
```yaml
@@ -246,6 +252,7 @@ agents:
246252
skills: [ <string> | { type, skill_id, version? } ]
247253
vault: <string>
248254
memory_stores: [ <string> ]
255+
environment_variables: { <key>: <string> } # Qoder only
249256
resources: [ SessionResource ]
250257
multiagent: { type: "coordinator", agents: [...] }
251258
metadata: { <key>: <string> }
@@ -266,6 +273,7 @@ agents:
266273
| `skills[]` | string \| AgentSkillRef | no | Skill name or `{ type: "official"\|"custom", skill_id, version? }`. |
267274
| `vault` | string | no | Vault name. |
268275
| `memory_stores` | string[] | no | Bound memory stores. |
276+
| `environment_variables` | map<string,string> | no | Qoder runtime variables. Managed Sessions use Qoder's `KEY=VALUE;...` wire format; Forward Templates store the map as defaults and Forward Sessions send it under `config.environment_variables`. |
269277
| `resources` | SessionResource[] | no | Resources attached to every managed Session created for the Agent. |
270278
| `multiagent.type` | `"coordinator"` | no | Declare a coordinator agent. |
271279
| `multiagent.agents` | string[] | yes (with multiagent) | Agents it orchestrates. |

examples/qoder/full/agents.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ environments:
3232
packages:
3333
apt: [git, curl]
3434
pip: [requests]
35+
setup_script: |
36+
set -euo pipefail
37+
install -d /data/workspace/.openagentpack
38+
test -f /data/workspace/.openagentpack/ready || printf 'ready\n' > /data/workspace/.openagentpack/ready
3539
metadata:
3640
team: platform
3741

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-08-12
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
## Context
2+
3+
Environment declarations flow through the public TypeScript model and Zod parser, provider-aware validation, provider request mapping, and provider-specific reverse/normalization paths used by sync and drift detection. Qoder now exposes `config.setup_script` for both cloud and self-hosted environments, with a 64 KB UTF-8 limit, but every stage currently drops or rejects it. The same API documentation establishes POST update semantics, whole-config replacement, metadata patching, and a narrower writable package set than the shared model.
4+
5+
## Goals / Non-Goals
6+
7+
**Goals:**
8+
9+
- Make setup scripts converge through create, update, sync, export, and drift detection.
10+
- Fail locally for script-size and Qoder package-manager violations.
11+
- Normalize response-only Qoder defaults without hiding declarative differences.
12+
- Correct update and metadata-deletion behavior without changing BYOC ownership rules.
13+
- Prove the contract with focused automated tests and a disposable live Qoder environment.
14+
15+
**Non-Goals:**
16+
17+
- Execute setup scripts locally or expose their Session-time logs through a new API.
18+
- Add file-path indirection for script content; the declaration remains an inline YAML string.
19+
- Claim setup-script support for providers whose current API contract has not been verified.
20+
- Manage externally referenced environments.
21+
22+
## Decisions
23+
24+
1. Add `setup_script?: string` to the shared environment config, but gate actual use per provider. This keeps the declaration portable while preventing adapters from silently dropping unsupported behavior. A Qoder-only extension object was considered, but would make the common Environment model needlessly provider-shaped.
25+
2. Enforce the documented maximum with `Buffer.byteLength(value, "utf8")`, not JavaScript string length, because the remote limit is byte-oriented and scripts may contain non-ASCII content.
26+
3. Keep the shared package union for other providers, while Qoder validation rejects non-empty `cargo`, `gem`, and `go`. Qoder normalization retains only writable `apt`, `npm`, and `pip` values and removes empty response defaults plus `packages.type`.
27+
4. Include setup scripts in both reverse mapping and comparable normalization. Absence and an empty string remain distinct because clearing a saved script must be representable and reconciled.
28+
5. Change Qoder environment update to POST and construct metadata tombstones from the current remote object before updating. This matches Qoder's metadata patch semantics while still sending the complete desired config.
29+
6. Exercise live behavior with a uniquely named disposable environment loaded from `.env`, verify create/get/update/readback, then delete it in a `finally` cleanup path. No secret or `.env` content is printed.
30+
31+
## Risks / Trade-offs
32+
33+
- [Provider documentation changes again] → Keep Qoder-specific validation and normalization isolated and back it with request-contract tests.
34+
- [A live setup script can cause Session startup failure] → Use a harmless marker script in live testing and document idempotency, failure, and secret-handling guidance.
35+
- [Metadata tombstones could target management metadata] → Diff only non-`agents.*` remote metadata and continue injecting management metadata normally.
36+
- [Empty arrays from Qoder cause false drift] → Canonicalize package objects on both desired and remote sides before hashing.
37+
- [Live cleanup fails] → Print only the disposable resource ID/name and an explicit cleanup command, leaving credentials undisclosed.
38+
39+
## Migration Plan
40+
41+
The field is optional, so existing declarations retain their current hashes after normalization. Deploy the parser, validation, mapper, adapter, tests, and documentation together. Rollback is code-only; environments already containing scripts continue to exist remotely, though an older client would no longer manage that field.
42+
43+
## Open Questions
44+
45+
None. The current Qoder documentation is explicit about accepted fields, execution semantics, and update behavior.

0 commit comments

Comments
 (0)