berry-agent 0.1.0-alpha.1

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 (401) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +96 -0
  3. package/dist/.api-emit.stamp +1 -0
  4. package/dist/.build-meta.json +6 -0
  5. package/dist/agent/events.js +1 -0
  6. package/dist/agent/index.js +2 -0
  7. package/dist/agent/loop.js +139 -0
  8. package/dist/agent/queue.js +119 -0
  9. package/dist/agent/stream.js +62 -0
  10. package/dist/agent/tools-batch.js +221 -0
  11. package/dist/agent/types.js +8 -0
  12. package/dist/api/berry-agent-llm.d.ts +18 -0
  13. package/dist/api/berry-agent.d.ts +9 -0
  14. package/dist/api/surface.json +1632 -0
  15. package/dist/api/tsconfig.paths.json +12 -0
  16. package/dist/api/typebox-compile.d.ts +2 -0
  17. package/dist/api/typebox-value.d.ts +2 -0
  18. package/dist/api/typebox.d.ts +2 -0
  19. package/dist/browser/cdp.js +256 -0
  20. package/dist/browser/codes.js +31 -0
  21. package/dist/browser/discover.js +107 -0
  22. package/dist/browser/engine.js +169 -0
  23. package/dist/browser/index.js +17 -0
  24. package/dist/browser/install.js +342 -0
  25. package/dist/browser/page.js +321 -0
  26. package/dist/browser/service.js +158 -0
  27. package/dist/browser/tools.js +198 -0
  28. package/dist/browser/types.js +81 -0
  29. package/dist/channels/ask-queue.js +82 -0
  30. package/dist/channels/commands.js +129 -0
  31. package/dist/channels/engine/cell.js +143 -0
  32. package/dist/channels/engine/diff.js +143 -0
  33. package/dist/channels/engine/engine.js +416 -0
  34. package/dist/channels/engine/index.js +8 -0
  35. package/dist/channels/engine/input-keys.js +86 -0
  36. package/dist/channels/engine/input.js +596 -0
  37. package/dist/channels/engine/memory-io.js +71 -0
  38. package/dist/channels/engine/process-io.js +38 -0
  39. package/dist/channels/engine/types.js +17 -0
  40. package/dist/channels/engine/width.js +122 -0
  41. package/dist/channels/index.js +15 -0
  42. package/dist/channels/registry.js +56 -0
  43. package/dist/channels/sdk/admit.js +29 -0
  44. package/dist/channels/sdk/backend.js +102 -0
  45. package/dist/channels/sdk/cursor.js +56 -0
  46. package/dist/channels/sdk/index.js +20 -0
  47. package/dist/channels/sdk/jsonl.js +208 -0
  48. package/dist/channels/sdk/protocol.js +24 -0
  49. package/dist/channels/sdk/schema.js +91 -0
  50. package/dist/channels/sdk/wire-core.js +446 -0
  51. package/dist/channels/service.js +169 -0
  52. package/dist/channels/tui/autocomplete/autocomplete.js +42 -0
  53. package/dist/channels/tui/autocomplete/file-mentions.js +106 -0
  54. package/dist/channels/tui/autocomplete/popup.js +148 -0
  55. package/dist/channels/tui/autocomplete/provider.js +7 -0
  56. package/dist/channels/tui/autocomplete/token.js +68 -0
  57. package/dist/channels/tui/backend/ansi-rows.js +211 -0
  58. package/dist/channels/tui/backend/main-screen.js +207 -0
  59. package/dist/channels/tui/backend/osc.js +91 -0
  60. package/dist/channels/tui/backend/transcript.js +230 -0
  61. package/dist/channels/tui/backend/tui-backend.js +915 -0
  62. package/dist/channels/tui/editor/editor-model.js +543 -0
  63. package/dist/channels/tui/editor/editor-view.js +140 -0
  64. package/dist/channels/tui/editor/editor.js +275 -0
  65. package/dist/channels/tui/editor/undo-stack.js +35 -0
  66. package/dist/channels/tui/editor/visual-lines.js +126 -0
  67. package/dist/channels/tui/editor/word-nav.js +106 -0
  68. package/dist/channels/tui/history/history-viewer.js +403 -0
  69. package/dist/channels/tui/index.js +3 -0
  70. package/dist/channels/tui/layout.js +167 -0
  71. package/dist/channels/tui/markdown/blocks.js +111 -0
  72. package/dist/channels/tui/markdown/inline.js +75 -0
  73. package/dist/channels/tui/markdown/markdown.js +182 -0
  74. package/dist/channels/tui/memory/memory-viewer.js +540 -0
  75. package/dist/channels/tui/overlay/alt-screen.js +105 -0
  76. package/dist/channels/tui/overlay/overlay.js +57 -0
  77. package/dist/channels/tui/overlay/select-confirm.js +156 -0
  78. package/dist/channels/tui/panels/todo-panel.js +54 -0
  79. package/dist/channels/tui/panels/tool-progress-panel.js +93 -0
  80. package/dist/channels/tui/scroll/scroll-view.js +254 -0
  81. package/dist/channels/tui/status/status-line.js +76 -0
  82. package/dist/channels/tui/text.js +38 -0
  83. package/dist/channels/tui/theme.js +41 -0
  84. package/dist/channels/types.js +11 -0
  85. package/dist/channels/ui-core.js +209 -0
  86. package/dist/checkpoint/capture.js +45 -0
  87. package/dist/checkpoint/codes.js +33 -0
  88. package/dist/checkpoint/command.js +82 -0
  89. package/dist/checkpoint/gate.js +48 -0
  90. package/dist/checkpoint/index.js +20 -0
  91. package/dist/checkpoint/restore.js +172 -0
  92. package/dist/checkpoint/store.js +247 -0
  93. package/dist/checkpoint/types.js +4 -0
  94. package/dist/checkpoint/walk.js +146 -0
  95. package/dist/compaction/ccr-tools.js +112 -0
  96. package/dist/compaction/ccr.js +84 -0
  97. package/dist/compaction/codes.js +21 -0
  98. package/dist/compaction/index.js +18 -0
  99. package/dist/compaction/policy.js +200 -0
  100. package/dist/compaction/service.js +422 -0
  101. package/dist/compaction/slots.js +121 -0
  102. package/dist/compaction/types.js +10 -0
  103. package/dist/context/codes.js +40 -0
  104. package/dist/context/events.js +160 -0
  105. package/dist/context/index.js +13 -0
  106. package/dist/context/logger.js +136 -0
  107. package/dist/context/scope.js +182 -0
  108. package/dist/context/workspace.js +104 -0
  109. package/dist/contracts/agent-events.d.ts +73 -0
  110. package/dist/contracts/agent-events.js +16 -0
  111. package/dist/contracts/api.d.ts +249 -0
  112. package/dist/contracts/api.js +299 -0
  113. package/dist/contracts/approval.d.ts +37 -0
  114. package/dist/contracts/approval.js +9 -0
  115. package/dist/contracts/env-ref.d.ts +41 -0
  116. package/dist/contracts/env-ref.js +32 -0
  117. package/dist/contracts/errors.d.ts +56 -0
  118. package/dist/contracts/errors.js +266 -0
  119. package/dist/contracts/events.d.ts +70 -0
  120. package/dist/contracts/events.js +329 -0
  121. package/dist/contracts/index.d.ts +32 -0
  122. package/dist/contracts/index.js +26 -0
  123. package/dist/contracts/llm.d.ts +275 -0
  124. package/dist/contracts/llm.js +12 -0
  125. package/dist/contracts/messages.d.ts +63 -0
  126. package/dist/contracts/messages.js +65 -0
  127. package/dist/contracts/redact.d.ts +46 -0
  128. package/dist/contracts/redact.js +223 -0
  129. package/dist/contracts/tools.d.ts +197 -0
  130. package/dist/contracts/tools.js +33 -0
  131. package/dist/contracts/types.d.ts +302 -0
  132. package/dist/contracts/types.js +50 -0
  133. package/dist/contracts/ui.d.ts +122 -0
  134. package/dist/contracts/ui.js +15 -0
  135. package/dist/conversation/agent-service.js +61 -0
  136. package/dist/conversation/approval-wiring.js +82 -0
  137. package/dist/conversation/backoff.js +38 -0
  138. package/dist/conversation/codes.js +47 -0
  139. package/dist/conversation/control-tools.js +102 -0
  140. package/dist/conversation/control.js +210 -0
  141. package/dist/conversation/driver.js +922 -0
  142. package/dist/conversation/index.js +12 -0
  143. package/dist/conversation/model-visible.js +169 -0
  144. package/dist/conversation/open-tools.js +126 -0
  145. package/dist/conversation/reseed.js +132 -0
  146. package/dist/conversation/sessions.js +215 -0
  147. package/dist/conversation/todo.js +203 -0
  148. package/dist/conversation/types.js +35 -0
  149. package/dist/conversation/wiring.js +204 -0
  150. package/dist/credentials/codes.js +59 -0
  151. package/dist/credentials/commands.js +186 -0
  152. package/dist/credentials/env-ref.js +34 -0
  153. package/dist/credentials/index.js +28 -0
  154. package/dist/credentials/migration.js +18 -0
  155. package/dist/credentials/oauth.js +266 -0
  156. package/dist/credentials/refresh.js +152 -0
  157. package/dist/credentials/secrets.js +118 -0
  158. package/dist/credentials/types.js +30 -0
  159. package/dist/exec/bash.js +279 -0
  160. package/dist/exec/codes.js +37 -0
  161. package/dist/exec/env.js +99 -0
  162. package/dist/exec/environment.js +39 -0
  163. package/dist/exec/git-guard.js +623 -0
  164. package/dist/exec/index.js +24 -0
  165. package/dist/exec/registry.js +120 -0
  166. package/dist/exec/spawn.js +281 -0
  167. package/dist/exec/tail.js +77 -0
  168. package/dist/exec/types.js +5 -0
  169. package/dist/goal/codes.js +33 -0
  170. package/dist/goal/command.js +175 -0
  171. package/dist/goal/fold.js +121 -0
  172. package/dist/goal/gates.js +122 -0
  173. package/dist/goal/index.js +22 -0
  174. package/dist/goal/migration.js +48 -0
  175. package/dist/goal/service.js +501 -0
  176. package/dist/goal/todo-tool.js +174 -0
  177. package/dist/goal/types.js +1 -0
  178. package/dist/goal/update-tool.js +46 -0
  179. package/dist/host/approval-cmd.js +276 -0
  180. package/dist/host/assembly.js +1146 -0
  181. package/dist/host/boot-failures.js +104 -0
  182. package/dist/host/budget-advisory.js +74 -0
  183. package/dist/host/budget-broadcast.js +50 -0
  184. package/dist/host/builtins.js +54 -0
  185. package/dist/host/cli.js +544 -0
  186. package/dist/host/codes.js +120 -0
  187. package/dist/host/config-schema.js +195 -0
  188. package/dist/host/conversation-stack.js +654 -0
  189. package/dist/host/core-plugins.js +1685 -0
  190. package/dist/host/credentials-cmd.js +42 -0
  191. package/dist/host/disclosure.js +30 -0
  192. package/dist/host/dispatch.js +105 -0
  193. package/dist/host/doors-cmd.js +154 -0
  194. package/dist/host/dump-config.js +44 -0
  195. package/dist/host/hook-dispatch-guard.js +27 -0
  196. package/dist/host/import-gate.js +153 -0
  197. package/dist/host/index.js +54 -0
  198. package/dist/host/issue-session.js +241 -0
  199. package/dist/host/loader.js +372 -0
  200. package/dist/host/main.js +161 -0
  201. package/dist/host/manifest.js +381 -0
  202. package/dist/host/mcp-entry.js +53 -0
  203. package/dist/host/plugin-boot.js +952 -0
  204. package/dist/host/plugin-context.js +672 -0
  205. package/dist/host/plugin-install.js +480 -0
  206. package/dist/host/plugin-reload.js +124 -0
  207. package/dist/host/plugin-store.js +462 -0
  208. package/dist/host/plugin-tools.js +359 -0
  209. package/dist/host/plugin-uninstall.js +257 -0
  210. package/dist/host/plugins-cmd.js +302 -0
  211. package/dist/host/plugins-command.js +130 -0
  212. package/dist/host/plugins-config.js +195 -0
  213. package/dist/host/prompt-sections.js +133 -0
  214. package/dist/host/run-entry.js +544 -0
  215. package/dist/host/runtime.js +209 -0
  216. package/dist/host/scheduler-tick.js +294 -0
  217. package/dist/host/serve-daemon.js +501 -0
  218. package/dist/host/serve-entry.js +279 -0
  219. package/dist/host/session-anchor.js +41 -0
  220. package/dist/host/sessions-cmd.js +219 -0
  221. package/dist/host/sessions-face.js +47 -0
  222. package/dist/host/settings-store.js +112 -0
  223. package/dist/host/signals.js +69 -0
  224. package/dist/host/single-instance.js +105 -0
  225. package/dist/host/subagent-factory.js +291 -0
  226. package/dist/host/testkit/harness.js +283 -0
  227. package/dist/host/testkit/index.js +14 -0
  228. package/dist/host/testkit/matrix.js +302 -0
  229. package/dist/host/tool-policy-store.js +177 -0
  230. package/dist/host/triggers.js +212 -0
  231. package/dist/host/tui-entry.js +216 -0
  232. package/dist/host/webui-bridge.js +165 -0
  233. package/dist/issue/codes.js +38 -0
  234. package/dist/issue/filter.js +146 -0
  235. package/dist/issue/github.js +116 -0
  236. package/dist/issue/index.js +17 -0
  237. package/dist/issue/mount.js +70 -0
  238. package/dist/issue/poll.js +58 -0
  239. package/dist/issue/service.js +341 -0
  240. package/dist/issue/tools.js +70 -0
  241. package/dist/issue/types.js +34 -0
  242. package/dist/issue/webhook.js +126 -0
  243. package/dist/llm/codes.js +77 -0
  244. package/dist/llm/complete.js +196 -0
  245. package/dist/llm/events.js +15 -0
  246. package/dist/llm/index.js +24 -0
  247. package/dist/llm/inflight.js +65 -0
  248. package/dist/llm/model-id.js +58 -0
  249. package/dist/llm/provider-face.d.ts +32 -0
  250. package/dist/llm/provider-face.js +34 -0
  251. package/dist/llm/recovery.js +146 -0
  252. package/dist/llm/runtime.js +46 -0
  253. package/dist/llm/stream-fn.js +147 -0
  254. package/dist/lsp/codes.js +31 -0
  255. package/dist/lsp/connection.js +147 -0
  256. package/dist/lsp/frame.js +110 -0
  257. package/dist/lsp/index.js +16 -0
  258. package/dist/lsp/inject.js +58 -0
  259. package/dist/lsp/instance.js +264 -0
  260. package/dist/lsp/service.js +522 -0
  261. package/dist/lsp/tools.js +53 -0
  262. package/dist/lsp/types.js +201 -0
  263. package/dist/mcp/bridge.js +222 -0
  264. package/dist/mcp/codes.js +21 -0
  265. package/dist/mcp/index.js +19 -0
  266. package/dist/mcp/jsonrpc.js +230 -0
  267. package/dist/mcp/service.js +125 -0
  268. package/dist/mcp/tools.js +145 -0
  269. package/dist/mcp/types.js +108 -0
  270. package/dist/memory/cite.js +131 -0
  271. package/dist/memory/codes.js +50 -0
  272. package/dist/memory/command.js +71 -0
  273. package/dist/memory/consolidate.js +219 -0
  274. package/dist/memory/cycle.js +109 -0
  275. package/dist/memory/dao.js +878 -0
  276. package/dist/memory/diff.js +238 -0
  277. package/dist/memory/extract.js +181 -0
  278. package/dist/memory/fts.js +58 -0
  279. package/dist/memory/index.js +42 -0
  280. package/dist/memory/inject.js +354 -0
  281. package/dist/memory/merge.js +178 -0
  282. package/dist/memory/migration.js +132 -0
  283. package/dist/memory/pollution.js +59 -0
  284. package/dist/memory/port.js +385 -0
  285. package/dist/memory/review.js +201 -0
  286. package/dist/memory/scan.js +89 -0
  287. package/dist/memory/tools.js +508 -0
  288. package/dist/memory/types.js +140 -0
  289. package/dist/obs/codes.js +38 -0
  290. package/dist/obs/db.js +115 -0
  291. package/dist/obs/index.js +20 -0
  292. package/dist/obs/rollup.js +61 -0
  293. package/dist/obs/service.js +363 -0
  294. package/dist/obs/session-tools.js +282 -0
  295. package/dist/obs/session-view.js +225 -0
  296. package/dist/obs/tool.js +97 -0
  297. package/dist/obs/types.js +1 -0
  298. package/dist/persist/audit.js +63 -0
  299. package/dist/persist/aux.js +39 -0
  300. package/dist/persist/codes.js +35 -0
  301. package/dist/persist/index.js +30 -0
  302. package/dist/persist/load-history.js +50 -0
  303. package/dist/persist/migrations.js +37 -0
  304. package/dist/persist/paths.js +108 -0
  305. package/dist/persist/persistence.js +229 -0
  306. package/dist/persist/schema.js +99 -0
  307. package/dist/persist/secret-box.js +95 -0
  308. package/dist/persist/store.js +706 -0
  309. package/dist/persist/write-behind.js +238 -0
  310. package/dist/safety/approval.js +171 -0
  311. package/dist/safety/bwrap.js +123 -0
  312. package/dist/safety/codes.js +57 -0
  313. package/dist/safety/danger.js +505 -0
  314. package/dist/safety/gate.js +226 -0
  315. package/dist/safety/index.js +24 -0
  316. package/dist/safety/presets.js +73 -0
  317. package/dist/safety/roots.js +139 -0
  318. package/dist/safety/sandbox.js +214 -0
  319. package/dist/safety/seatbelt.js +88 -0
  320. package/dist/safety/sensitive.js +34 -0
  321. package/dist/safety/tool-policy.js +203 -0
  322. package/dist/safety/types.js +13 -0
  323. package/dist/scheduler/codes.js +54 -0
  324. package/dist/scheduler/cron-backend.js +135 -0
  325. package/dist/scheduler/engine.js +280 -0
  326. package/dist/scheduler/gates.js +60 -0
  327. package/dist/scheduler/index.js +25 -0
  328. package/dist/scheduler/migration.js +22 -0
  329. package/dist/scheduler/runner.js +171 -0
  330. package/dist/scheduler/schedule.js +193 -0
  331. package/dist/scheduler/service.js +283 -0
  332. package/dist/scheduler/tick.js +139 -0
  333. package/dist/scheduler/types.js +1 -0
  334. package/dist/sdk/http.js +865 -0
  335. package/dist/sdk/index.js +22 -0
  336. package/dist/sdk/mcp.js +289 -0
  337. package/dist/sdk/plugin-route-registry.js +126 -0
  338. package/dist/sdk/plugin-routes.js +149 -0
  339. package/dist/sdk/security.js +116 -0
  340. package/dist/sdk/types.js +32 -0
  341. package/dist/session/budget.js +159 -0
  342. package/dist/session/codes.js +40 -0
  343. package/dist/session/derive.js +180 -0
  344. package/dist/session/event-data.js +1 -0
  345. package/dist/session/fork.js +72 -0
  346. package/dist/session/import-gates.js +148 -0
  347. package/dist/session/index.js +18 -0
  348. package/dist/session/recover.js +103 -0
  349. package/dist/session/session.js +279 -0
  350. package/dist/session/snapshot.js +107 -0
  351. package/dist/skills/agents.js +242 -0
  352. package/dist/skills/codes.js +51 -0
  353. package/dist/skills/discovery.js +266 -0
  354. package/dist/skills/frontmatter.js +215 -0
  355. package/dist/skills/index.js +28 -0
  356. package/dist/skills/load.js +118 -0
  357. package/dist/skills/manage.js +201 -0
  358. package/dist/skills/registry.js +138 -0
  359. package/dist/skills/render.js +124 -0
  360. package/dist/skills/sections.js +171 -0
  361. package/dist/skills/types.js +21 -0
  362. package/dist/subagent/codes.js +50 -0
  363. package/dist/subagent/declarative.js +55 -0
  364. package/dist/subagent/index.js +19 -0
  365. package/dist/subagent/notify.js +51 -0
  366. package/dist/subagent/provide.js +7 -0
  367. package/dist/subagent/registry.js +149 -0
  368. package/dist/subagent/service.js +338 -0
  369. package/dist/subagent/surface.js +44 -0
  370. package/dist/subagent/tool.js +153 -0
  371. package/dist/subagent/types.js +25 -0
  372. package/dist/tools/apply-patch.js +164 -0
  373. package/dist/tools/codes.js +109 -0
  374. package/dist/tools/fs.js +501 -0
  375. package/dist/tools/index.js +17 -0
  376. package/dist/tools/observed.js +99 -0
  377. package/dist/tools/pipeline.js +176 -0
  378. package/dist/tools/protected-read.js +54 -0
  379. package/dist/tools/registry.js +250 -0
  380. package/dist/tools/search.js +451 -0
  381. package/dist/tools/worktree.js +327 -0
  382. package/dist/web/codes.js +37 -0
  383. package/dist/web/gate.js +43 -0
  384. package/dist/web/hygiene.js +195 -0
  385. package/dist/web/index.js +16 -0
  386. package/dist/web/service.js +207 -0
  387. package/dist/web/ssrf-guard.js +44 -0
  388. package/dist/web/tool.js +76 -0
  389. package/dist/web/types.js +10 -0
  390. package/dist/webui/assets/index-B-t2O8gh.js +22 -0
  391. package/dist/webui/assets/index-DOlgSZ9Q.css +2 -0
  392. package/dist/webui/index.html +14 -0
  393. package/dist/webui/index.js +14 -0
  394. package/dist/webui/server.js +549 -0
  395. package/dist/webui/types.js +38 -0
  396. package/examples/README.md +26 -0
  397. package/examples/minimal-code-plugin/entry.js +43 -0
  398. package/examples/minimal-code-plugin/package.json +12 -0
  399. package/examples/pure-skill-pack/package.json +14 -0
  400. package/examples/pure-skill-pack/skills/markdown-table/SKILL.md +32 -0
  401. package/package.json +86 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * L0 contracts — LLM 边界消息基础件(04 篇 §3 StreamFn 契约 + §5 模型层)。
3
+ *
4
+ * 承 berry 同款关键决策:agent loop 不 import llm(02 篇 §4.2 关键不依赖第
5
+ * 一条),StreamFn 签名与消息形状收进 contracts——pi-ai 产生的消息值可原样
6
+ * 赋给这里的类型(标准三角色零转换直通)。
7
+ *
8
+ * 兼容策略:字段取 pi-ai 0.84.4 对应接口的**超集兼容子集**——本文件要求的
9
+ * 必填字段在 pi-ai 中全部存在且同名同型;pi-ai 独有的字段(api/responseModel/
10
+ * deferred 等)不在此收口,多出的字段对结构化赋值透明。
11
+ */
12
+ export {};
@@ -0,0 +1,63 @@
1
+ /**
2
+ * L0 contracts — 消息模型与自定义角色注册(04 篇 §2「AgentMessage 与自定义角色」)。
3
+ *
4
+ * 消息模型 = 标准三角色(llm.ts Message)∪ 自定义角色(CustomMessage)。自定义
5
+ * 角色经 registerMessageRole 注册(render/toLlm 双写映射 + hidden 位),域名前缀
6
+ * 两段式强制(`memory/recall` 式——与 03 篇 §2.7 prompt slot 同构的域名纪律)。
7
+ * 宿主不预注册任何自定义角色;conversation 按需注册(04 §2)。
8
+ *
9
+ * 单入口裁决(本仓 vs berry 蓝本差异①):蓝本双入口(registerAppMessageRole /
10
+ * registerHostMessageRole)不采纳——扩展单位既归一为插件,宿主件与插件同走
11
+ * registerMessageRole 单入口、同守域名前缀纪律,无宿主单段自留地。
12
+ */
13
+ import type { Message } from './llm.js';
14
+ /**
15
+ * 标准角色名闭集(convertToLlm 透传的标准半边;自定义角色撞此集任何一名即拒)。
16
+ * 与 llm.ts Message 三角色判别位一一对应。
17
+ */
18
+ export declare const STANDARD_MESSAGE_ROLES: ReadonlySet<string>;
19
+ /** 自定义角色消息(content 载荷形状由角色定义自裁——toLlm 映射的输入) */
20
+ export interface CustomMessage {
21
+ /** 自定义角色名(域名两段式) */
22
+ role: string;
23
+ /** 载荷(角色定义自裁其形状) */
24
+ content: unknown;
25
+ /** Unix 毫秒时间戳 */
26
+ timestamp: number;
27
+ }
28
+ /** 消息模型全集:标准三角色 ∪ 自定义角色(loop 与驱动侧的共同消息面) */
29
+ export type AgentMessage = Message | CustomMessage;
30
+ /** 呈现意图(render 映射的输出半边;hidden = 瞬态注入不进用户可见流) */
31
+ export interface MessageRoleRender {
32
+ /** inline = 进对话流;status = 状态行;hidden = 不可见(模型可见但用户不可见的瞬态注入) */
33
+ intent: 'inline' | 'status' | 'hidden';
34
+ /** 呈现标签(UI 折行显示用) */
35
+ label?: string;
36
+ }
37
+ /** 角色定义:toLlm 映射(进模型上下文的降写)+ render 呈现(用户可见面) */
38
+ export interface MessageRoleDefinition {
39
+ /**
40
+ * 自定义消息 → LLM 消息的转写:返回 Message(降写为标准角色)、Message[]
41
+ * (一拆多)或 null(剥离——瞬态注入本轮用毕即隐)。
42
+ */
43
+ toLlm?: (message: CustomMessage) => Message | Message[] | null;
44
+ /** 呈现映射(缺省无 render = 不可见) */
45
+ render?: MessageRoleRender;
46
+ }
47
+ /**
48
+ * 注册自定义消息角色(ctx.agent.registerMessageRole 的本体——单入口)。
49
+ *
50
+ * 拒绝式两码(03 篇 §2.7 消息面行):撞标准角色名或在册角色 → AGENT_ROLE_EXISTS;
51
+ * 域名前缀两段式违例 → AGENT_ROLE_INVALID。注册失败零记账(无半注册残留)。
52
+ *
53
+ * @param role 角色名(域名两段式,如 `memory/recall`)
54
+ * @param definition 角色定义(toLlm/render 双写映射)
55
+ * @returns disposer——仅当注册表内仍是**本定义**时移除(防误摘后来同名胜出者)
56
+ */
57
+ export declare function registerMessageRole(role: string, definition: MessageRoleDefinition): () => void;
58
+ /** 查询角色定义(标准角色与未注册角色返回 undefined) */
59
+ export declare function getMessageRoleDefinition(role: string): MessageRoleDefinition | undefined;
60
+ /** 在册自定义角色名枚举(诊断/目录面) */
61
+ export declare function listMessageRoleNames(): string[];
62
+ /** 标准消息窄化守卫(正向判窄化——自定义消息判别用 !isStandardMessage) */
63
+ export declare function isStandardMessage(message: AgentMessage): message is Message;
@@ -0,0 +1,65 @@
1
+ /**
2
+ * L0 contracts — 消息模型与自定义角色注册(04 篇 §2「AgentMessage 与自定义角色」)。
3
+ *
4
+ * 消息模型 = 标准三角色(llm.ts Message)∪ 自定义角色(CustomMessage)。自定义
5
+ * 角色经 registerMessageRole 注册(render/toLlm 双写映射 + hidden 位),域名前缀
6
+ * 两段式强制(`memory/recall` 式——与 03 篇 §2.7 prompt slot 同构的域名纪律)。
7
+ * 宿主不预注册任何自定义角色;conversation 按需注册(04 §2)。
8
+ *
9
+ * 单入口裁决(本仓 vs berry 蓝本差异①):蓝本双入口(registerAppMessageRole /
10
+ * registerHostMessageRole)不采纳——扩展单位既归一为插件,宿主件与插件同走
11
+ * registerMessageRole 单入口、同守域名前缀纪律,无宿主单段自留地。
12
+ */
13
+ import { BaseError } from './errors.js';
14
+ /**
15
+ * 标准角色名闭集(convertToLlm 透传的标准半边;自定义角色撞此集任何一名即拒)。
16
+ * 与 llm.ts Message 三角色判别位一一对应。
17
+ */
18
+ export const STANDARD_MESSAGE_ROLES = new Set(['user', 'assistant', 'toolResult']);
19
+ /**
20
+ * 自定义域名前缀两段式判据(03 篇 §2.7 消息面行):恰含一个 `/`、两段均
21
+ * 小写字母数字连字符且段首为字母(`memory/recall` 合法;`Memory/recall`、
22
+ * `memory`、`a/b/c` 均非法)。
23
+ */
24
+ const CUSTOM_ROLE_RE = /^[a-z][a-z0-9-]*\/[a-z][a-z0-9-]*$/;
25
+ /** 角色注册表本体(role → 定义;进程级单表,宿主件与插件共用) */
26
+ const roleRegistry = new Map();
27
+ /**
28
+ * 注册自定义消息角色(ctx.agent.registerMessageRole 的本体——单入口)。
29
+ *
30
+ * 拒绝式两码(03 篇 §2.7 消息面行):撞标准角色名或在册角色 → AGENT_ROLE_EXISTS;
31
+ * 域名前缀两段式违例 → AGENT_ROLE_INVALID。注册失败零记账(无半注册残留)。
32
+ *
33
+ * @param role 角色名(域名两段式,如 `memory/recall`)
34
+ * @param definition 角色定义(toLlm/render 双写映射)
35
+ * @returns disposer——仅当注册表内仍是**本定义**时移除(防误摘后来同名胜出者)
36
+ */
37
+ export function registerMessageRole(role, definition) {
38
+ // 撞名检查前置于格式检查:标准角色名(user 等单段)先撞此闸——「名字已被
39
+ // 占用」比「格式违例」更指向根因(03 §2.7:撞标准角色或在册角色均 AGENT_ROLE_EXISTS)
40
+ if (STANDARD_MESSAGE_ROLES.has(role) || roleRegistry.has(role)) {
41
+ throw new BaseError('AGENT_ROLE_EXISTS', `消息角色 ${role} 已在册(标准角色或在册自定义角色),重影即消息转写分叉`);
42
+ }
43
+ if (!CUSTOM_ROLE_RE.test(role)) {
44
+ throw new BaseError('AGENT_ROLE_INVALID', `角色名 ${JSON.stringify(role)} 违域名前缀两段式纪律(恰含一个 /、两段均小写字母数字连字符,如 memory/recall)`);
45
+ }
46
+ roleRegistry.set(role, definition);
47
+ return () => {
48
+ // 仅当仍是本定义时移除——后来者不可能同名胜出(拒绝式),此守卫防的是
49
+ // disposer 持有过期时序下的误摘(先 dispose 后重注册再 dispose 的序列)
50
+ if (roleRegistry.get(role) === definition)
51
+ roleRegistry.delete(role);
52
+ };
53
+ }
54
+ /** 查询角色定义(标准角色与未注册角色返回 undefined) */
55
+ export function getMessageRoleDefinition(role) {
56
+ return roleRegistry.get(role);
57
+ }
58
+ /** 在册自定义角色名枚举(诊断/目录面) */
59
+ export function listMessageRoleNames() {
60
+ return [...roleRegistry.keys()];
61
+ }
62
+ /** 标准消息窄化守卫(正向判窄化——自定义消息判别用 !isStandardMessage) */
63
+ export function isStandardMessage(message) {
64
+ return STANDARD_MESSAGE_ROLES.has(message.role);
65
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * 出口治理③ 凭据消毒(04 §7 执行段 2026-09-08 落码定形——出口层 redaction
3
+ * 纯函数单源;c-4 泄漏面净化④「server 工具结果回显 env 值」的收口批)。
4
+ *
5
+ * 词汇面与词面单源纪律(env-ref.ts 同先例):放 contracts 使两消费方零新
6
+ * DAG 边——tools 管道链尾(模式 + 值基两腿)与 agent 错误包装位(纯模式
7
+ * 腿——错误即结果 ⑤ 与正常结果同一出口语义)。纯函数零依赖零状态,jiti
8
+ * 可载。
9
+ *
10
+ * 两腿:
11
+ * - **模式腿**(`redactSensitiveText`):闭集正则三段——URL userinfo 剥离 /
12
+ * URL query 敏感参数值剥离 / 敏感键名值脱敏(赋值形覆盖裸 =、:、JSON
13
+ * 引号形与 Authorization 头整行特例)。无外部数据依赖、恒在场。
14
+ * - **值基腿**(`redactKnownSecretValues` + `redactToolResultExit`):装配
15
+ * 注入 credentials 库活值 provider——具名形态外的裸值回显收口;provider
16
+ * 缺席 = 纯模式执法(降级诚实)。
17
+ *
18
+ * 非静默原则(截断注记同律):消毒以 `[REDACTED:<reason>]` 注记进上下文
19
+ * ——模型可见有物被消,非凭空篡改。幂等:注记自身不构成再触发形(回调内
20
+ * 显式判已注记即跳过)。
21
+ */
22
+ import type { AgentToolResult } from './tools.js';
23
+ /**
24
+ * 模式腿:出口文本消毒(04 §7 出口治理③模式集三段——纯函数、幂等、恒在场)。
25
+ *
26
+ * 覆盖面(闭集、大小写不敏感):URL userinfo / URL query 敏感参数值 /
27
+ * 敏感键名赋值值(含 Authorization 头整行特例)。通用赋值形值长 < 4 跳过
28
+ * (散文冒号误伤面控制——"the token: is" 不触发;URL 两段上下文无歧义不设此阈)。
29
+ */
30
+ export declare function redactSensitiveText(text: string): string;
31
+ /**
32
+ * 值基腿:已知秘密活值整段置换(split/join 字面替换——值含正则元字符安全)。
33
+ *
34
+ * 长值先换(前缀包含关系下短值先换会破坏长值锚);长度 < 8 不参与(短值
35
+ * 误伤普通文本的灾难面控制——04 §7 定形⑤)。provider 给值已是明文(装配
36
+ * 侧 credentials 库 live 读——本函数恒不取库,纯数据进出)。
37
+ */
38
+ export declare function redactKnownSecretValues(text: string, values: readonly string[]): string;
39
+ /**
40
+ * 工具结果出口消毒(管道链尾调用——04 §7 定形①:护栏之前一步)。
41
+ *
42
+ * 就地改写:文本 content 逐块消毒(图片等自有界块原样保留——与输出护栏
43
+ * 同判据);details 深走字符串叶消毒(结构化明细同是 server 回显面)。
44
+ * 纯模式 + 值基两腿合流;provider 调用方恒传数组(装配闭包 live 读)。
45
+ */
46
+ export declare function redactToolResultExit(result: AgentToolResult, sensitiveValues: readonly string[]): void;
@@ -0,0 +1,223 @@
1
+ /**
2
+ * 出口治理③ 凭据消毒(04 §7 执行段 2026-09-08 落码定形——出口层 redaction
3
+ * 纯函数单源;c-4 泄漏面净化④「server 工具结果回显 env 值」的收口批)。
4
+ *
5
+ * 词汇面与词面单源纪律(env-ref.ts 同先例):放 contracts 使两消费方零新
6
+ * DAG 边——tools 管道链尾(模式 + 值基两腿)与 agent 错误包装位(纯模式
7
+ * 腿——错误即结果 ⑤ 与正常结果同一出口语义)。纯函数零依赖零状态,jiti
8
+ * 可载。
9
+ *
10
+ * 两腿:
11
+ * - **模式腿**(`redactSensitiveText`):闭集正则三段——URL userinfo 剥离 /
12
+ * URL query 敏感参数值剥离 / 敏感键名值脱敏(赋值形覆盖裸 =、:、JSON
13
+ * 引号形与 Authorization 头整行特例)。无外部数据依赖、恒在场。
14
+ * - **值基腿**(`redactKnownSecretValues` + `redactToolResultExit`):装配
15
+ * 注入 credentials 库活值 provider——具名形态外的裸值回显收口;provider
16
+ * 缺席 = 纯模式执法(降级诚实)。
17
+ *
18
+ * 非静默原则(截断注记同律):消毒以 `[REDACTED:<reason>]` 注记进上下文
19
+ * ——模型可见有物被消,非凭空篡改。幂等:注记自身不构成再触发形(回调内
20
+ * 显式判已注记即跳过)。
21
+ */
22
+ /** 消毒注记前缀(形如 `[REDACTED:<reason>]`——幂等判定的锚) */
23
+ const MARK = '[REDACTED:';
24
+ /** URL query 敏感参数名闭集(小写单源;匹配大小写不敏感) */
25
+ const QUERY_TOKEN_PARAMS = [
26
+ 'access_token',
27
+ 'refresh_token',
28
+ 'id_token',
29
+ 'client_secret',
30
+ 'api_key',
31
+ 'apikey',
32
+ 'token',
33
+ 'secret',
34
+ 'password',
35
+ 'passwd',
36
+ 'signature',
37
+ 'sig',
38
+ 'key',
39
+ ];
40
+ /** 敏感键名分段闭集(键名按 -_. 分段、**末段**命中即敏感;小写单源) */
41
+ const SENSITIVE_NAME_SEGMENTS = new Set([
42
+ 'token',
43
+ 'tokens',
44
+ 'secret',
45
+ 'secrets',
46
+ 'password',
47
+ 'passwords',
48
+ 'passwd',
49
+ 'pass',
50
+ 'pwd',
51
+ 'apikey',
52
+ 'key',
53
+ 'keys',
54
+ 'credential',
55
+ 'credentials',
56
+ 'signature',
57
+ 'auth',
58
+ 'authorization',
59
+ 'bearer',
60
+ ]);
61
+ /** 正则元字符转义(闭集参数名拼接进 alternation 前的安全化) */
62
+ function escapeRe(s) {
63
+ return s.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
64
+ }
65
+ /** 值是否已是消毒注记(幂等跳过锚) */
66
+ function isMarked(value) {
67
+ return value.startsWith(MARK);
68
+ }
69
+ /**
70
+ * 键名是否敏感(**末段**判据——GITHUB_TOKEN / aws_secret_access_key / api-key
71
+ * 同判;末段判控制误伤面:token_type / token_url / secret_name 之类「敏感词
72
+ * 作前缀修饰、末段为中性词」的公开字段不触发)。
73
+ */
74
+ function isSensitiveName(name) {
75
+ const segments = name
76
+ .toLowerCase()
77
+ .split(/[-_.]+/)
78
+ .filter((seg) => seg.length > 0);
79
+ const last = segments[segments.length - 1];
80
+ return last !== undefined && SENSITIVE_NAME_SEGMENTS.has(last);
81
+ }
82
+ /**
83
+ * URL query 敏感参数值剥离正则(`?token=…` / `&api_key=…`——参数名精确段
84
+ * 匹配:`[?&]` 前锚 + `=` 后锚,`token_type` 之类前缀词不误伤)。
85
+ */
86
+ const QUERY_TOKEN_RE = new RegExp(`([?&])(${QUERY_TOKEN_PARAMS.map(escapeRe).join('|')})(=)([^&\\s#'"]*)`, 'gi');
87
+ /**
88
+ * URL userinfo 剥离正则(`scheme://user:pass@`——冒号对形才命中,裸用户名
89
+ * 形不触发)。值两段排除 `[`:消毒注记形 `[REDACTED:...]` 不被当 user:pass
90
+ * 二次剥离(幂等锚的一环)。
91
+ */
92
+ const URL_USERINFO_RE = /([a-zA-Z][a-zA-Z0-9+.-]*:\/\/)([^\s"'<>@/[]+):([^\s"'<>@/[]+)@/g;
93
+ /** Authorization 头整行特例(值含空格——`Bearer xyz` 裸赋值形只截到首词,特例整行收口) */
94
+ const AUTHORIZATION_RE = /\b(proxy-authorization|authorization)(\s*[=:]\s*)([^\r\n]+)/gi;
95
+ /**
96
+ * 通用赋值形正则:名字(裸词 / 引号词)+ 分隔(= 或 :)+ 值(引号串或裸串)。
97
+ * 敏感性与否经回调判名(分段闭集)——正则只负责形,语义在回调。
98
+ */
99
+ const ASSIGNMENT_RE = /("[A-Za-z][A-Za-z0-9_.-]*"|[A-Za-z][A-Za-z0-9_.-]*)(\s*[=:]\s*)("[^"\n]*"|'[^'\n]*'|[^\s,;"'`&\]}]+)/g;
100
+ /** 键名提取(剥引号——JSON 形 `"api_key"` 与裸形 `api_key` 同判) */
101
+ function bareName(raw) {
102
+ return raw.startsWith('"') || raw.startsWith("'") ? raw.slice(1, -1) : raw;
103
+ }
104
+ /** 值替换形(保引号——JSON 形消毒产物仍是合法引号串) */
105
+ function markedValue(raw) {
106
+ if (raw.startsWith('"'))
107
+ return '"[REDACTED:secret]"';
108
+ if (raw.startsWith("'"))
109
+ return "'[REDACTED:secret]'";
110
+ return '[REDACTED:secret]';
111
+ }
112
+ /**
113
+ * 模式腿:出口文本消毒(04 §7 出口治理③模式集三段——纯函数、幂等、恒在场)。
114
+ *
115
+ * 覆盖面(闭集、大小写不敏感):URL userinfo / URL query 敏感参数值 /
116
+ * 敏感键名赋值值(含 Authorization 头整行特例)。通用赋值形值长 < 4 跳过
117
+ * (散文冒号误伤面控制——"the token: is" 不触发;URL 两段上下文无歧义不设此阈)。
118
+ */
119
+ export function redactSensitiveText(text) {
120
+ // 段序:userinfo → query → Authorization → 通用赋值(特例先于通例——
121
+ // Authorization 整行形若先被通例截短即漏尾词)
122
+ let out = text.replace(URL_USERINFO_RE, '$1[REDACTED:url-userinfo]@');
123
+ out = out.replace(QUERY_TOKEN_RE, (full, q, name, eq, value) => isMarked(value) ? full : `${q}${name}${eq}[REDACTED:query-token]`);
124
+ out = out.replace(AUTHORIZATION_RE, (full, name, sep, value) => isMarked(value.trimStart()) ? full : `${name}${sep}[REDACTED:credential]`);
125
+ return redactAssignments(out);
126
+ }
127
+ /**
128
+ * 通用赋值形消毒(redactSensitiveText 第四段本体——独立函数供值内递归)。
129
+ * 非敏感名命中不吞段:裸值字符类允许 = 与全/半角冒号,形如
130
+ * `Error: 命令失败:GITHUB_TOKEN=x` 的前缀对会把后续敏感对并进自己的值区
131
+ * (正则消费区不再访)——值内递归再扫收口。递归操作于严格更短子串,深度
132
+ * 有界。
133
+ */
134
+ function redactAssignments(text) {
135
+ return text.replace(ASSIGNMENT_RE, (full, rawName, sep, rawValue) => {
136
+ if (isMarked(rawValue))
137
+ return full;
138
+ if (!isSensitiveName(bareName(rawName))) {
139
+ return `${rawName}${sep}${redactAssignments(rawValue)}`;
140
+ }
141
+ // 裸值过短跳过(散文误伤阈——引号值不设阈:引号形即结构化语境)
142
+ if (!/["']/.test(rawValue[0] ?? '') && rawValue.length < 4)
143
+ return full;
144
+ return `${rawName}${sep}${markedValue(rawValue)}`;
145
+ });
146
+ }
147
+ /**
148
+ * 值基腿:已知秘密活值整段置换(split/join 字面替换——值含正则元字符安全)。
149
+ *
150
+ * 长值先换(前缀包含关系下短值先换会破坏长值锚);长度 < 8 不参与(短值
151
+ * 误伤普通文本的灾难面控制——04 §7 定形⑤)。provider 给值已是明文(装配
152
+ * 侧 credentials 库 live 读——本函数恒不取库,纯数据进出)。
153
+ */
154
+ export function redactKnownSecretValues(text, values) {
155
+ const eligible = values.filter((v) => typeof v === 'string' && v.length >= 8 && !v.includes(MARK));
156
+ const ordered = [...new Set(eligible)].sort((a, b) => b.length - a.length);
157
+ let out = text;
158
+ for (const value of ordered) {
159
+ if (!out.includes(value))
160
+ continue;
161
+ out = out.split(value).join('[REDACTED:credential]');
162
+ }
163
+ return out;
164
+ }
165
+ /** 两腿合流(值基先行——名形留下具名注记,模式腿补裸形) */
166
+ function redactAll(text, values) {
167
+ return redactSensitiveText(redactKnownSecretValues(text, values));
168
+ }
169
+ /** details 深走上限(防御深度——病态深构不递归失控) */
170
+ const DETAILS_DEPTH_CAP = 8;
171
+ /** details 字符串叶消毒(结构保形——只改字符串叶,数与布尔不动) */
172
+ function redactDetails(node, values, depth, seen) {
173
+ if (depth > DETAILS_DEPTH_CAP)
174
+ return;
175
+ if (typeof node === 'string')
176
+ return; // 字符串非对象——叶替换在调用处(readonly 容器内就地不可行,见下)
177
+ if (node === null || typeof node !== 'object')
178
+ return;
179
+ if (seen.has(node))
180
+ return; // 环防御(details 是工具产物,理论纯 JSON——防御位)
181
+ seen.add(node);
182
+ if (Array.isArray(node)) {
183
+ for (let i = 0; i < node.length; i++) {
184
+ const item = node[i];
185
+ if (typeof item === 'string')
186
+ node[i] = redactAll(item, values);
187
+ else
188
+ redactDetails(item, values, depth + 1, seen);
189
+ }
190
+ return;
191
+ }
192
+ const record = node;
193
+ for (const key of Object.keys(record)) {
194
+ const value = record[key];
195
+ if (typeof value === 'string') {
196
+ // 对象键名敏感即整值脱敏(c-4 ④ 本体形态:结构化明细里敏感键携裸值——
197
+ // 字符串叶内无键名形可匹配,模式正则够不着;键名即结构化语境的赋值形,
198
+ // JSON 引号形的内存对偶,同律不设值阈)
199
+ record[key] = isSensitiveName(key) ? '[REDACTED:secret]' : redactAll(value, values);
200
+ }
201
+ else if (value !== null && typeof value === 'object')
202
+ redactDetails(value, values, depth + 1, seen);
203
+ }
204
+ }
205
+ /**
206
+ * 工具结果出口消毒(管道链尾调用——04 §7 定形①:护栏之前一步)。
207
+ *
208
+ * 就地改写:文本 content 逐块消毒(图片等自有界块原样保留——与输出护栏
209
+ * 同判据);details 深走字符串叶消毒(结构化明细同是 server 回显面)。
210
+ * 纯模式 + 值基两腿合流;provider 调用方恒传数组(装配闭包 live 读)。
211
+ */
212
+ export function redactToolResultExit(result, sensitiveValues) {
213
+ if (Array.isArray(result.content)) {
214
+ for (const block of result.content) {
215
+ if (block !== null && typeof block === 'object' && block.type === 'text' && typeof block.text === 'string') {
216
+ block.text = redactAll(block.text, sensitiveValues);
217
+ }
218
+ }
219
+ }
220
+ if (result.details !== undefined && result.details !== null && typeof result.details === 'object') {
221
+ redactDetails(result.details, sensitiveValues, 0, new Set());
222
+ }
223
+ }
@@ -0,0 +1,197 @@
1
+ /**
2
+ * L0 contracts — AgentTool 工具族类型(agent 件三段管道的执行体契约)。
3
+ *
4
+ * 裁决(本仓 vs berry 蓝本差异②):蓝本 AgentTool 族先落 agent 件后迁
5
+ * contracts——本仓一步到位直上 contracts(插件 defineTool 的参数类型消费面,
6
+ * 避免落码即迁的双写窗口)。工具面三段管道(schema→守门→执行)本体在
7
+ * tools 件(后续批);本件只钉**执行体形状**——loop 工具批的直接消费面。
8
+ */
9
+ import type { ImageContent, TextContent, ToolCallBlock, Usage } from './llm.js';
10
+ /** 工具执行结果(终值——错误也走 isError 数据面不走异常面) */
11
+ export interface AgentToolResult {
12
+ /** 结果内容(与 ToolResultMessage.content 同形;空结果传空数组) */
13
+ content: (TextContent | ImageContent)[];
14
+ /** 供日志/UI 的结构化明细(不进主上下文计费) */
15
+ details?: unknown;
16
+ /** 错误标记(错误是数据契约之一:isError=true 的结果照常进上下文配对) */
17
+ isError?: boolean;
18
+ /** 工具执行自身的用量(若可得上报) */
19
+ usage?: Usage;
20
+ /** 本次结果后新可用的工具名(延迟装载透传) */
21
+ addedToolNames?: string[];
22
+ /** 终止旗标:批内全 terminate 才 terminate(批内一致裁决——单件否决不放大) */
23
+ terminate?: boolean;
24
+ }
25
+ /** 工具执行进度回调(tool_execution_update 事件的载荷源;promise 结算后的迟到进度被丢弃) */
26
+ export type ToolUpdateCallback = (update: unknown) => void;
27
+ /**
28
+ * 工具执行体(loop 工具批消费的最小形状——完整 defineTool 形在 tools 件)。
29
+ * execute 契约:一切失败编码为 isError 结果(数据面),同步抛错由执行器
30
+ * 包装兜底(tools-batch——loop 骨架零 try/catch 的配套执法位)。
31
+ */
32
+ export interface AgentTool {
33
+ /** 工具名(模型可见清单词法面) */
34
+ name: string;
35
+ /** 工具描述(模型可见) */
36
+ description: string;
37
+ /** UI 呈现标签(缺省用 name) */
38
+ label?: string;
39
+ /** JSON Schema 参数描述(typebox 产物或等价 JSON Schema 对象) */
40
+ parameters: object;
41
+ /**
42
+ * 效果面(03 §2.3 一位两用——批调度与审批共此单键,不另设同义键):
43
+ * ① 调度语义(tools-batch 批消费序执法——04 §2 尾句):read(含缺省)批内
44
+ * 可并行调度、write 批边界串行(写前清空在飞只读);
45
+ * ② 审批语义:write 触发审批对(守门段校验,审批编舞归 safety 件)。
46
+ */
47
+ effect?: ToolEffect;
48
+ /** 参数预处理钩子(执行前最后一改参数的机会;返回改后参数) */
49
+ prepareArguments?: (arguments_: Record<string, unknown>) => Record<string, unknown> | Promise<Record<string, unknown>>;
50
+ /**
51
+ * 执行体:@param toolCallId 调用 id(与 assistant 内 toolCall 配对键)
52
+ * @param arguments_ 已解析参数 @param signal 中止信号(协作面)
53
+ * @param onUpdate 进度回调(迟到进度被丢弃)
54
+ */
55
+ execute: (toolCallId: string, arguments_: Record<string, unknown>, signal?: AbortSignal, onUpdate?: ToolUpdateCallback) => Promise<AgentToolResult>;
56
+ }
57
+ /** 工具批执行输入项(assistant 内联 toolCall 块的直取形) */
58
+ export type AgentToolCall = ToolCallBlock;
59
+ /**
60
+ * 工具效果面(03 §2.3 一位两用)——**工具档三值**(04 §9 定形块①,2026-09-11
61
+ * 审批分档批):`read` = 只读(批内并行调度、不走审批对);`write` = 写面
62
+ * (批边界串行屏障 + 审批对触发);`exec` = 任意进程执行类(v1 升档清单恰
63
+ * 一处 = bash——exec/bash.ts;write/exec 同触发审批对、同走批边界串行)。
64
+ * **缺省 = exec**(未知缺省最危律——04 §9 定形块②;执法位在注册面归一
65
+ * `def.effect ?? 'exec'`,2026-09-11 缺省反转,原缺省 read 作废)。
66
+ * 审批编舞归 safety 件。
67
+ */
68
+ export type ToolEffect = 'read' | 'write' | 'exec';
69
+ /**
70
+ * 工具档偏序 rank(04 §9 定形块①:read < write < exec)。与 §8 沙箱档
71
+ * TIER_RANK(safety/approval 件内私有常量)**两轴分立**:工具档 = 该工具
72
+ * 固有风险位,沙箱档 = 本次运行许可面,互不推导。消费位:策略表条目
73
+ * `effect?` 限定的偏序包含判(safety 匹配引擎)、粘性/allow 授权不跨档
74
+ * 覆盖的比较面(04 §9 ①「write 档免问授权结构上不覆盖 exec 调用」)。
75
+ */
76
+ export declare const TOOL_TIER_RANK: Readonly<Record<ToolEffect, number>>;
77
+ /** 工具执行语境(管道构造后传给 ToolDefinition.execute 的第 2 参) */
78
+ export interface ToolContext {
79
+ /** 调用 id(与 assistant 内联 toolCall 配对键) */
80
+ toolCallId: string;
81
+ /** 中止信号(协作面——超时/取消传播) */
82
+ signal?: AbortSignal;
83
+ /** 进度回调(迟到的进度被丢弃——loop 工具批侧语义) */
84
+ onUpdate?: ToolUpdateCallback;
85
+ /** 会话语境键(驱动层工具的 per-session 状态路由键——fs 观察态等) */
86
+ sessionId?: string;
87
+ }
88
+ /**
89
+ * 注册表内工具定义(03 §2.3 defineTool 形——插件注册动词 ctx.tools.register
90
+ * 的入参形状)。与 AgentTool(loop 直消费面)的分野:本形 execute 收
91
+ * (args, toolCtx) 插件便利签名;注册表经 toAgentTool 包装成三段管道执行体。
92
+ */
93
+ export interface ToolDefinition {
94
+ /** 工具名(全局唯一;命名纪律与查重见 03 §2.7) */
95
+ name: string;
96
+ /** 模型可见描述(注册面注入模式扫描——03 §2.8) */
97
+ description: string;
98
+ /** JSON Schema 参数描述(typebox 产物或等价 JSON Schema 对象;根须 object) */
99
+ parameters: object;
100
+ /** 单次执行预算毫秒(正数;缺省走管道 60s——04 §7 执行段) */
101
+ timeoutMs?: number;
102
+ /** 效果面(一位两用——调度语义 + 审批触发;缺省 exec〔未知缺省最危律——04 §9 定形块②,2026-09-11 反转〕。03 §2.3) */
103
+ effect?: ToolEffect;
104
+ /**
105
+ * 幂等位(03 §2.3):缺省 true;false = 禁静默重试——副作用型工具重放即
106
+ * 重复执行,重试决策须回模型或上抛不静默。框架侧重放机制(04 §2 call_id
107
+ * 幂等决策)已落码(agent 件 tools-batch 消费序 limiter——回执腿不重执行,
108
+ * 2026-09-09);本位词面与其相容(重放回执既不构成「静默重试」)。
109
+ */
110
+ repeatable?: boolean;
111
+ /**
112
+ * 归因铸造位(03 §2.3 尾注——T9 案一批 R1 定形):**注册面铸造、插件不可
113
+ * 自报**——ctx.tools.register 受理壳(fork 级闭包携 pluginId)无条件覆写
114
+ * 为注册者 pluginId,defineTool 输入形状无 owner 参数位(传入自报值恒不达
115
+ * 注册表——冒名结构性不存在)。值域 = 插件 id 裸词(官方件含 core: 前缀
116
+ * 形)+ 保留位 'core:host'(不经插件注册面的宿主装配工具——open 域
117
+ * fs/bash/todo 族 + 模型面八件 plugin_* + obs/control extraTools 族;缺省
118
+ * 盖章单点在 open-tools 注册处)。消费位 = tool/call 事件载荷 owner 位
119
+ * (05 §1.1 写时带出——读侧零 join);读侧勿当件 id join 装机账本。
120
+ */
121
+ owner?: string;
122
+ /** 执行体:一切失败编码为 isError 结果(数据面);抛错由管道/loop 包装兜底 */
123
+ execute: (args: Record<string, unknown>, toolCtx: ToolContext) => Promise<AgentToolResult>;
124
+ }
125
+ /** 守门段决策词汇(03 §2.4——拦截族 handler 控制输出同一套) */
126
+ export type GateAction = {
127
+ action: 'allow';
128
+ } | {
129
+ action: 'block';
130
+ reason: string;
131
+ };
132
+ /**
133
+ * 守门段 waterfall 载荷(04 §7 段 2)。**可变入参就地改写**:链上 gateInput
134
+ * 对象对整条链固定,守门者改 gateInput.args 即改执行段所见参数(mutate 语义
135
+ * 依赖此——置 mutated 旗供 durable 落账判定)。放行 = next(input) 委托下游;
136
+ * 拦截 = 不调 next 短路、置 outcome 后返回(waterfall 短路语义即 block 语义)。
137
+ */
138
+ export interface GateInput {
139
+ /** 被调用工具(只读参考) */
140
+ tool: ToolDefinition;
141
+ /** 调用参数(可变——mutate 就地改写) */
142
+ args: Record<string, unknown>;
143
+ /** 调用 id */
144
+ toolCallId: string;
145
+ /**
146
+ * 会话键(管道签名本有——工具按会话键分派时透传进守门面;04 §7 批 15d
147
+ * 补注。消费先例 = core:checkpoint pre-mutation 捕获按会话判 per-run;
148
+ * 无会话场景〔测试/系统调用〕缺省不带)
149
+ */
150
+ sessionId?: string;
151
+ /** 中止信号(守门面构造审批 ask 载荷时携带) */
152
+ signal?: AbortSignal;
153
+ /** 参数已被改写旗(改参的守门者维护;落账 decision=mutate 的判据) */
154
+ mutated: boolean;
155
+ /**
156
+ * 放行来源标注(04 §9 命中审计条款):免问面(跨会话工具策略表)命中的
157
+ * 守门者置 `policy-allow:<条目序>`(2026-09-11 审批分档批更词——原
158
+ * `allowlist:<条目序>` 词面作废,04 §9 定形块④;值域归 04 §9 单源),
159
+ * 管道落 gate/decision 时承接进 reason 位(放行仍可审计——「谁放的行」
160
+ * 指哪条既有授权放的行);缺省 undefined = 普通放行,落账 reason 'ok'
161
+ */
162
+ allowReason?: string;
163
+ /** 拦截决策(block 者置;缺省 undefined = 放行沿链) */
164
+ outcome?: GateAction;
165
+ }
166
+ /** 执行段 waterfall 载荷(around-dispatch:T = 执行闭包,监听者包装后经 next 传播) */
167
+ export type ExecuteInput = () => Promise<AgentToolResult>;
168
+ /** 后处理段 waterfall 载荷(可就地改写 result——裁剪/spill/isError 改写) */
169
+ export interface PostExecuteInput {
170
+ /** 被调用工具(只读参考) */
171
+ tool: ToolDefinition;
172
+ /** 调用参数(守门后终参) */
173
+ args: Record<string, unknown>;
174
+ /** 调用 id */
175
+ toolCallId: string;
176
+ /** 工具结果(可变——监听者就地改写) */
177
+ result: AgentToolResult;
178
+ }
179
+ /** gate/decision durable 落账记录(05 §1.1 词汇表 gate/decision 行的 data 形状) */
180
+ export interface GateDecisionRecord {
181
+ /** 调用 id(与 tool/call·tool/result 配对键) */
182
+ toolCallId: string;
183
+ /** 决策三值(allow / block / mutate) */
184
+ decision: 'allow' | 'block' | 'mutate';
185
+ /** 决策理由(block 原因 / 放行来源标注;缺省 'ok') */
186
+ reason: string;
187
+ }
188
+ /** gate/decision 落账 sink(装配根接 session.append;tools 不依赖 session——DAG 单向) */
189
+ export type GateDecisionSink = (record: GateDecisionRecord) => void;
190
+ /** 三段管道执行器(注册表 toAgentTool 的执行真身;抛 BaseError 由 loop 包装 isError) */
191
+ export type ToolPipelineExecutor = (def: ToolDefinition, toolCallId: string, args: Record<string, unknown>, signal?: AbortSignal, onUpdate?: ToolUpdateCallback, sessionId?: string) => Promise<AgentToolResult>;
192
+ export declare const TOOL_PRE_EXECUTE_EVENT = "tools_pre_execute";
193
+ export declare const TOOL_EXECUTE_EVENT = "tools_execute";
194
+ export declare const TOOL_POST_EXECUTE_EVENT = "tools_post_execute";
195
+ export declare const TOOLS_CHANGE_EVENT = "tools_change";
196
+ /** tools 件经 ctx 事件面消费的词汇全集(装配根注册清单单源) */
197
+ export declare const TOOL_EVENT_NAMES: readonly string[];
@@ -0,0 +1,33 @@
1
+ /**
2
+ * L0 contracts — AgentTool 工具族类型(agent 件三段管道的执行体契约)。
3
+ *
4
+ * 裁决(本仓 vs berry 蓝本差异②):蓝本 AgentTool 族先落 agent 件后迁
5
+ * contracts——本仓一步到位直上 contracts(插件 defineTool 的参数类型消费面,
6
+ * 避免落码即迁的双写窗口)。工具面三段管道(schema→守门→执行)本体在
7
+ * tools 件(后续批);本件只钉**执行体形状**——loop 工具批的直接消费面。
8
+ */
9
+ /**
10
+ * 工具档偏序 rank(04 §9 定形块①:read < write < exec)。与 §8 沙箱档
11
+ * TIER_RANK(safety/approval 件内私有常量)**两轴分立**:工具档 = 该工具
12
+ * 固有风险位,沙箱档 = 本次运行许可面,互不推导。消费位:策略表条目
13
+ * `effect?` 限定的偏序包含判(safety 匹配引擎)、粘性/allow 授权不跨档
14
+ * 覆盖的比较面(04 §9 ①「write 档免问授权结构上不覆盖 exec 调用」)。
15
+ */
16
+ export const TOOL_TIER_RANK = {
17
+ read: 0,
18
+ write: 1,
19
+ exec: 2,
20
+ };
21
+ /* 钩子词汇常量(03 §2.4 主表三段 + tools_change——词本体在 LIVE 词表,
22
+ * 装配根 registerEventNames 消费本清单;tools 件自用 + safety 守门行订阅面) */
23
+ export const TOOL_PRE_EXECUTE_EVENT = 'tools_pre_execute';
24
+ export const TOOL_EXECUTE_EVENT = 'tools_execute';
25
+ export const TOOL_POST_EXECUTE_EVENT = 'tools_post_execute';
26
+ export const TOOLS_CHANGE_EVENT = 'tools_change';
27
+ /** tools 件经 ctx 事件面消费的词汇全集(装配根注册清单单源) */
28
+ export const TOOL_EVENT_NAMES = [
29
+ TOOL_PRE_EXECUTE_EVENT,
30
+ TOOL_EXECUTE_EVENT,
31
+ TOOL_POST_EXECUTE_EVENT,
32
+ TOOLS_CHANGE_EVENT,
33
+ ];