agent-gear 2.4.0 → 2.5.0
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.
- package/AGENTS.md +64 -5
- package/dist/cloud-host/supervisor.d.ts +92 -0
- package/dist/cloud-host/supervisor.d.ts.map +1 -0
- package/dist/cloud-host/supervisor.js +216 -0
- package/dist/cloud-host/supervisor.js.map +1 -0
- package/dist/cloud-host/supervisor.test.d.ts +2 -0
- package/dist/cloud-host/supervisor.test.d.ts.map +1 -0
- package/dist/cloud-host/supervisor.test.js +296 -0
- package/dist/cloud-host/supervisor.test.js.map +1 -0
- package/dist/commands/harness.d.ts +17 -0
- package/dist/commands/harness.d.ts.map +1 -0
- package/dist/commands/harness.js +35 -0
- package/dist/commands/harness.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -3
- package/dist/config.js.map +1 -1
- package/dist/harness/env.d.ts +36 -0
- package/dist/harness/env.d.ts.map +1 -0
- package/dist/harness/env.js +78 -0
- package/dist/harness/env.js.map +1 -0
- package/dist/harness/env.test.d.ts +2 -0
- package/dist/harness/env.test.d.ts.map +1 -0
- package/dist/harness/env.test.js +70 -0
- package/dist/harness/env.test.js.map +1 -0
- package/dist/harness/opencode-cli.d.ts +24 -0
- package/dist/harness/opencode-cli.d.ts.map +1 -0
- package/dist/harness/opencode-cli.js +74 -0
- package/dist/harness/opencode-cli.js.map +1 -0
- package/dist/harness/opencode-cli.test.d.ts +2 -0
- package/dist/harness/opencode-cli.test.d.ts.map +1 -0
- package/dist/harness/opencode-cli.test.js +62 -0
- package/dist/harness/opencode-cli.test.js.map +1 -0
- package/dist/harness/opencode-config.atomic-failure.test.d.ts +2 -0
- package/dist/harness/opencode-config.atomic-failure.test.d.ts.map +1 -0
- package/dist/harness/opencode-config.atomic-failure.test.js +35 -0
- package/dist/harness/opencode-config.atomic-failure.test.js.map +1 -0
- package/dist/harness/opencode-config.d.ts +54 -0
- package/dist/harness/opencode-config.d.ts.map +1 -0
- package/dist/harness/opencode-config.js +130 -0
- package/dist/harness/opencode-config.js.map +1 -0
- package/dist/harness/opencode-config.test.d.ts +2 -0
- package/dist/harness/opencode-config.test.d.ts.map +1 -0
- package/dist/harness/opencode-config.test.js +183 -0
- package/dist/harness/opencode-config.test.js.map +1 -0
- package/dist/harness/prepare.d.ts +34 -0
- package/dist/harness/prepare.d.ts.map +1 -0
- package/dist/harness/prepare.js +46 -0
- package/dist/harness/prepare.js.map +1 -0
- package/dist/harness/prepare.test.d.ts +2 -0
- package/dist/harness/prepare.test.d.ts.map +1 -0
- package/dist/harness/prepare.test.js +96 -0
- package/dist/harness/prepare.test.js.map +1 -0
- package/dist/heartbeat.d.ts.map +1 -1
- package/dist/heartbeat.js +2 -0
- package/dist/heartbeat.js.map +1 -1
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -1
- package/dist/socketio-client.d.ts +62 -3
- package/dist/socketio-client.d.ts.map +1 -1
- package/dist/socketio-client.js +155 -16
- package/dist/socketio-client.js.map +1 -1
- package/dist/socketio-client.test.d.ts +2 -0
- package/dist/socketio-client.test.d.ts.map +1 -0
- package/dist/socketio-client.test.js +132 -0
- package/dist/socketio-client.test.js.map +1 -0
- package/dist/workload-executor.d.ts +24 -1
- package/dist/workload-executor.d.ts.map +1 -1
- package/dist/workload-executor.js +78 -16
- package/dist/workload-executor.js.map +1 -1
- package/dist/workload-executor.test.js +99 -1
- package/dist/workload-executor.test.js.map +1 -1
- package/package.json +2 -1
- package/src/cloud-host/supervisor.test.ts +367 -0
- package/src/cloud-host/supervisor.ts +289 -0
- package/src/commands/harness.ts +44 -0
- package/src/config.ts +9 -3
- package/src/harness/env.test.ts +79 -0
- package/src/harness/env.ts +89 -0
- package/src/harness/opencode-cli.test.ts +82 -0
- package/src/harness/opencode-cli.ts +99 -0
- package/src/harness/opencode-config.atomic-failure.test.ts +51 -0
- package/src/harness/opencode-config.test.ts +238 -0
- package/src/harness/opencode-config.ts +176 -0
- package/src/harness/prepare.test.ts +117 -0
- package/src/harness/prepare.ts +69 -0
- package/src/heartbeat.ts +2 -0
- package/src/index.ts +22 -0
- package/src/socketio-client.test.ts +155 -0
- package/src/socketio-client.ts +204 -18
- package/src/workload-executor.test.ts +120 -0
- package/src/workload-executor.ts +100 -17
- package/tests/commands/harness.test.ts +90 -0
- package/tests/socketio-client.test.ts +140 -2
package/AGENTS.md
CHANGED
|
@@ -16,8 +16,19 @@ src/
|
|
|
16
16
|
├── config.ts # Key/endpoint reading with priority chain
|
|
17
17
|
├── socketio-client.ts # Socket.IO client connection + event handling(register 上报完整版本)
|
|
18
18
|
├── heartbeat.ts # Heartbeat sender (30s interval)
|
|
19
|
-
├── workload-executor.ts # 工作负载脚本串行执行(超时/截断/重连重放)+
|
|
20
|
-
|
|
19
|
+
├── workload-executor.ts # 工作负载脚本串行执行(超时/截断/重连重放)+ 参数/容器 env 注入 + secret 脱敏
|
|
20
|
+
├── daemon.ts # Daemon management (PID file, signal handling)
|
|
21
|
+
├── cloud-host/
|
|
22
|
+
│ └── supervisor.ts # 云电脑双连接(/worker → controller-api)与 init 等待编排
|
|
23
|
+
├── harness/
|
|
24
|
+
│ ├── env.ts # harness env 校验(ZAG_MODEL_* / ZAG_DEFAULT_WORKSPACE)
|
|
25
|
+
│ ├── opencode-cli.ts # `opencode --version` 硬校验(兼容 `-v`)
|
|
26
|
+
│ ├── opencode-config.ts# opencode.jsonc 定位/合并(保留注释,仅替换 provider.zag,0600)
|
|
27
|
+
│ └── prepare.ts # `harness prepare` 编排 + 摘要(不含 secret)
|
|
28
|
+
└── commands/
|
|
29
|
+
├── harness.ts # `agent-gear harness prepare`
|
|
30
|
+
├── mcp.ts
|
|
31
|
+
└── mcp-proxy.ts
|
|
21
32
|
```
|
|
22
33
|
|
|
23
34
|
## 工作负载参数注入
|
|
@@ -41,9 +52,57 @@ src/
|
|
|
41
52
|
- `post` 批次不参与必须判定(`required` 固定 `false`,即使携带 `true` 也不短路)。
|
|
42
53
|
- 无 `required` 字段时行为与旧版完全一致(非必须项失败后继续执行后续条目)。
|
|
43
54
|
|
|
44
|
-
- 版本:包版本 `2.
|
|
45
|
-
|
|
46
|
-
|
|
55
|
+
- 版本:包版本 `2.5.0`(major 保持 2;云电脑双连接 / `harness prepare`,cloud-controller 对
|
|
56
|
+
`purpose=harness` 的 `MIN_HARNESS_WORKER_VERSION` 为 `2.5.0`)。参数注入需 `>=2.3.0`、`items[].required`
|
|
57
|
+
短路需 `>=2.4.0`;普通容器 `MIN_WORKER_VERSION` 仍为 `2.2.0`(服务端为唯一裁决,旧 worker 忽略
|
|
58
|
+
`required` 仍正确)。
|
|
59
|
+
|
|
60
|
+
## 容器级 env 与 secret 脱敏(2.5.0)
|
|
61
|
+
|
|
62
|
+
`workload:run` 可携带容器级 `env`(仅 `purpose=harness` 下发,如 `ZAG_MODEL_*` / `ZAG_HOST_*` /
|
|
63
|
+
`ZAG_DEFAULT_WORKSPACE`)。每个 item 的执行环境合并顺序:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
process.env → 容器 env(批次内所有 item) → WORKLOAD_PARAMS / WORKLOAD_PARAM_*(item 参数优先)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- `ZAG_MODEL_API_KEY` / `ZAG_HOST_KEY` / `ZAG_CONTROLLER_KEY` 的值在**脚本输出、日志、错误**中统一替换为
|
|
70
|
+
`***`(`redactSecrets`;日志中的 `workload:run` payload 同样脱敏)。
|
|
71
|
+
- 普通容器不携带 `env`,行为与旧版完全一致。
|
|
72
|
+
|
|
73
|
+
## 云电脑模式(cloud-host supervisor)
|
|
74
|
+
|
|
75
|
+
入口默认 action 检测 `ZAG_HOST_ENDPOINT` + `ZAG_HOST_KEY` + `ZAG_CONTROLLER_KEY`(三者同时非空):
|
|
76
|
+
|
|
77
|
+
| 连接 | endpoint env | 凭据 env | 职责 |
|
|
78
|
+
|------|--------------|----------|------|
|
|
79
|
+
| `/worker`(cloud-controller) | `ZAG_SERVER_ENDPOINT` | `ZAG_CONTROLLER_KEY`(一次性 token) | 生命周期 / 初始化脚本 |
|
|
80
|
+
| controller-api 标准连接 | `ZAG_HOST_ENDPOINT` | `ZAG_HOST_KEY`(仅握手 `auth.token`,不入 URL) | 会话 / ACP / 工作区 / 心跳 |
|
|
81
|
+
|
|
82
|
+
- 先连 `/worker`:`registered.initializing=true` 时等待首个 `workload:run` init 批次结束(成功/失败)后
|
|
83
|
+
再连 controller-api;`false`/缺省立即连接;等待上限 `HARNESS_INIT_WAIT_MS`(默认 10 分钟)。
|
|
84
|
+
**被打断(cancelled)的批次不算完成**(重连重放时继续等待);超时后迟到的 `registered` 不再次进入等待。
|
|
85
|
+
- 启动时 `mkdir -p ZAG_DEFAULT_WORKSPACE`(默认 `/root/workspace`,幂等)。
|
|
86
|
+
- 云电脑两端连接均 `persistConfig=false`:**不读写** `~/.zag/config.toml`(不落 resumeToken/Key);
|
|
87
|
+
本地单连接保持原行为,配置写入使用权限 `0600`。
|
|
88
|
+
- 任一端 `shutdown` → 关闭两端并退出:正常(服务端主动 shutdown/SIGTERM/SIGINT)退出 0;`version_mismatch:*` / `error:*` / 必须工作负载初始化失败退出 1(entrypoint 自愈与失败语义);**不发送 `unregister`**(容器销毁由 agent-api 编排)。
|
|
89
|
+
- `KEY_ALREADY_ONLINE` 在云电脑模式按 1s→2s→…→30s 退避手动重连;**仅在 `registered` 成功后重置退避计数**(connect 先于 register 结果,不能作为成功信号)。退避定时器不 `unref`,避免双端断开时进程静默退出。
|
|
90
|
+
- 双连接只启动一个 `LocalMcpServer`:`/worker` 连接 `skipLocalMcpStart=true`,标准连接负责启动。
|
|
91
|
+
- 未检测到云电脑模式时保持本地控制器单连接旧行为不变。
|
|
92
|
+
|
|
93
|
+
## harness prepare(OpenCode)
|
|
94
|
+
|
|
95
|
+
init 脚本(admin-api 迁移 005)在安装固定版本 OpenCode 后执行 `agent-gear harness prepare`:
|
|
96
|
+
|
|
97
|
+
1. 校验 `ZAG_MODEL_BASE_URL` / `ZAG_MODEL_API_KEY` / `ZAG_MODEL_IDS`(JSON 数组,去空去重)/
|
|
98
|
+
`ZAG_DEFAULT_WORKSPACE`;缺失项按变量名报错并非零退出(不泄漏其它 env 值)。
|
|
99
|
+
2. `opencode --version` 硬校验(旧版兼容 `opencode -v`),失败非零退出。
|
|
100
|
+
3. `mkdir -p ZAG_DEFAULT_WORKSPACE`。
|
|
101
|
+
4. 定位 `~/.config/opencode/opencode.jsonc`:同目录已有 `.json` 且无 `.jsonc` 时合并 `.json`;否则新建
|
|
102
|
+
`.jsonc`。使用 `jsonc-parser` 保留注释与既有 provider,仅替换 `provider.zag`;权限 0600。
|
|
103
|
+
`provider.zag = { npm: '@ai-sdk/openai-compatible', name: 'ZAG', options: { baseURL, apiKey }, models: { <id>: { name: <id> } } }`。
|
|
104
|
+
|
|
105
|
+
> 镜像**不预装** `@opencode/cli`,由 harness 工作负载按 `OPENCODE_CLI_VERSION` 固定版本安装。
|
|
47
106
|
|
|
48
107
|
## Dev Commands
|
|
49
108
|
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Socket } from 'socket.io-client';
|
|
2
|
+
import { type ConnectToServerOptions } from '../socketio-client.js';
|
|
3
|
+
/** 未设置 `HARNESS_INIT_WAIT_MS` 时的初始化等待上限(10 分钟)。 */
|
|
4
|
+
export declare const DEFAULT_HARNESS_INIT_WAIT_MS = 600000;
|
|
5
|
+
/** 未设置 `ZAG_DEFAULT_WORKSPACE` 时的默认工作区(容器内以 root 运行)。 */
|
|
6
|
+
export declare const DEFAULT_WORKSPACE = "/root/workspace";
|
|
7
|
+
/** 云电脑模式必需的环境变量(三者同时非空才进入 supervisor)。 */
|
|
8
|
+
export declare const CLOUD_HOST_MODE_KEYS: readonly ["ZAG_HOST_ENDPOINT", "ZAG_HOST_KEY", "ZAG_CONTROLLER_KEY"];
|
|
9
|
+
/** 云电脑 supervisor 的运行参数(从容器 env 读取)。 */
|
|
10
|
+
export interface CloudHostEnv {
|
|
11
|
+
/** controller-api 标准连接地址(env `ZAG_HOST_ENDPOINT`)。 */
|
|
12
|
+
hostEndpoint: string;
|
|
13
|
+
/** 标准连接凭据(env `ZAG_HOST_KEY`,仅经握手 auth.token 携带)。 */
|
|
14
|
+
hostKey: string;
|
|
15
|
+
/** cloud-controller `/worker` 一次性 token(env `ZAG_CONTROLLER_KEY`)。 */
|
|
16
|
+
controllerKey: string;
|
|
17
|
+
/** cloud-controller `/worker` 地址(env `ZAG_SERVER_ENDPOINT`)。 */
|
|
18
|
+
serverEndpoint: string;
|
|
19
|
+
/** 注册上报的主机名(env `ZAG_HOST_NAME`,缺省 `os.hostname()`)。 */
|
|
20
|
+
hostName: string;
|
|
21
|
+
/** 默认工作区(env `ZAG_DEFAULT_WORKSPACE`,缺省 `/root/workspace`)。 */
|
|
22
|
+
workspace: string;
|
|
23
|
+
/** 初始化等待超时(env `HARNESS_INIT_WAIT_MS`,缺省 10 分钟)。 */
|
|
24
|
+
initWaitMs: number;
|
|
25
|
+
}
|
|
26
|
+
/** 云电脑 env 校验失败(消息只含变量名,不含任何值)。 */
|
|
27
|
+
export declare class CloudHostEnvError extends Error {
|
|
28
|
+
constructor(message: string);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 模式检测:同时设置 `ZAG_HOST_ENDPOINT` + `ZAG_HOST_KEY` + `ZAG_CONTROLLER_KEY` 且非空
|
|
32
|
+
* → 云电脑模式;否则沿用本地控制器单连接旧路径。
|
|
33
|
+
*/
|
|
34
|
+
export declare function isCloudHostMode(env?: NodeJS.ProcessEnv): boolean;
|
|
35
|
+
/** 解析初始化等待超时:显式非正整数时回退默认值(不因错误配置阻塞上线)。 */
|
|
36
|
+
export declare function parseInitWaitMs(value: string | undefined): number;
|
|
37
|
+
/**
|
|
38
|
+
* 读取并校验云电脑模式 env。
|
|
39
|
+
*
|
|
40
|
+
* 缺失项一次性列出变量名(便于 init 日志定位),**绝不输出变量值**(含 secret)。
|
|
41
|
+
*/
|
|
42
|
+
export declare function readCloudHostEnv(env?: NodeJS.ProcessEnv): CloudHostEnv;
|
|
43
|
+
/** 依赖注入(测试锚定时序与副作用;生产使用默认实现)。 */
|
|
44
|
+
export interface CloudHostSupervisorDeps {
|
|
45
|
+
env?: NodeJS.ProcessEnv;
|
|
46
|
+
connect?: (endpoint: string, key: string, options?: ConnectToServerOptions) => Socket;
|
|
47
|
+
makeDir?: (path: string) => Promise<void>;
|
|
48
|
+
exit?: (code: number) => void;
|
|
49
|
+
log?: (message: string) => void;
|
|
50
|
+
/** 是否接管 SIGINT/SIGTERM(默认 true;测试关闭以免污染进程)。 */
|
|
51
|
+
installSignalHandlers?: boolean;
|
|
52
|
+
}
|
|
53
|
+
export interface CloudHostSupervisorHandle {
|
|
54
|
+
/** `/worker` 连接(cloud-controller)。 */
|
|
55
|
+
workerSocket: Socket;
|
|
56
|
+
/** controller-api 标准连接(初始化完成后才建立)。 */
|
|
57
|
+
readonly controllerSocket: Socket | null;
|
|
58
|
+
/** 已创建(幂等)的默认工作区。 */
|
|
59
|
+
workspace: string;
|
|
60
|
+
/**
|
|
61
|
+
* 关闭两端并退出(不发送 `unregister`)。
|
|
62
|
+
*
|
|
63
|
+
* `code` 缺省按 `reason` 自动判定:服务端主动 shutdown / 信号 / unregistered → 0;
|
|
64
|
+
* `version_mismatch:*` / `error:*` / 初始化失败类 → 1(避免错误路径 `exit(0)` 掩盖失败,
|
|
65
|
+
* 并让 entrypoint 的 VERSION_MISMATCH 自愈生效,C-2)。
|
|
66
|
+
*/
|
|
67
|
+
shutdown: (reason: string, code?: number) => void;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 错误/失败类 shutdown reason 判定(C-2):
|
|
71
|
+
*
|
|
72
|
+
* - `socketio-client` 把 `VERSION_MISMATCH` / 其它 `error` 事件转成
|
|
73
|
+
* `version_mismatch:*` / `error:<code>` 前缀;
|
|
74
|
+
* - cloud-controller 的必须工作负载失败 reason 形如「必须工作负载「x」初始化失败」
|
|
75
|
+
* (经 `worker shutdown: ...` 包装后仍需识别);
|
|
76
|
+
* - 其余(服务端主动 shutdown、`unregistered`、SIGINT/SIGTERM)视为正常退出。
|
|
77
|
+
*/
|
|
78
|
+
export declare function isFailureShutdownReason(reason: string): boolean;
|
|
79
|
+
/** 由 shutdown reason 推导退出码:失败路径 1、正常退出 0。 */
|
|
80
|
+
export declare function resolveShutdownExitCode(reason: string): number;
|
|
81
|
+
/**
|
|
82
|
+
* 云电脑双连接 supervisor(契约 `agent-controller-websocket.md` §4.3):
|
|
83
|
+
*
|
|
84
|
+
* 1. `mkdir -p ZAG_DEFAULT_WORKSPACE`(幂等);
|
|
85
|
+
* 2. 先连 cloud-controller `/worker`(`ZAG_SERVER_ENDPOINT` + `ZAG_CONTROLLER_KEY`);
|
|
86
|
+
* 3. `registered.initializing=true` → 等待首个 `workload:run` 批次结束(成功/失败/超时)后
|
|
87
|
+
* 再连 controller-api(`ZAG_HOST_ENDPOINT` + `ZAG_HOST_KEY`);`false`/缺省立即连接;
|
|
88
|
+
* 4. 任一端 `shutdown` → 关闭两端并退出(正常 0;`version_mismatch`/`error`/初始化失败 1);**始终不发送 `unregister`**;
|
|
89
|
+
* 5. 仅 controller-api 标准连接启动本地 MCP 回环服务(worker 连接跳过,避免端口冲突)。
|
|
90
|
+
*/
|
|
91
|
+
export declare function startCloudHostSupervisor(deps?: CloudHostSupervisorDeps): Promise<CloudHostSupervisorHandle>;
|
|
92
|
+
//# sourceMappingURL=supervisor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervisor.d.ts","sourceRoot":"","sources":["../../src/cloud-host/supervisor.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAGL,KAAK,sBAAsB,EAC5B,MAAM,uBAAuB,CAAC;AAE/B,mDAAmD;AACnD,eAAO,MAAM,4BAA4B,SAAU,CAAC;AAEpD,yDAAyD;AACzD,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAEnD,0CAA0C;AAC1C,eAAO,MAAM,oBAAoB,sEAAuE,CAAC;AAEzG,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,aAAa,EAAE,MAAM,CAAC;IACtB,gEAAgE;IAChE,cAAc,EAAE,MAAM,CAAC;IACvB,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,mCAAmC;AACnC,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,OAAO,EAAE,MAAM;CAI5B;AAMD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAE7E;AAED,0CAA0C;AAC1C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGjE;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,YAAY,CAuBnF;AAED,iCAAiC;AACjC,MAAM,WAAW,uBAAuB;IACtC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,sBAAsB,KAAK,MAAM,CAAC;IACtF,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,+CAA+C;IAC/C,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,yBAAyB;IACxC,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IACzC,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAW/D;AAED,6CAA6C;AAC7C,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9D;AAQD;;;;;;;;;GASG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,yBAAyB,CAAC,CA2HpC"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { mkdir } from 'node:fs/promises';
|
|
2
|
+
import { hostname } from 'node:os';
|
|
3
|
+
import { connectToServer, parseEndpoint, } from '../socketio-client.js';
|
|
4
|
+
/** 未设置 `HARNESS_INIT_WAIT_MS` 时的初始化等待上限(10 分钟)。 */
|
|
5
|
+
export const DEFAULT_HARNESS_INIT_WAIT_MS = 600_000;
|
|
6
|
+
/** 未设置 `ZAG_DEFAULT_WORKSPACE` 时的默认工作区(容器内以 root 运行)。 */
|
|
7
|
+
export const DEFAULT_WORKSPACE = '/root/workspace';
|
|
8
|
+
/** 云电脑模式必需的环境变量(三者同时非空才进入 supervisor)。 */
|
|
9
|
+
export const CLOUD_HOST_MODE_KEYS = ['ZAG_HOST_ENDPOINT', 'ZAG_HOST_KEY', 'ZAG_CONTROLLER_KEY'];
|
|
10
|
+
/** 云电脑 env 校验失败(消息只含变量名,不含任何值)。 */
|
|
11
|
+
export class CloudHostEnvError extends Error {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'CloudHostEnvError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function nonEmpty(value) {
|
|
18
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 模式检测:同时设置 `ZAG_HOST_ENDPOINT` + `ZAG_HOST_KEY` + `ZAG_CONTROLLER_KEY` 且非空
|
|
22
|
+
* → 云电脑模式;否则沿用本地控制器单连接旧路径。
|
|
23
|
+
*/
|
|
24
|
+
export function isCloudHostMode(env = process.env) {
|
|
25
|
+
return CLOUD_HOST_MODE_KEYS.every((key) => nonEmpty(env[key]).length > 0);
|
|
26
|
+
}
|
|
27
|
+
/** 解析初始化等待超时:显式非正整数时回退默认值(不因错误配置阻塞上线)。 */
|
|
28
|
+
export function parseInitWaitMs(value) {
|
|
29
|
+
const parsed = Number.parseInt(value ?? '', 10);
|
|
30
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_HARNESS_INIT_WAIT_MS;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 读取并校验云电脑模式 env。
|
|
34
|
+
*
|
|
35
|
+
* 缺失项一次性列出变量名(便于 init 日志定位),**绝不输出变量值**(含 secret)。
|
|
36
|
+
*/
|
|
37
|
+
export function readCloudHostEnv(env = process.env) {
|
|
38
|
+
const required = [
|
|
39
|
+
'ZAG_HOST_ENDPOINT',
|
|
40
|
+
'ZAG_HOST_KEY',
|
|
41
|
+
'ZAG_CONTROLLER_KEY',
|
|
42
|
+
'ZAG_SERVER_ENDPOINT',
|
|
43
|
+
];
|
|
44
|
+
const missing = required.filter((key) => nonEmpty(env[key]).length === 0);
|
|
45
|
+
if (missing.length > 0) {
|
|
46
|
+
throw new CloudHostEnvError(`missing required environment variable(s) for cloud-host mode: ${missing.join(', ')}`);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
hostEndpoint: nonEmpty(env.ZAG_HOST_ENDPOINT),
|
|
50
|
+
hostKey: nonEmpty(env.ZAG_HOST_KEY),
|
|
51
|
+
controllerKey: nonEmpty(env.ZAG_CONTROLLER_KEY),
|
|
52
|
+
serverEndpoint: nonEmpty(env.ZAG_SERVER_ENDPOINT),
|
|
53
|
+
hostName: nonEmpty(env.ZAG_HOST_NAME) || hostname(),
|
|
54
|
+
workspace: nonEmpty(env.ZAG_DEFAULT_WORKSPACE) || DEFAULT_WORKSPACE,
|
|
55
|
+
initWaitMs: parseInitWaitMs(env.HARNESS_INIT_WAIT_MS),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 错误/失败类 shutdown reason 判定(C-2):
|
|
60
|
+
*
|
|
61
|
+
* - `socketio-client` 把 `VERSION_MISMATCH` / 其它 `error` 事件转成
|
|
62
|
+
* `version_mismatch:*` / `error:<code>` 前缀;
|
|
63
|
+
* - cloud-controller 的必须工作负载失败 reason 形如「必须工作负载「x」初始化失败」
|
|
64
|
+
* (经 `worker shutdown: ...` 包装后仍需识别);
|
|
65
|
+
* - 其余(服务端主动 shutdown、`unregistered`、SIGINT/SIGTERM)视为正常退出。
|
|
66
|
+
*/
|
|
67
|
+
export function isFailureShutdownReason(reason) {
|
|
68
|
+
const normalized = reason.trim().toLowerCase();
|
|
69
|
+
// reason 可能被 `worker shutdown:` / `controller-api shutdown:` 包装,用 includes 判定前缀。
|
|
70
|
+
if (normalized.includes('version_mismatch:') || /(^|[\s:])error:/.test(normalized)) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
return (reason.includes('初始化失败') ||
|
|
74
|
+
normalized.includes('init failed') ||
|
|
75
|
+
normalized.includes('initialization failed'));
|
|
76
|
+
}
|
|
77
|
+
/** 由 shutdown reason 推导退出码:失败路径 1、正常退出 0。 */
|
|
78
|
+
export function resolveShutdownExitCode(reason) {
|
|
79
|
+
return isFailureShutdownReason(reason) ? 1 : 0;
|
|
80
|
+
}
|
|
81
|
+
/** 日志中的连接目标:仅 origin + namespace,绝不包含 query/token。 */
|
|
82
|
+
function describeEndpoint(endpoint) {
|
|
83
|
+
const { origin, namespace } = parseEndpoint(endpoint);
|
|
84
|
+
return namespace === '/' ? origin : `${origin}${namespace}`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 云电脑双连接 supervisor(契约 `agent-controller-websocket.md` §4.3):
|
|
88
|
+
*
|
|
89
|
+
* 1. `mkdir -p ZAG_DEFAULT_WORKSPACE`(幂等);
|
|
90
|
+
* 2. 先连 cloud-controller `/worker`(`ZAG_SERVER_ENDPOINT` + `ZAG_CONTROLLER_KEY`);
|
|
91
|
+
* 3. `registered.initializing=true` → 等待首个 `workload:run` 批次结束(成功/失败/超时)后
|
|
92
|
+
* 再连 controller-api(`ZAG_HOST_ENDPOINT` + `ZAG_HOST_KEY`);`false`/缺省立即连接;
|
|
93
|
+
* 4. 任一端 `shutdown` → 关闭两端并退出(正常 0;`version_mismatch`/`error`/初始化失败 1);**始终不发送 `unregister`**;
|
|
94
|
+
* 5. 仅 controller-api 标准连接启动本地 MCP 回环服务(worker 连接跳过,避免端口冲突)。
|
|
95
|
+
*/
|
|
96
|
+
export async function startCloudHostSupervisor(deps = {}) {
|
|
97
|
+
const env = readCloudHostEnv(deps.env ?? process.env);
|
|
98
|
+
const connect = deps.connect ?? connectToServer;
|
|
99
|
+
const makeDir = deps.makeDir ?? ((path) => mkdir(path, { recursive: true }).then(() => undefined));
|
|
100
|
+
const exit = deps.exit ?? ((code) => process.exit(code));
|
|
101
|
+
const log = deps.log ?? ((message) => console.log(message));
|
|
102
|
+
// 初始化脚本/工作负载需要在工作区落地前执行,先幂等创建工作区。
|
|
103
|
+
await makeDir(env.workspace);
|
|
104
|
+
log(`[CloudHost] workspace ready: ${env.workspace}`);
|
|
105
|
+
let controllerSocket = null;
|
|
106
|
+
let initWaitTimer = null;
|
|
107
|
+
let waitingForInit = false;
|
|
108
|
+
let initBatchCompleted = false;
|
|
109
|
+
let shutdownStarted = false;
|
|
110
|
+
const clearInitTimer = () => {
|
|
111
|
+
if (initWaitTimer) {
|
|
112
|
+
clearTimeout(initWaitTimer);
|
|
113
|
+
initWaitTimer = null;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const shutdown = (reason, code) => {
|
|
117
|
+
if (shutdownStarted)
|
|
118
|
+
return;
|
|
119
|
+
shutdownStarted = true;
|
|
120
|
+
clearInitTimer();
|
|
121
|
+
const exitCode = code ?? resolveShutdownExitCode(reason);
|
|
122
|
+
log(`[CloudHost] shutting down: ${reason} (exit ${exitCode})`);
|
|
123
|
+
try {
|
|
124
|
+
workerSocket.disconnect();
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
/* socket may already be closed */
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
controllerSocket?.disconnect();
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
/* socket may already be closed */
|
|
134
|
+
}
|
|
135
|
+
// 不发送 unregister:容器销毁由 agent-api 编排(stopCloudHost / TTL / 失败回调)。
|
|
136
|
+
// 失败/版本不兼容路径必须非零退出:Job 终态映射为 failed,且 entrypoint 的自愈升级生效(C-2)。
|
|
137
|
+
exit(exitCode);
|
|
138
|
+
};
|
|
139
|
+
const connectController = () => {
|
|
140
|
+
if (controllerSocket)
|
|
141
|
+
return;
|
|
142
|
+
clearInitTimer();
|
|
143
|
+
waitingForInit = false;
|
|
144
|
+
log(`[CloudHost] connecting controller-api: ${describeEndpoint(env.hostEndpoint)}`);
|
|
145
|
+
controllerSocket = connect(env.hostEndpoint, env.hostKey, {
|
|
146
|
+
serverName: env.hostName,
|
|
147
|
+
handshakeToken: env.hostKey,
|
|
148
|
+
handleWorkload: false,
|
|
149
|
+
skipLocalMcpStart: false,
|
|
150
|
+
persistConfig: false,
|
|
151
|
+
onShutdown: (payload) => shutdown(`controller-api shutdown: ${payload.reason}`),
|
|
152
|
+
});
|
|
153
|
+
};
|
|
154
|
+
const waitForInitBatch = () => {
|
|
155
|
+
if (initBatchCompleted) {
|
|
156
|
+
connectController();
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
if (waitingForInit)
|
|
160
|
+
return;
|
|
161
|
+
waitingForInit = true;
|
|
162
|
+
log(`[CloudHost] waiting for harness initialization (timeout ${env.initWaitMs}ms)`);
|
|
163
|
+
initWaitTimer = setTimeout(() => {
|
|
164
|
+
initWaitTimer = null;
|
|
165
|
+
// 超时后视为已完成:迟到的 registered(initializing=true) 不得再次进入等待(幽灵定时器)。
|
|
166
|
+
initBatchCompleted = true;
|
|
167
|
+
log('[CloudHost] harness initialization wait timed out; connecting controller-api anyway');
|
|
168
|
+
connectController();
|
|
169
|
+
}, env.initWaitMs);
|
|
170
|
+
};
|
|
171
|
+
const workerSocket = connect(env.serverEndpoint, env.controllerKey, {
|
|
172
|
+
serverName: env.hostName,
|
|
173
|
+
handshakeToken: env.controllerKey,
|
|
174
|
+
handleWorkload: true,
|
|
175
|
+
skipLocalMcpStart: true,
|
|
176
|
+
persistConfig: false,
|
|
177
|
+
onRegistered: (payload) => {
|
|
178
|
+
log(`[CloudHost] worker registered: ${payload.controllerId}${payload.initializing ? ' (initializing)' : ''}`);
|
|
179
|
+
if (payload.initializing) {
|
|
180
|
+
waitForInitBatch();
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
connectController();
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
onWorkloadBatchComplete: (summary) => {
|
|
187
|
+
if (summary.phase !== 'init')
|
|
188
|
+
return;
|
|
189
|
+
if (summary.cancelled || summary.status === 'cancelled') {
|
|
190
|
+
// 被新批次/销毁打断:不得视为初始化完成(重连重放 init 时 OpenCode 可能仍在安装)。
|
|
191
|
+
log('[CloudHost] harness initialization interrupted; waiting for replay');
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
initBatchCompleted = true;
|
|
195
|
+
if (waitingForInit) {
|
|
196
|
+
log(`[CloudHost] harness initialization finished (${summary.status}` +
|
|
197
|
+
`${summary.failedCount ? `, failed=${summary.failedCount}` : ''}); connecting controller-api`);
|
|
198
|
+
connectController();
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
onShutdown: (payload) => shutdown(`worker shutdown: ${payload.reason}`),
|
|
202
|
+
});
|
|
203
|
+
if (deps.installSignalHandlers !== false) {
|
|
204
|
+
process.once('SIGINT', () => shutdown('SIGINT'));
|
|
205
|
+
process.once('SIGTERM', () => shutdown('SIGTERM'));
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
workerSocket,
|
|
209
|
+
get controllerSocket() {
|
|
210
|
+
return controllerSocket;
|
|
211
|
+
},
|
|
212
|
+
workspace: env.workspace,
|
|
213
|
+
shutdown,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=supervisor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/cloud-host/supervisor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supervisor.test.d.ts","sourceRoot":"","sources":["../../src/cloud-host/supervisor.test.ts"],"names":[],"mappings":""}
|