@downcity/agent 1.1.113 → 1.1.119

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.
Files changed (137) hide show
  1. package/bin/agent/local/Agent.d.ts +39 -0
  2. package/bin/agent/local/Agent.d.ts.map +1 -1
  3. package/bin/agent/local/Agent.js +53 -0
  4. package/bin/agent/local/Agent.js.map +1 -1
  5. package/bin/agent/local/services/AgentAssemblyService.d.ts +4 -0
  6. package/bin/agent/local/services/AgentAssemblyService.d.ts.map +1 -1
  7. package/bin/agent/local/services/AgentAssemblyService.js +18 -2
  8. package/bin/agent/local/services/AgentAssemblyService.js.map +1 -1
  9. package/bin/agent/local/services/AgentLifecycleService.d.ts +6 -0
  10. package/bin/agent/local/services/AgentLifecycleService.d.ts.map +1 -1
  11. package/bin/agent/local/services/AgentLifecycleService.js +4 -0
  12. package/bin/agent/local/services/AgentLifecycleService.js.map +1 -1
  13. package/bin/agent/remote/RemoteAgent.d.ts +35 -1
  14. package/bin/agent/remote/RemoteAgent.d.ts.map +1 -1
  15. package/bin/agent/remote/RemoteAgent.js +37 -1
  16. package/bin/agent/remote/RemoteAgent.js.map +1 -1
  17. package/bin/agent/remote/RemoteTransport.d.ts +22 -0
  18. package/bin/agent/remote/RemoteTransport.d.ts.map +1 -1
  19. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts +17 -0
  20. package/bin/agent/remote/transports/HttpRemoteAgentTransport.d.ts.map +1 -1
  21. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js +63 -0
  22. package/bin/agent/remote/transports/HttpRemoteAgentTransport.js.map +1 -1
  23. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts +16 -0
  24. package/bin/agent/remote/transports/RpcRemoteAgentTransport.d.ts.map +1 -1
  25. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js +18 -0
  26. package/bin/agent/remote/transports/RpcRemoteAgentTransport.js.map +1 -1
  27. package/bin/executor/Executor.d.ts.map +1 -1
  28. package/bin/executor/Executor.js +7 -1
  29. package/bin/executor/Executor.js.map +1 -1
  30. package/bin/index.d.ts +0 -1
  31. package/bin/index.d.ts.map +1 -1
  32. package/bin/index.js +0 -1
  33. package/bin/index.js.map +1 -1
  34. package/bin/rpc/Client.d.ts +28 -0
  35. package/bin/rpc/Client.d.ts.map +1 -1
  36. package/bin/rpc/Client.js +63 -0
  37. package/bin/rpc/Client.js.map +1 -1
  38. package/bin/rpc/server/InternalHandlers.d.ts.map +1 -1
  39. package/bin/rpc/server/InternalHandlers.js +54 -0
  40. package/bin/rpc/server/InternalHandlers.js.map +1 -1
  41. package/bin/rpc/server/ServerTypes.d.ts +5 -0
  42. package/bin/rpc/server/ServerTypes.d.ts.map +1 -1
  43. package/bin/types/agent/AgentOptions.d.ts +9 -0
  44. package/bin/types/agent/AgentOptions.d.ts.map +1 -1
  45. package/bin/types/config/DowncityConfig.d.ts +2 -2
  46. package/bin/types/config/DowncityConfig.d.ts.map +1 -1
  47. package/bin/types/rpc/RpcProtocol.d.ts +53 -0
  48. package/bin/types/rpc/RpcProtocol.d.ts.map +1 -1
  49. package/package.json +4 -3
  50. package/scripts/linux-bubblewrap-sandbox.test.mjs +1 -1
  51. package/scripts/shell-sandbox-preflight.test.mjs +1 -1
  52. package/src/agent/local/Agent.ts +68 -0
  53. package/src/agent/local/services/AgentAssemblyService.ts +23 -2
  54. package/src/agent/local/services/AgentLifecycleService.ts +11 -0
  55. package/src/agent/remote/RemoteAgent.ts +54 -1
  56. package/src/agent/remote/RemoteTransport.ts +23 -0
  57. package/src/agent/remote/transports/HttpRemoteAgentTransport.ts +101 -0
  58. package/src/agent/remote/transports/RpcRemoteAgentTransport.ts +35 -0
  59. package/src/executor/Executor.ts +12 -2
  60. package/src/index.ts +0 -1
  61. package/src/rpc/Client.ts +80 -0
  62. package/src/rpc/server/InternalHandlers.ts +55 -0
  63. package/src/rpc/server/ServerTypes.ts +5 -0
  64. package/src/types/agent/AgentOptions.ts +10 -0
  65. package/src/types/config/DowncityConfig.ts +2 -2
  66. package/src/types/rpc/RpcProtocol.ts +59 -0
  67. package/tsconfig.tsbuildinfo +1 -1
  68. package/bin/executor/tools/shell/ShellToolBridge.d.ts +0 -79
  69. package/bin/executor/tools/shell/ShellToolBridge.d.ts.map +0 -1
  70. package/bin/executor/tools/shell/ShellToolBridge.js +0 -320
  71. package/bin/executor/tools/shell/ShellToolBridge.js.map +0 -1
  72. package/bin/executor/tools/shell/ShellToolDefinition.d.ts +0 -116
  73. package/bin/executor/tools/shell/ShellToolDefinition.d.ts.map +0 -1
  74. package/bin/executor/tools/shell/ShellToolDefinition.js +0 -369
  75. package/bin/executor/tools/shell/ShellToolDefinition.js.map +0 -1
  76. package/bin/executor/tools/shell/ShellToolFormatting.d.ts +0 -17
  77. package/bin/executor/tools/shell/ShellToolFormatting.d.ts.map +0 -1
  78. package/bin/executor/tools/shell/ShellToolFormatting.js +0 -36
  79. package/bin/executor/tools/shell/ShellToolFormatting.js.map +0 -1
  80. package/bin/executor/tools/shell/ShellToolSchemas.d.ts +0 -61
  81. package/bin/executor/tools/shell/ShellToolSchemas.d.ts.map +0 -1
  82. package/bin/executor/tools/shell/ShellToolSchemas.js +0 -130
  83. package/bin/executor/tools/shell/ShellToolSchemas.js.map +0 -1
  84. package/bin/executor/tools/shell/types/Shell.d.ts +0 -115
  85. package/bin/executor/tools/shell/types/Shell.d.ts.map +0 -1
  86. package/bin/executor/tools/shell/types/Shell.js +0 -9
  87. package/bin/executor/tools/shell/types/Shell.js.map +0 -1
  88. package/bin/executor/tools/shell/types/ShellPlugin.d.ts +0 -258
  89. package/bin/executor/tools/shell/types/ShellPlugin.d.ts.map +0 -1
  90. package/bin/executor/tools/shell/types/ShellPlugin.js +0 -9
  91. package/bin/executor/tools/shell/types/ShellPlugin.js.map +0 -1
  92. package/bin/sandbox/LinuxBubblewrapSandbox.d.ts +0 -19
  93. package/bin/sandbox/LinuxBubblewrapSandbox.d.ts.map +0 -1
  94. package/bin/sandbox/LinuxBubblewrapSandbox.js +0 -186
  95. package/bin/sandbox/LinuxBubblewrapSandbox.js.map +0 -1
  96. package/bin/sandbox/MacOsSeatbeltSandbox.d.ts +0 -16
  97. package/bin/sandbox/MacOsSeatbeltSandbox.d.ts.map +0 -1
  98. package/bin/sandbox/MacOsSeatbeltSandbox.js +0 -154
  99. package/bin/sandbox/MacOsSeatbeltSandbox.js.map +0 -1
  100. package/bin/sandbox/SandboxConfigResolver.d.ts +0 -37
  101. package/bin/sandbox/SandboxConfigResolver.d.ts.map +0 -1
  102. package/bin/sandbox/SandboxConfigResolver.js +0 -130
  103. package/bin/sandbox/SandboxConfigResolver.js.map +0 -1
  104. package/bin/sandbox/SandboxPreflight.d.ts +0 -73
  105. package/bin/sandbox/SandboxPreflight.d.ts.map +0 -1
  106. package/bin/sandbox/SandboxPreflight.js +0 -122
  107. package/bin/sandbox/SandboxPreflight.js.map +0 -1
  108. package/bin/sandbox/SandboxRunner.d.ts +0 -61
  109. package/bin/sandbox/SandboxRunner.d.ts.map +0 -1
  110. package/bin/sandbox/SandboxRunner.js +0 -107
  111. package/bin/sandbox/SandboxRunner.js.map +0 -1
  112. package/bin/sandbox/UnrestrictedSandbox.d.ts +0 -16
  113. package/bin/sandbox/UnrestrictedSandbox.d.ts.map +0 -1
  114. package/bin/sandbox/UnrestrictedSandbox.js +0 -39
  115. package/bin/sandbox/UnrestrictedSandbox.js.map +0 -1
  116. package/bin/sandbox/types/Sandbox.d.ts +0 -130
  117. package/bin/sandbox/types/Sandbox.d.ts.map +0 -1
  118. package/bin/sandbox/types/Sandbox.js +0 -10
  119. package/bin/sandbox/types/Sandbox.js.map +0 -1
  120. package/bin/sandbox/types/SandboxRuntime.d.ts +0 -370
  121. package/bin/sandbox/types/SandboxRuntime.d.ts.map +0 -1
  122. package/bin/sandbox/types/SandboxRuntime.js +0 -10
  123. package/bin/sandbox/types/SandboxRuntime.js.map +0 -1
  124. package/src/executor/tools/shell/ShellToolBridge.ts +0 -412
  125. package/src/executor/tools/shell/ShellToolDefinition.ts +0 -524
  126. package/src/executor/tools/shell/ShellToolFormatting.ts +0 -34
  127. package/src/executor/tools/shell/ShellToolSchemas.ts +0 -139
  128. package/src/executor/tools/shell/types/Shell.ts +0 -123
  129. package/src/executor/tools/shell/types/ShellPlugin.ts +0 -278
  130. package/src/sandbox/LinuxBubblewrapSandbox.ts +0 -222
  131. package/src/sandbox/MacOsSeatbeltSandbox.ts +0 -191
  132. package/src/sandbox/SandboxConfigResolver.ts +0 -152
  133. package/src/sandbox/SandboxPreflight.ts +0 -205
  134. package/src/sandbox/SandboxRunner.ts +0 -151
  135. package/src/sandbox/UnrestrictedSandbox.ts +0 -53
  136. package/src/sandbox/types/Sandbox.ts +0 -144
  137. package/src/sandbox/types/SandboxRuntime.ts +0 -440
@@ -1,123 +0,0 @@
1
- /**
2
- * Shell 工具类型定义。
3
- *
4
- * 关键点(中文)
5
- * - 统一沉淀 `shell_start/shell_status/shell_read/shell_write/shell_wait/shell_close` 类型。
6
- * - `shell_id` 与 chat `sessionId` 严格分离,避免语义混淆。
7
- */
8
-
9
- /**
10
- * shell 执行 sandbox 模式。
11
- */
12
- export type ShellSandboxMode = "safe" | "unrestricted";
13
-
14
- /**
15
- * shell unrestricted sandbox 申请原因。
16
- */
17
- export type ShellUnrestrictedReason = string;
18
-
19
- /**
20
- * 启动一个交互式 shell session 的输入。
21
- */
22
- export type ShellStartInput = {
23
- /** 要启动的命令文本。 */
24
- cmd: string;
25
- /** shell 进程的工作目录。 */
26
- workdir?: string;
27
- /** 显式指定 shell 可执行文件。 */
28
- shell?: string;
29
- /** 是否使用 login shell 语义启动。 */
30
- login?: boolean;
31
- /** 启动后内联等待输出的毫秒数。 */
32
- inline_wait_ms?: number;
33
- /** 最多返回多少输出 token。 */
34
- max_output_tokens?: number;
35
- /** 进程退出时是否自动通知调用方。 */
36
- auto_notify_on_exit?: boolean;
37
- /** 命令执行 sandbox 模式;默认 safe。 */
38
- sandbox?: ShellSandboxMode;
39
- /** 请求 unrestricted sandbox 时展示给用户的原因。 */
40
- reason?: string;
41
- };
42
-
43
- /**
44
- * 执行一次非持久 shell 命令的输入。
45
- */
46
- export type ShellExecInput = {
47
- /** 要执行的命令文本。 */
48
- cmd: string;
49
- /** 命令执行工作目录。 */
50
- workdir?: string;
51
- /** 显式指定 shell 可执行文件。 */
52
- shell?: string;
53
- /** 是否使用 login shell 语义启动。 */
54
- login?: boolean;
55
- /** 本次命令执行超时时间。 */
56
- timeout_ms?: number;
57
- /** 最多返回多少输出 token。 */
58
- max_output_tokens?: number;
59
- /** 命令执行 sandbox 模式;默认 safe。 */
60
- sandbox?: ShellSandboxMode;
61
- /** 请求 unrestricted sandbox 时展示给用户的原因。 */
62
- reason?: string;
63
- };
64
-
65
- /**
66
- * 查询 shell 运行状态的输入。
67
- */
68
- export type ShellStatusInput = {
69
- /** 要查询的 shell session ID。 */
70
- shell_id?: string;
71
- /** 可选的原始命令文本,用于宽松筛选。 */
72
- cmd?: string;
73
- };
74
-
75
- /**
76
- * 读取 shell 输出流的输入。
77
- */
78
- export type ShellReadInput = {
79
- /** 要读取的 shell session ID。 */
80
- shell_id: string;
81
- /** 从哪个游标开始增量读取。 */
82
- from_cursor?: number;
83
- /** 最多返回多少输出 token。 */
84
- max_output_tokens?: number;
85
- };
86
-
87
- /**
88
- * 向 shell session 写入输入字符。
89
- */
90
- export type ShellWriteInput = {
91
- /** 要写入的 shell session ID。 */
92
- shell_id: string;
93
- /** 要发送到 stdin 的字符内容。 */
94
- chars: string;
95
- /** 向 unrestricted shell session 写入 stdin 时展示给用户的原因。 */
96
- reason?: ShellUnrestrictedReason;
97
- };
98
-
99
- /**
100
- * 等待 shell 新输出的输入。
101
- */
102
- export type ShellWaitInput = {
103
- /** 要等待的 shell session ID。 */
104
- shell_id: string;
105
- /** 从哪个版本号之后开始等待变更。 */
106
- after_version?: number;
107
- /** 从哪个输出游标开始读取。 */
108
- from_cursor?: number;
109
- /** 最长等待时间。 */
110
- timeout_ms?: number;
111
- /** 最多返回多少输出 token。 */
112
- max_output_tokens?: number;
113
- };
114
-
115
- /**
116
- * 关闭 shell session 的输入。
117
- */
118
- export type ShellCloseInput = {
119
- /** 要关闭的 shell session ID。 */
120
- shell_id: string;
121
- /** 是否强制结束子进程。 */
122
- force?: boolean;
123
- };
@@ -1,278 +0,0 @@
1
- /**
2
- * Shell plugin runtime 类型定义。
3
- *
4
- * 关键点(中文)
5
- * - `shell_id` 是 shell 会话的唯一标识,与 chat `sessionId` 严格区分。
6
- * - 这些类型同时服务于 shell runtime 状态管理与 agent tool 协议。
7
- */
8
-
9
- export type ShellSessionStatus =
10
- | "starting"
11
- | "running"
12
- | "completed"
13
- | "failed"
14
- | "killed"
15
- | "expired";
16
-
17
- /**
18
- * shell 执行 sandbox 模式。
19
- */
20
- export type ShellSandboxMode = "safe" | "unrestricted";
21
-
22
- /**
23
- * unrestricted sandbox 审批状态。
24
- */
25
- export type ShellApprovalStatus = "approved" | "denied" | "expired";
26
-
27
- /**
28
- * shell unrestricted sandbox 审批来源工具。
29
- */
30
- export type ShellApprovalToolName = "shell_exec" | "shell_start" | "shell_write";
31
-
32
- /**
33
- * shell 会话关联的外部引用。
34
- *
35
- * 说明(中文)
36
- * - 用于记录诸如第三方平台 `thread_id`、任务链接等弱结构化引用。
37
- * - 不要求所有 shell 都存在该信息;仅在可识别时附加。
38
- */
39
- export type ShellExternalRef = {
40
- /** 引用类别,例如 `thread_id`。 */
41
- kind: string;
42
- /** 引用的原始值。 */
43
- value: string;
44
- /** 可选的人类可读标签。 */
45
- label?: string;
46
- };
47
-
48
- /**
49
- * shell 会话快照。
50
- *
51
- * 说明(中文)
52
- * - 该对象是 shell plugin runtime 对外暴露的统一状态视图。
53
- * - 内部运行态(child process / waiter 集合)不会暴露给上层。
54
- */
55
- export type ShellSessionSnapshot = {
56
- /** shell 唯一标识。 */
57
- shellId: string;
58
- /** 发起该 shell 的 chat/context 标识;不存在时表示非聊天上下文触发。 */
59
- ownerContextId?: string;
60
- /** 原始命令字符串。 */
61
- cmd: string;
62
- /** 命令执行工作目录(绝对路径)。 */
63
- cwd: string;
64
- /** 实际使用的 shell 可执行文件路径。 */
65
- shellPath: string;
66
- /** 当前 shell 是否运行在 sandbox 中。 */
67
- sandboxed?: boolean;
68
- /** 当前 shell 的 Downcity sandbox 模式。 */
69
- sandboxMode?: ShellSandboxMode;
70
- /** unrestricted sandbox 审批状态。 */
71
- approvalStatus?: ShellApprovalStatus;
72
- /** unrestricted sandbox 审批请求 ID。 */
73
- approvalId?: string;
74
- /** unrestricted sandbox 申请原因。 */
75
- approvalReason?: string;
76
- /** 当前 shell 是否允许继续写入 stdin。 */
77
- stdinWritable?: boolean;
78
- /** 当前 shell 使用的 sandbox backend。 */
79
- sandboxBackend?: string;
80
- /** 当前 shell 采用的 sandbox 网络模式。 */
81
- sandboxNetworkMode?: "off" | "restricted" | "full";
82
- /** 当前 agent 级 sandbox 的持久目录。 */
83
- sandboxDir?: string;
84
- /** 当前 shell 在 sandbox 中使用的 HOME。 */
85
- sandboxHomeDir?: string;
86
- /** 当前 shell 在 sandbox 中使用的临时目录。 */
87
- sandboxTmpDir?: string;
88
- /** 当前 shell 在 sandbox 中使用的 XDG cache 目录。 */
89
- sandboxCacheDir?: string;
90
- /** 当前 shell 状态。 */
91
- status: ShellSessionStatus;
92
- /** 子进程 pid;若尚未创建成功则为空。 */
93
- pid?: number;
94
- /** shell 创建时间戳(毫秒)。 */
95
- startedAt: number;
96
- /** 最近一次状态或输出变更时间戳(毫秒)。 */
97
- updatedAt: number;
98
- /** shell 结束时间戳(毫秒);运行中为空。 */
99
- endedAt?: number;
100
- /** 进程退出码;运行中为空。 */
101
- exitCode?: number;
102
- /** 最近一次收到输出的时间戳(毫秒)。 */
103
- lastOutputAt?: number;
104
- /** 最近一小段输出预览,供状态查询快速展示。 */
105
- lastOutputPreview?: string;
106
- /** 当前累计输出字符数。 */
107
- outputChars: number;
108
- /** 因内存缓存裁剪而丢弃的字符数。 */
109
- droppedChars: number;
110
- /** 状态版本号;任意输出/状态变化都递增。 */
111
- version: number;
112
- /** 是否在 shell 结束后自动回投到所属 chat,让主 agent 自己回复。 */
113
- autoNotifyOnExit: boolean;
114
- /** 自动回投是否已经发送,避免重复通知。 */
115
- notificationSent: boolean;
116
- /** 从输出中识别到的外部引用集合。 */
117
- externalRefs: ShellExternalRef[];
118
- };
119
-
120
- /**
121
- * shell 启动请求。
122
- */
123
- export type ShellStartRequest = {
124
- /** 要执行的完整 shell 命令。 */
125
- cmd: string;
126
- /** 可选工作目录;为空时回退项目根目录。 */
127
- cwd?: string;
128
- /** 可选 shell 路径,例如 `/bin/zsh`。 */
129
- shell?: string;
130
- /** 是否以 login shell 方式启动;默认 `true`。 */
131
- login?: boolean;
132
- /** 启动后内联等待多久再返回首批状态/输出。 */
133
- inlineWaitMs?: number;
134
- /** 单次读取输出返回给模型的 token 上限。 */
135
- maxOutputTokens?: number;
136
- /** 显式指定 owner sessionId;为空时优先从 SessionRunScope 推断。 */
137
- ownerContextId?: string;
138
- /** 是否在 shell 结束后自动回投主 chat agent。 */
139
- autoNotifyOnExit?: boolean;
140
- /** 命令执行 sandbox 模式;默认 safe。 */
141
- sandbox?: ShellSandboxMode;
142
- /** 请求 unrestricted sandbox 时展示给用户的原因。 */
143
- reason?: string;
144
- /** 内部审批来源工具名;普通调用方不需要传。 */
145
- approvalToolName?: ShellApprovalToolName;
146
- };
147
-
148
- /**
149
- * shell 一次性执行请求。
150
- *
151
- * 说明(中文)
152
- * - 适合短命令与无需中途查询状态的场景。
153
- * - 底层仍复用 shell session 引擎,但调用方不需要管理 `shell_id`。
154
- */
155
- export type ShellExecRequest = {
156
- /** 要执行的完整 shell 命令。 */
157
- cmd: string;
158
- /** 可选工作目录;为空时回退项目根目录。 */
159
- cwd?: string;
160
- /** 可选 shell 路径,例如 `/bin/zsh`。 */
161
- shell?: string;
162
- /** 是否以 login shell 方式启动;默认 `true`。 */
163
- login?: boolean;
164
- /** 整个一次性执行的总超时时间(毫秒)。 */
165
- timeoutMs?: number;
166
- /** 单次读取输出返回给模型的 token 上限。 */
167
- maxOutputTokens?: number;
168
- /** 命令执行 sandbox 模式;默认 safe。 */
169
- sandbox?: ShellSandboxMode;
170
- /** 请求 unrestricted sandbox 时展示给用户的原因。 */
171
- reason?: string;
172
- };
173
-
174
- /**
175
- * shell 查询请求。
176
- *
177
- * 说明(中文)
178
- * - `shellId` 优先级最高。
179
- * - 若未提供 `shellId`,允许在同一 owner context 下按 `cmd` 模糊匹配最近一个会话。
180
- */
181
- export type ShellQueryRequest = {
182
- /** 目标 shell_id。 */
183
- shellId?: string;
184
- /** 命令关键字;用于在当前 context 下查找最近匹配会话。 */
185
- cmd?: string;
186
- /** 指定 owner sessionId;为空时优先从 SessionRunScope 推断。 */
187
- ownerContextId?: string;
188
- /** 是否允许匹配已结束会话。 */
189
- includeCompleted?: boolean;
190
- };
191
-
192
- /**
193
- * shell 输出读取请求。
194
- */
195
- export type ShellReadRequest = ShellQueryRequest & {
196
- /** 从哪个字符偏移开始读取;默认从头或从最新游标外部自行维护。 */
197
- fromCursor?: number;
198
- /** 单次读取输出返回给模型的 token 上限。 */
199
- maxOutputTokens?: number;
200
- };
201
-
202
- /**
203
- * shell stdin 写入请求。
204
- */
205
- export type ShellWriteRequest = {
206
- /** 目标 shell_id。 */
207
- shellId: string;
208
- /** 要写入 stdin 的原始文本。 */
209
- chars: string;
210
- /** 向 unrestricted shell session 写入 stdin 时展示给用户的原因。 */
211
- reason?: string;
212
- };
213
-
214
- /**
215
- * shell 等待请求。
216
- *
217
- * 说明(中文)
218
- * - `afterVersion` 用于等待“状态变化”而非模型侧空轮询。
219
- * - 可同时附带 `fromCursor`,一旦变化就顺便取回新的输出增量。
220
- */
221
- export type ShellWaitRequest = {
222
- /** 目标 shell_id。 */
223
- shellId: string;
224
- /** 仅当版本号大于该值时才立即返回。 */
225
- afterVersion?: number;
226
- /** 读取输出的起始字符游标。 */
227
- fromCursor?: number;
228
- /** 最大等待时间(毫秒)。 */
229
- timeoutMs?: number;
230
- /** 单次读取输出返回给模型的 token 上限。 */
231
- maxOutputTokens?: number;
232
- };
233
-
234
- /**
235
- * shell 关闭请求。
236
- */
237
- export type ShellCloseRequest = {
238
- /** 目标 shell_id。 */
239
- shellId: string;
240
- /** 是否强制 kill(SIGKILL);默认优雅终止。 */
241
- force?: boolean;
242
- };
243
-
244
- /**
245
- * shell 输出块。
246
- *
247
- * 说明(中文)
248
- * - 统一用于 `start/read/wait` 的输出增量返回。
249
- * - `startCursor/endCursor` 采用字符偏移,便于上层自行维护断点。
250
- */
251
- export type ShellOutputChunk = {
252
- /** 本次输出块对应的 shell_id。 */
253
- shellId: string;
254
- /** 本次读取返回的文本。 */
255
- output: string;
256
- /** 本次读取的起始字符游标。 */
257
- startCursor: number;
258
- /** 本次读取结束后的字符游标。 */
259
- endCursor: number;
260
- /** 原始待读取文本字符数。 */
261
- originalChars: number;
262
- /** 原始待读取文本行数。 */
263
- originalLines: number;
264
- /** 是否仍有未读输出。 */
265
- hasMoreOutput: boolean;
266
- };
267
-
268
- /**
269
- * shell plugin runtime 对 agent tool 返回的统一数据结构。
270
- */
271
- export type ShellActionResponse = {
272
- /** shell 当前快照。 */
273
- shell: ShellSessionSnapshot;
274
- /** 可选输出块;仅在 start/read/wait 中返回。 */
275
- chunk?: ShellOutputChunk;
276
- /** 操作说明或附加提示。 */
277
- note?: string;
278
- };
@@ -1,222 +0,0 @@
1
- /**
2
- * Linux Bubblewrap sandbox backend。
3
- *
4
- * 关键点(中文)
5
- * - 基于 `bwrap` 提供 Linux 本机 shell sandbox。
6
- * - 继续保持“shell 命令必须进入 sandbox”的安全语义,不提供宿主机裸跑回退。
7
- * - 边界与 macOS backend 对齐:路径、环境变量、网络、agent 级共享 HOME/TMPDIR/cache。
8
- */
9
-
10
- import { spawn } from "node:child_process";
11
- import path from "node:path";
12
- import fs from "fs-extra";
13
- import type {
14
- SandboxSpawnParams,
15
- SandboxSpawnResult,
16
- } from "@/sandbox/types/SandboxRuntime.js";
17
-
18
- const DEFAULT_PATH_VALUE =
19
- "/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin";
20
-
21
- function dedupeExistingPaths(values: string[]): string[] {
22
- const seen = new Set<string>();
23
- const result: string[] = [];
24
- for (const value of values) {
25
- const normalized = path.resolve(String(value || "").trim());
26
- if (!normalized || seen.has(normalized)) continue;
27
- if (!fs.existsSync(normalized)) continue;
28
- seen.add(normalized);
29
- result.push(normalized);
30
- }
31
- return result;
32
- }
33
-
34
- function buildReadablePaths(params: {
35
- rootPath: string;
36
- shellPath: string;
37
- sandboxDir: string;
38
- tmpDir: string;
39
- cacheDir: string;
40
- }): string[] {
41
- return dedupeExistingPaths([
42
- "/usr",
43
- "/bin",
44
- "/sbin",
45
- "/lib",
46
- "/lib64",
47
- "/etc",
48
- params.rootPath,
49
- params.sandboxDir,
50
- params.tmpDir,
51
- params.cacheDir,
52
- path.dirname(params.shellPath),
53
- ]);
54
- }
55
-
56
- function buildWritablePaths(params: SandboxSpawnParams): string[] {
57
- return dedupeExistingPaths([
58
- ...params.config.writablePaths,
59
- params.executionDir,
60
- params.config.sandboxDir,
61
- params.config.tmpDir,
62
- params.config.cacheDir,
63
- ]);
64
- }
65
-
66
- function isPathCoveredBy(paths: string[], targetPath: string): boolean {
67
- const normalizedTarget = path.resolve(targetPath);
68
- return paths.some((value) => {
69
- const normalizedValue = path.resolve(value);
70
- if (normalizedValue === normalizedTarget) return true;
71
- const relative = path.relative(normalizedValue, normalizedTarget);
72
- return Boolean(relative) && !relative.startsWith("..") && !path.isAbsolute(relative);
73
- });
74
- }
75
-
76
- function buildSandboxEnv(params: SandboxSpawnParams): NodeJS.ProcessEnv {
77
- const env: NodeJS.ProcessEnv = {};
78
- for (const key of params.config.envAllowlist) {
79
- const value = params.baseEnv[key];
80
- if (typeof value !== "string" || !value.trim()) continue;
81
- env[key] = value;
82
- }
83
-
84
- for (const [key, value] of Object.entries(params.baseEnv)) {
85
- if (!key.startsWith("DC_")) continue;
86
- if (typeof value !== "string" || !value.trim()) continue;
87
- env[key] = value;
88
- }
89
-
90
- env.PATH = String(env.PATH || params.baseEnv.PATH || DEFAULT_PATH_VALUE);
91
- env.HOME = params.config.homeDir;
92
- env.TMPDIR = params.config.tmpDir;
93
- env.XDG_CACHE_HOME = params.config.cacheDir;
94
- env.DC_SANDBOX = "1";
95
- env.DC_SANDBOX_DIR = params.config.sandboxDir;
96
- env.DC_SANDBOX_HOME = params.config.homeDir;
97
- env.DC_SANDBOX_CACHE = params.config.cacheDir;
98
- env.SHELL = params.shellPath;
99
-
100
- return env;
101
- }
102
-
103
- function addReadOnlyBind(args: string[], sourcePath: string): void {
104
- args.push("--ro-bind", sourcePath, sourcePath);
105
- }
106
-
107
- function addWritableBind(args: string[], sourcePath: string): void {
108
- args.push("--bind", sourcePath, sourcePath);
109
- }
110
-
111
- function addParentDirs(args: string[], targetPath: string, createdDirs: Set<string>): void {
112
- const parts = path.resolve(targetPath).split(path.sep).filter(Boolean);
113
- let current = "";
114
- for (let index = 0; index < parts.length - 1; index += 1) {
115
- current = `${current}/${parts[index]}`;
116
- if (createdDirs.has(current)) continue;
117
- createdDirs.add(current);
118
- args.push("--dir", current);
119
- }
120
- }
121
-
122
- export function buildLinuxBubblewrapArgs(params: SandboxSpawnParams & {
123
- actualCwd: string;
124
- }): string[] {
125
- const readablePaths = buildReadablePaths({
126
- rootPath: params.config.rootPath,
127
- shellPath: params.shellPath,
128
- sandboxDir: params.config.sandboxDir,
129
- tmpDir: params.config.tmpDir,
130
- cacheDir: params.config.cacheDir,
131
- });
132
- const writablePaths = buildWritablePaths(params);
133
- const writableSet = new Set(writablePaths);
134
- const createdDirs = new Set<string>();
135
- const mountedPaths: string[] = [];
136
- const args = [
137
- "--die-with-parent",
138
- "--unshare-pid",
139
- "--proc",
140
- "/proc",
141
- "--dev",
142
- "/dev",
143
- ];
144
-
145
- if (params.config.networkMode === "off") {
146
- args.push("--unshare-net");
147
- }
148
-
149
- for (const readablePath of readablePaths) {
150
- if (writableSet.has(readablePath)) continue;
151
- if (!isPathCoveredBy(mountedPaths, readablePath)) {
152
- addParentDirs(args, readablePath, createdDirs);
153
- }
154
- addReadOnlyBind(args, readablePath);
155
- mountedPaths.push(readablePath);
156
- }
157
-
158
- for (const writablePath of writablePaths) {
159
- if (isPathCoveredBy(mountedPaths, writablePath)) continue;
160
- addParentDirs(args, writablePath, createdDirs);
161
- addWritableBind(args, writablePath);
162
- mountedPaths.push(writablePath);
163
- }
164
-
165
- if (
166
- !isPathCoveredBy(readablePaths, params.actualCwd) &&
167
- !isPathCoveredBy(writablePaths, params.actualCwd)
168
- ) {
169
- if (!isPathCoveredBy(mountedPaths, params.actualCwd)) {
170
- addParentDirs(args, params.actualCwd, createdDirs);
171
- }
172
- addReadOnlyBind(args, params.actualCwd);
173
- }
174
-
175
- args.push(
176
- "--chdir",
177
- params.actualCwd,
178
- params.shellPath,
179
- params.login ? "-lc" : "-c",
180
- params.cmd,
181
- );
182
- return args;
183
- }
184
-
185
- /**
186
- * 在 Linux bubblewrap sandbox 中启动 shell 子进程。
187
- */
188
- export async function spawnLinuxBubblewrapSandbox(
189
- params: SandboxSpawnParams & { actualCwd: string },
190
- ): Promise<SandboxSpawnResult> {
191
- await fs.ensureDir(params.config.sandboxDir);
192
- await fs.ensureDir(params.config.tmpDir);
193
- await fs.ensureDir(params.config.cacheDir);
194
- await fs.ensureDir(params.executionDir);
195
- for (const writablePath of params.config.writablePaths) {
196
- await fs.ensureDir(writablePath);
197
- }
198
-
199
- const child = spawn("bwrap", buildLinuxBubblewrapArgs({
200
- ...params,
201
- }), {
202
- cwd: params.actualCwd,
203
- stdio: "pipe",
204
- env: buildSandboxEnv(params),
205
- });
206
-
207
- child.stdout.setEncoding("utf8");
208
- child.stderr.setEncoding("utf8");
209
-
210
- return {
211
- child,
212
- cwd: params.actualCwd,
213
- sandboxed: true,
214
- sandboxMode: "safe",
215
- backend: "linux-bubblewrap",
216
- networkMode: params.config.networkMode,
217
- sandboxDir: params.config.sandboxDir,
218
- homeDir: params.config.homeDir,
219
- tmpDir: params.config.tmpDir,
220
- cacheDir: params.config.cacheDir,
221
- };
222
- }