@sema-agent/server 1.323.0 → 2.0.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.
Files changed (539) hide show
  1. package/dist/approval-hmac.d.ts +40 -0
  2. package/dist/approval-hmac.js +67 -0
  3. package/dist/approval.d.ts +31 -0
  4. package/dist/approval.js +72 -4
  5. package/dist/audit.d.ts +26 -0
  6. package/dist/audit.js +40 -1
  7. package/dist/auth-bridge.d.ts +10 -0
  8. package/dist/auth-bridge.js +47 -4
  9. package/dist/auth-keys.d.ts +19 -0
  10. package/dist/auth-keys.js +13 -0
  11. package/dist/bake-runner/main.d.ts +5 -0
  12. package/dist/bake-runner/main.js +43 -4
  13. package/dist/bake-runner/protocol.d.ts +57 -0
  14. package/dist/bake-runner/protocol.js +58 -3
  15. package/dist/bake-runner/runner.d.ts +54 -0
  16. package/dist/bake-runner/runner.js +87 -5
  17. package/dist/bench/l8/artifact.d.ts +63 -0
  18. package/dist/bench/l8/artifact.js +61 -2
  19. package/dist/bench/l8/escape.d.ts +36 -0
  20. package/dist/bench/l8/escape.js +25 -0
  21. package/dist/bench/l8/index.d.ts +14 -0
  22. package/dist/bench/l8/index.js +14 -0
  23. package/dist/bench/l8/probes.d.ts +74 -0
  24. package/dist/bench/l8/probes.js +60 -0
  25. package/dist/bench/l8/run-probes.d.ts +43 -0
  26. package/dist/bench/l8/run-probes.js +45 -2
  27. package/dist/bench/s1/arms.d.ts +126 -0
  28. package/dist/bench/s1/arms.js +188 -13
  29. package/dist/bench/s1/live-deps.d.ts +66 -0
  30. package/dist/bench/s1/live-deps.js +249 -11
  31. package/dist/bench/s1/oracle.d.ts +49 -0
  32. package/dist/bench/s1/oracle.js +36 -1
  33. package/dist/bench/s1/repair-oracle-adapter.d.ts +33 -0
  34. package/dist/bench/s1/repair-oracle-adapter.js +30 -0
  35. package/dist/bench/s1/reviewer.d.ts +38 -0
  36. package/dist/bench/s1/reviewer.js +34 -0
  37. package/dist/bench/s1/row.d.ts +77 -0
  38. package/dist/bench/s1/row.js +62 -0
  39. package/dist/bench/s1/run-firm.d.ts +47 -0
  40. package/dist/bench/s1/run-firm.js +70 -4
  41. package/dist/bench/s1/runner-ctx.d.ts +71 -0
  42. package/dist/bench/s1/runner-ctx.js +36 -0
  43. package/dist/bench/s1/tasks.d.ts +108 -0
  44. package/dist/bench/s1/tasks.js +115 -0
  45. package/dist/boot-reclaim.d.ts +19 -0
  46. package/dist/boot-reclaim.js +20 -0
  47. package/dist/brain.d.ts +25 -0
  48. package/dist/brain.js +61 -1
  49. package/dist/budget.d.ts +66 -0
  50. package/dist/budget.js +128 -4
  51. package/dist/capabilities/builtin-tools.d.ts +3 -0
  52. package/dist/capabilities/builtin-tools.js +3 -0
  53. package/dist/capabilities/center-plugins.d.ts +17 -1
  54. package/dist/capabilities/center-plugins.js +45 -4
  55. package/dist/capabilities/center-prompts.d.ts +46 -0
  56. package/dist/capabilities/center-prompts.js +57 -3
  57. package/dist/capabilities/code-review-council.d.ts +28 -0
  58. package/dist/capabilities/code-review-council.js +40 -7
  59. package/dist/capabilities/collab-wire.d.ts +2 -0
  60. package/dist/capabilities/collab-workflows.d.ts +7 -0
  61. package/dist/capabilities/collab-workflows.js +44 -1
  62. package/dist/capabilities/oa-tools.d.ts +6 -0
  63. package/dist/capabilities/oa-tools.js +10 -0
  64. package/dist/capabilities/prompt.d.ts +14 -0
  65. package/dist/capabilities/prompt.js +14 -0
  66. package/dist/capabilities/prompts/code-review.d.ts +14 -0
  67. package/dist/capabilities/prompts/code-review.js +14 -0
  68. package/dist/capabilities/prompts/identity.d.ts +6 -0
  69. package/dist/capabilities/prompts/identity.js +6 -0
  70. package/dist/capabilities/prompts/team.d.ts +4 -0
  71. package/dist/capabilities/prompts/team.js +4 -0
  72. package/dist/capabilities/repo-tools.d.ts +11 -0
  73. package/dist/capabilities/repo-tools.js +8 -0
  74. package/dist/capabilities/sandbox-file-send.d.ts +95 -0
  75. package/dist/capabilities/sandbox-file-send.js +91 -3
  76. package/dist/capabilities/scenarios.d.ts +130 -0
  77. package/dist/capabilities/scenarios.js +180 -7
  78. package/dist/capabilities/select-environment-tool.d.ts +7 -0
  79. package/dist/capabilities/select-environment-tool.js +30 -0
  80. package/dist/capabilities/send-user-file-tool.d.ts +33 -0
  81. package/dist/capabilities/send-user-file-tool.js +65 -1
  82. package/dist/capabilities/skills.d.ts +29 -0
  83. package/dist/capabilities/skills.js +13 -2
  84. package/dist/capabilities/team.d.ts +22 -0
  85. package/dist/capabilities/team.js +22 -2
  86. package/dist/capabilities/tool-defer.d.ts +26 -0
  87. package/dist/capabilities/tool-defer.js +3 -0
  88. package/dist/config-center/apply-effective.d.ts +65 -0
  89. package/dist/config-center/apply-effective.js +204 -12
  90. package/dist/config-center/http-client.d.ts +34 -0
  91. package/dist/config-center/http-client.js +68 -0
  92. package/dist/config-center/restart-signal.d.ts +22 -0
  93. package/dist/config-center/restart-signal.js +39 -0
  94. package/dist/config-center/skills-mcp.d.ts +20 -1
  95. package/dist/config-center/skills-mcp.js +42 -7
  96. package/dist/config-center/types.d.ts +92 -1
  97. package/dist/config-lkg.d.ts +12 -0
  98. package/dist/config-lkg.js +41 -0
  99. package/dist/config-provider.d.ts +78 -0
  100. package/dist/config-provider.js +165 -2
  101. package/dist/config-types.d.ts +546 -0
  102. package/dist/config.d.ts +64 -0
  103. package/dist/config.js +455 -60
  104. package/dist/degenerate-instrument.d.ts +38 -0
  105. package/dist/degenerate-instrument.js +55 -3
  106. package/dist/elicitation.d.ts +39 -0
  107. package/dist/elicitation.js +87 -3
  108. package/dist/env-facts.d.ts +61 -0
  109. package/dist/env-facts.js +73 -7
  110. package/dist/fleet/fleet-bus.d.ts +185 -0
  111. package/dist/fleet/fleet-bus.js +333 -27
  112. package/dist/fleet/subagent-tail-bus.d.ts +11 -0
  113. package/dist/fleet/subagent-tail-bus.js +33 -2
  114. package/dist/fleet-client.d.ts +38 -0
  115. package/dist/fleet-client.js +44 -9
  116. package/dist/fleet-lease.d.ts +46 -0
  117. package/dist/fleet-lease.js +73 -5
  118. package/dist/hooks/branch-transcript.d.ts +8 -0
  119. package/dist/hooks/branch-transcript.js +33 -0
  120. package/dist/hooks/cc-stop-prompt.d.ts +42 -0
  121. package/dist/hooks/cc-stop-prompt.js +43 -1
  122. package/dist/hooks/hook-llm.d.ts +15 -0
  123. package/dist/hooks/hook-llm.js +47 -0
  124. package/dist/hooks/hook-runner.d.ts +89 -0
  125. package/dist/hooks/hook-runner.js +327 -18
  126. package/dist/http/idempotency.d.ts +31 -0
  127. package/dist/http/idempotency.js +34 -0
  128. package/dist/http/principal-gate.d.ts +17 -0
  129. package/dist/http/principal-gate.js +35 -3
  130. package/dist/http/route-ctx.d.ts +36 -0
  131. package/dist/http/routes/approvals-assistant.d.ts +25 -0
  132. package/dist/http/routes/approvals-assistant.js +253 -23
  133. package/dist/http/routes/attachments.js +22 -4
  134. package/dist/http/routes/capabilities.d.ts +7 -0
  135. package/dist/http/routes/capabilities.js +202 -1
  136. package/dist/http/routes/fleet.d.ts +6 -0
  137. package/dist/http/routes/fleet.js +94 -5
  138. package/dist/http/routes/images.d.ts +17 -0
  139. package/dist/http/routes/images.js +222 -14
  140. package/dist/http/routes/leader.d.ts +7 -0
  141. package/dist/http/routes/leader.js +10 -0
  142. package/dist/http/routes/memory-policy.d.ts +6 -0
  143. package/dist/http/routes/memory-policy.js +38 -6
  144. package/dist/http/routes/notify-wake.d.ts +10 -0
  145. package/dist/http/routes/notify-wake.js +19 -3
  146. package/dist/http/routes/observability.d.ts +6 -0
  147. package/dist/http/routes/observability.js +19 -2
  148. package/dist/http/routes/runs.d.ts +15 -0
  149. package/dist/http/routes/runs.js +464 -41
  150. package/dist/http/routes/session-sync.d.ts +15 -0
  151. package/dist/http/routes/session-sync.js +229 -19
  152. package/dist/http/routes/sessions-list.d.ts +6 -0
  153. package/dist/http/routes/sessions-list.js +35 -4
  154. package/dist/http/routes/sessions.d.ts +14 -0
  155. package/dist/http/routes/sessions.js +176 -31
  156. package/dist/http/routes/side-query.d.ts +8 -0
  157. package/dist/http/routes/side-query.js +26 -1
  158. package/dist/http/routes/tasks.d.ts +18 -0
  159. package/dist/http/routes/tasks.js +501 -38
  160. package/dist/http/routes/trace-usage.d.ts +10 -0
  161. package/dist/http/routes/trace-usage.js +66 -14
  162. package/dist/http/routes/workflows.d.ts +12 -0
  163. package/dist/http/routes/workflows.js +180 -19
  164. package/dist/http/run-meta.d.ts +11 -0
  165. package/dist/http/run-meta.js +6 -0
  166. package/dist/http/send.d.ts +19 -0
  167. package/dist/http/send.js +11 -0
  168. package/dist/http/server.d.ts +255 -0
  169. package/dist/http/server.js +921 -75
  170. package/dist/http/sse-log.d.ts +15 -0
  171. package/dist/http/sse-log.js +16 -0
  172. package/dist/http/tar.d.ts +9 -0
  173. package/dist/http/tar.js +21 -5
  174. package/dist/http/wire-gate.d.ts +9 -0
  175. package/dist/http/wire-gate.js +9 -0
  176. package/dist/http/wire-types.d.ts +187 -0
  177. package/dist/http/workspace-content.d.ts +8 -0
  178. package/dist/http/workspace-content.js +10 -0
  179. package/dist/images/bake-validate.d.ts +63 -0
  180. package/dist/images/bake-validate.js +71 -1
  181. package/dist/images/manifest.d.ts +19 -0
  182. package/dist/images/manifest.js +6 -1
  183. package/dist/index.d.ts +1 -5
  184. package/dist/index.js +10 -5
  185. package/dist/key-resolver.d.ts +23 -0
  186. package/dist/key-resolver.js +27 -2
  187. package/dist/leader/diffout.d.ts +23 -0
  188. package/dist/leader/diffout.js +8 -1
  189. package/dist/leader/diffup.d.ts +32 -0
  190. package/dist/leader/diffup.js +43 -0
  191. package/dist/leader/endpoint.d.ts +20 -0
  192. package/dist/leader/endpoint.js +25 -2
  193. package/dist/leader/fanout.d.ts +60 -0
  194. package/dist/leader/fanout.js +29 -3
  195. package/dist/leader/grader-env-factory.d.ts +74 -0
  196. package/dist/leader/grader-env-factory.js +62 -3
  197. package/dist/leader/leader.d.ts +97 -0
  198. package/dist/leader/leader.js +151 -4
  199. package/dist/leader/merge.d.ts +94 -0
  200. package/dist/leader/merge.js +112 -9
  201. package/dist/leader/planner.d.ts +52 -0
  202. package/dist/leader/planner.js +47 -3
  203. package/dist/leader/repair-oracle.d.ts +61 -0
  204. package/dist/leader/repair-oracle.js +59 -1
  205. package/dist/leader/repair-wire.d.ts +78 -0
  206. package/dist/leader/repair-wire.js +79 -2
  207. package/dist/leader/wire.d.ts +79 -0
  208. package/dist/leader/wire.js +255 -8
  209. package/dist/lsp/e2b-bridge.d.ts +16 -0
  210. package/dist/lsp/e2b-bridge.js +32 -4
  211. package/dist/lsp/e2b-manager.d.ts +10 -0
  212. package/dist/lsp/e2b-manager.js +18 -2
  213. package/dist/lsp/lsp-frames.d.ts +12 -0
  214. package/dist/lsp/lsp-frames.js +12 -0
  215. package/dist/lsp/manager.d.ts +12 -0
  216. package/dist/lsp/manager.js +35 -2
  217. package/dist/lsp/types.d.ts +10 -0
  218. package/dist/lsp/ws-transport.d.ts +12 -0
  219. package/dist/lsp/ws-transport.js +53 -5
  220. package/dist/lsp-evict.d.ts +14 -0
  221. package/dist/lsp-evict.js +15 -1
  222. package/dist/main.js +2132 -96
  223. package/dist/memory-export.d.ts +1 -0
  224. package/dist/memory-export.js +4 -0
  225. package/dist/memory-scope.d.ts +49 -0
  226. package/dist/memory-scope.js +87 -4
  227. package/dist/memory-sync-client.d.ts +24 -0
  228. package/dist/memory-sync-client.js +41 -2
  229. package/dist/memory-sync.d.ts +23 -0
  230. package/dist/memory-sync.js +70 -1
  231. package/dist/model-select.d.ts +39 -0
  232. package/dist/model-select.js +42 -1
  233. package/dist/observability/cost-quota.d.ts +20 -0
  234. package/dist/observability/cost-quota.js +4 -0
  235. package/dist/observability/cost-taxonomy.d.ts +45 -0
  236. package/dist/observability/cost-taxonomy.js +34 -0
  237. package/dist/observability/logger.d.ts +1 -0
  238. package/dist/observability/logger.js +6 -0
  239. package/dist/observability/metrics.d.ts +13 -0
  240. package/dist/observability/metrics.js +63 -0
  241. package/dist/observability/otel-exporter.d.ts +9 -0
  242. package/dist/observability/otel-exporter.js +11 -3
  243. package/dist/observability/principal-context.d.ts +9 -0
  244. package/dist/observability/principal-context.js +9 -0
  245. package/dist/observability/prompt-manifest.d.ts +37 -0
  246. package/dist/observability/prompt-manifest.js +35 -1
  247. package/dist/observability/rate-limit.d.ts +10 -0
  248. package/dist/observability/rate-limit.js +1 -0
  249. package/dist/observability/tool-trace.d.ts +24 -0
  250. package/dist/observability/tool-trace.js +41 -1
  251. package/dist/orchestration/hardened-vm-runner.d.ts +107 -0
  252. package/dist/orchestration/hardened-vm-runner.js +119 -4
  253. package/dist/orchestration/hardened-vm-worker-runner.d.ts +14 -0
  254. package/dist/orchestration/hardened-vm-worker-runner.js +26 -1
  255. package/dist/orchestration/hardened-vm-worker.js +27 -0
  256. package/dist/orchestration/subagent-steer.d.ts +44 -0
  257. package/dist/orchestration/subagent-steer.js +45 -1
  258. package/dist/orchestration/workflow-agent-steer.d.ts +54 -0
  259. package/dist/orchestration/workflow-agent-steer.js +80 -1
  260. package/dist/orchestration/workflow-completion-inbox.d.ts +189 -2
  261. package/dist/orchestration/workflow-completion-inbox.js +283 -32
  262. package/dist/orchestration/workflow-notify-journal.d.ts +132 -1
  263. package/dist/orchestration/workflow-notify-journal.js +187 -13
  264. package/dist/parked-decide.d.ts +61 -0
  265. package/dist/parked-decide.js +58 -1
  266. package/dist/per-task-image.d.ts +54 -0
  267. package/dist/per-task-image.js +41 -0
  268. package/dist/plan-cache-probe.d.ts +35 -0
  269. package/dist/plan-cache-probe.js +18 -3
  270. package/dist/plugins/approval-exemption-store.d.ts +7 -0
  271. package/dist/plugins/approval-exemption-store.js +28 -2
  272. package/dist/plugins/approval-store-sql.d.ts +64 -0
  273. package/dist/plugins/approval-store-sql.js +32 -0
  274. package/dist/plugins/background-agent-store-sql.d.ts +55 -0
  275. package/dist/plugins/background-agent-store-sql.js +91 -4
  276. package/dist/plugins/background-shell-support.d.ts +98 -0
  277. package/dist/plugins/background-shell-support.js +117 -13
  278. package/dist/plugins/blob-backend.d.ts +104 -0
  279. package/dist/plugins/blob-backend.js +163 -6
  280. package/dist/plugins/breaker-state-sql.d.ts +65 -1
  281. package/dist/plugins/breaker-state-sql.js +46 -8
  282. package/dist/plugins/caching-session-store.d.ts +42 -0
  283. package/dist/plugins/caching-session-store.js +63 -3
  284. package/dist/plugins/checkpoint-store-sql.d.ts +179 -0
  285. package/dist/plugins/checkpoint-store-sql.js +239 -11
  286. package/dist/plugins/file-outcome-sink.d.ts +4 -0
  287. package/dist/plugins/file-outcome-sink.js +9 -0
  288. package/dist/plugins/file-resume-anchor-store.d.ts +20 -0
  289. package/dist/plugins/file-resume-anchor-store.js +43 -4
  290. package/dist/plugins/file-run-store.d.ts +90 -0
  291. package/dist/plugins/file-run-store.js +145 -13
  292. package/dist/plugins/file-snapshot-store-sql.d.ts +133 -1
  293. package/dist/plugins/file-snapshot-store-sql.js +178 -10
  294. package/dist/plugins/file-workflow-journal-store.d.ts +10 -0
  295. package/dist/plugins/file-workflow-journal-store.js +10 -0
  296. package/dist/plugins/fork-routing-session-store.d.ts +47 -0
  297. package/dist/plugins/fork-routing-session-store.js +51 -3
  298. package/dist/plugins/host-platform.d.ts +69 -0
  299. package/dist/plugins/host-platform.js +81 -2
  300. package/dist/plugins/image-bake-store-sql.d.ts +136 -1
  301. package/dist/plugins/image-bake-store-sql.js +241 -7
  302. package/dist/plugins/image-index-sql.d.ts +46 -0
  303. package/dist/plugins/image-index-sql.js +113 -4
  304. package/dist/plugins/k8s-bg-scripts.d.ts +34 -0
  305. package/dist/plugins/k8s-bg-scripts.js +88 -4
  306. package/dist/plugins/k8s-exec-protocol.d.ts +33 -0
  307. package/dist/plugins/k8s-exec-protocol.js +41 -0
  308. package/dist/plugins/local-checkpoint-store.d.ts +40 -0
  309. package/dist/plugins/local-checkpoint-store.js +86 -7
  310. package/dist/plugins/local-session-store.d.ts +157 -0
  311. package/dist/plugins/local-session-store.js +289 -34
  312. package/dist/plugins/local-task-attachment-store.js +14 -2
  313. package/dist/plugins/mailbox-store-sql.d.ts +38 -0
  314. package/dist/plugins/mailbox-store-sql.js +39 -6
  315. package/dist/plugins/memory-engine-pg.d.ts +30 -0
  316. package/dist/plugins/memory-engine-pg.js +122 -4
  317. package/dist/plugins/memory-engine-tidb.d.ts +26 -0
  318. package/dist/plugins/memory-engine-tidb.js +115 -5
  319. package/dist/plugins/memory-engine-vector-util.d.ts +5 -0
  320. package/dist/plugins/memory-engine-vector-util.js +5 -0
  321. package/dist/plugins/memory-resume-anchor-store.d.ts +8 -0
  322. package/dist/plugins/memory-resume-anchor-store.js +17 -0
  323. package/dist/plugins/memory-run-store.d.ts +63 -0
  324. package/dist/plugins/memory-run-store.js +73 -8
  325. package/dist/plugins/memory-session-policy-store.d.ts +17 -0
  326. package/dist/plugins/memory-session-policy-store.js +17 -0
  327. package/dist/plugins/memory-sync-store-pg.d.ts +42 -0
  328. package/dist/plugins/memory-sync-store-pg.js +45 -2
  329. package/dist/plugins/memory-sync-store-tidb.d.ts +9 -0
  330. package/dist/plugins/memory-sync-store-tidb.js +31 -1
  331. package/dist/plugins/outcome-ledger-sql.d.ts +63 -0
  332. package/dist/plugins/outcome-ledger-sql.js +97 -3
  333. package/dist/plugins/pg-approval-store.d.ts +7 -0
  334. package/dist/plugins/pg-approval-store.js +7 -0
  335. package/dist/plugins/pg-breaker-state.d.ts +6 -0
  336. package/dist/plugins/pg-breaker-state.js +6 -0
  337. package/dist/plugins/pg-checkpoint-store.d.ts +8 -0
  338. package/dist/plugins/pg-checkpoint-store.js +8 -0
  339. package/dist/plugins/pg-cost-quota.d.ts +17 -0
  340. package/dist/plugins/pg-cost-quota.js +6 -0
  341. package/dist/plugins/pg-file-snapshot-store.d.ts +6 -0
  342. package/dist/plugins/pg-file-snapshot-store.js +6 -0
  343. package/dist/plugins/pg-image-bake.d.ts +9 -0
  344. package/dist/plugins/pg-image-bake.js +9 -0
  345. package/dist/plugins/pg-image-index.d.ts +9 -0
  346. package/dist/plugins/pg-image-index.js +9 -0
  347. package/dist/plugins/pg-outcome-ledger.d.ts +9 -0
  348. package/dist/plugins/pg-outcome-ledger.js +9 -0
  349. package/dist/plugins/pg-pool.d.ts +50 -0
  350. package/dist/plugins/pg-pool.js +78 -0
  351. package/dist/plugins/pg-query.d.ts +11 -0
  352. package/dist/plugins/pg-rate-limiter.d.ts +23 -0
  353. package/dist/plugins/pg-rate-limiter.js +12 -2
  354. package/dist/plugins/pg-resume-anchor-store.d.ts +5 -0
  355. package/dist/plugins/pg-resume-anchor-store.js +5 -0
  356. package/dist/plugins/pg-run-store.d.ts +7 -0
  357. package/dist/plugins/pg-run-store.js +7 -0
  358. package/dist/plugins/pg-safe-json.d.ts +13 -0
  359. package/dist/plugins/pg-safe-json.js +40 -4
  360. package/dist/plugins/pg-session-policy-store.d.ts +5 -0
  361. package/dist/plugins/pg-session-policy-store.js +5 -0
  362. package/dist/plugins/pg-session-storage.d.ts +72 -0
  363. package/dist/plugins/pg-session-storage.js +152 -20
  364. package/dist/plugins/pg-session-store.d.ts +10 -0
  365. package/dist/plugins/pg-session-store.js +10 -0
  366. package/dist/plugins/pg-tool-result-store.d.ts +7 -0
  367. package/dist/plugins/pg-tool-result-store.js +7 -0
  368. package/dist/plugins/pg-workflow-journal-store.d.ts +7 -0
  369. package/dist/plugins/pg-workflow-journal-store.js +7 -0
  370. package/dist/plugins/pg-workflow-run-store.d.ts +7 -0
  371. package/dist/plugins/pg-workflow-run-store.js +7 -0
  372. package/dist/plugins/posix-shell-fs.d.ts +3 -0
  373. package/dist/plugins/posix-shell-fs.js +31 -1
  374. package/dist/plugins/remote-env-adb.d.ts +25 -0
  375. package/dist/plugins/remote-env-adb.js +95 -12
  376. package/dist/plugins/remote-env-e2b.d.ts +146 -0
  377. package/dist/plugins/remote-env-e2b.js +371 -40
  378. package/dist/plugins/remote-env-file-error.d.ts +34 -0
  379. package/dist/plugins/remote-env-file-error.js +37 -0
  380. package/dist/plugins/remote-env-host.d.ts +151 -0
  381. package/dist/plugins/remote-env-host.js +468 -70
  382. package/dist/plugins/remote-env-k8s.d.ts +135 -0
  383. package/dist/plugins/remote-env-k8s.js +318 -32
  384. package/dist/plugins/remote-env-local-docker.d.ts +65 -0
  385. package/dist/plugins/remote-env-local-docker.js +149 -24
  386. package/dist/plugins/remote-env-ssh.d.ts +35 -0
  387. package/dist/plugins/remote-env-ssh.js +117 -20
  388. package/dist/plugins/remote-scratchpad.d.ts +38 -0
  389. package/dist/plugins/remote-scratchpad.js +32 -2
  390. package/dist/plugins/remote-shell.d.ts +22 -0
  391. package/dist/plugins/remote-shell.js +27 -1
  392. package/dist/plugins/resume-anchor-store-sql.d.ts +28 -0
  393. package/dist/plugins/resume-anchor-store-sql.js +11 -0
  394. package/dist/plugins/roster-store-sql.d.ts +27 -0
  395. package/dist/plugins/roster-store-sql.js +54 -0
  396. package/dist/plugins/run-store-sql.d.ts +194 -0
  397. package/dist/plugins/run-store-sql.js +210 -9
  398. package/dist/plugins/s3-presign.d.ts +20 -0
  399. package/dist/plugins/s3-presign.js +49 -2
  400. package/dist/plugins/scheduler-support.d.ts +12 -0
  401. package/dist/plugins/scheduler-support.js +75 -3
  402. package/dist/plugins/send-file-ledger.d.ts +15 -0
  403. package/dist/plugins/send-file-ledger.js +53 -4
  404. package/dist/plugins/send-user-file.d.ts +77 -0
  405. package/dist/plugins/send-user-file.js +92 -4
  406. package/dist/plugins/session-policy-store-sql.d.ts +15 -0
  407. package/dist/plugins/session-policy-store-sql.js +75 -3
  408. package/dist/plugins/session-store.d.ts +45 -0
  409. package/dist/plugins/session-store.js +51 -0
  410. package/dist/plugins/sql-driver.d.ts +77 -0
  411. package/dist/plugins/sql-driver.js +4 -0
  412. package/dist/plugins/sql-escape.d.ts +8 -0
  413. package/dist/plugins/sql-escape.js +8 -0
  414. package/dist/plugins/sql-row-helpers.d.ts +25 -0
  415. package/dist/plugins/sql-row-helpers.js +25 -0
  416. package/dist/plugins/store-backend.d.ts +103 -0
  417. package/dist/plugins/store-backend.js +120 -27
  418. package/dist/plugins/store-contracts.d.ts +62 -0
  419. package/dist/plugins/store-contracts.js +3 -0
  420. package/dist/plugins/task-attachment-store.d.ts +60 -0
  421. package/dist/plugins/task-attachment-store.js +49 -3
  422. package/dist/plugins/task-list-store-sql.d.ts +25 -0
  423. package/dist/plugins/task-list-store-sql.js +21 -0
  424. package/dist/plugins/tidb-approval-store.d.ts +6 -0
  425. package/dist/plugins/tidb-approval-store.js +6 -0
  426. package/dist/plugins/tidb-breaker-state.d.ts +5 -0
  427. package/dist/plugins/tidb-breaker-state.js +5 -0
  428. package/dist/plugins/tidb-checkpoint-store.d.ts +7 -0
  429. package/dist/plugins/tidb-checkpoint-store.js +7 -0
  430. package/dist/plugins/tidb-cost-quota.d.ts +6 -0
  431. package/dist/plugins/tidb-cost-quota.js +1 -0
  432. package/dist/plugins/tidb-file-snapshot-store.d.ts +6 -0
  433. package/dist/plugins/tidb-file-snapshot-store.js +6 -0
  434. package/dist/plugins/tidb-image-bake.d.ts +8 -0
  435. package/dist/plugins/tidb-image-bake.js +8 -0
  436. package/dist/plugins/tidb-image-index.d.ts +8 -0
  437. package/dist/plugins/tidb-image-index.js +8 -0
  438. package/dist/plugins/tidb-outcome-ledger.d.ts +10 -0
  439. package/dist/plugins/tidb-outcome-ledger.js +10 -0
  440. package/dist/plugins/tidb-pool.d.ts +56 -0
  441. package/dist/plugins/tidb-pool.js +181 -1
  442. package/dist/plugins/tidb-rate-limiter.d.ts +11 -0
  443. package/dist/plugins/tidb-rate-limiter.js +5 -2
  444. package/dist/plugins/tidb-resume-anchor-store.d.ts +5 -0
  445. package/dist/plugins/tidb-resume-anchor-store.js +5 -0
  446. package/dist/plugins/tidb-run-store.d.ts +7 -0
  447. package/dist/plugins/tidb-run-store.js +7 -0
  448. package/dist/plugins/tidb-session-policy-store.d.ts +5 -0
  449. package/dist/plugins/tidb-session-policy-store.js +5 -0
  450. package/dist/plugins/tidb-session-storage.d.ts +43 -0
  451. package/dist/plugins/tidb-session-storage.js +62 -3
  452. package/dist/plugins/tidb-session-store.d.ts +142 -0
  453. package/dist/plugins/tidb-session-store.js +264 -16
  454. package/dist/plugins/tidb-tool-result-store.d.ts +5 -0
  455. package/dist/plugins/tidb-tool-result-store.js +7 -0
  456. package/dist/plugins/tidb-workflow-journal-store.d.ts +7 -0
  457. package/dist/plugins/tidb-workflow-journal-store.js +7 -0
  458. package/dist/plugins/tidb-workflow-run-store.d.ts +8 -0
  459. package/dist/plugins/tidb-workflow-run-store.js +8 -0
  460. package/dist/plugins/tool-result-store-sql.d.ts +58 -0
  461. package/dist/plugins/tool-result-store-sql.js +38 -2
  462. package/dist/plugins/web-search.d.ts +35 -0
  463. package/dist/plugins/web-search.js +45 -9
  464. package/dist/plugins/workflow-journal-limits.d.ts +10 -0
  465. package/dist/plugins/workflow-journal-limits.js +10 -0
  466. package/dist/plugins/workflow-journal-store-sql.d.ts +78 -0
  467. package/dist/plugins/workflow-journal-store-sql.js +58 -2
  468. package/dist/plugins/workflow-run-store-sql.d.ts +84 -0
  469. package/dist/plugins/workflow-run-store-sql.js +84 -6
  470. package/dist/plugins/worktree-isolation.d.ts +45 -0
  471. package/dist/plugins/worktree-isolation.js +105 -6
  472. package/dist/plugins/write-behind-counter.d.ts +56 -1
  473. package/dist/plugins/write-behind-counter.js +53 -14
  474. package/dist/principal-jwt.d.ts +24 -0
  475. package/dist/principal-jwt.js +60 -5
  476. package/dist/project-memory.d.ts +22 -0
  477. package/dist/project-memory.js +144 -15
  478. package/dist/prompts-domain-validate.d.ts +28 -0
  479. package/dist/prompts-domain-validate.js +42 -1
  480. package/dist/question.d.ts +33 -0
  481. package/dist/question.js +69 -2
  482. package/dist/resource-suspend.d.ts +21 -0
  483. package/dist/resource-suspend.js +16 -0
  484. package/dist/router/route-orchestration.d.ts +78 -0
  485. package/dist/router/route-orchestration.js +77 -0
  486. package/dist/run-local.d.ts +32 -0
  487. package/dist/run-local.js +172 -8
  488. package/dist/runs.d.ts +189 -4
  489. package/dist/runs.js +465 -24
  490. package/dist/runtime-caps-resolver.d.ts +106 -0
  491. package/dist/runtime-caps-resolver.js +89 -4
  492. package/dist/runtime-governance.d.ts +84 -0
  493. package/dist/runtime-governance.js +127 -1
  494. package/dist/sandbox-pkg-source.d.ts +23 -0
  495. package/dist/sandbox-pkg-source.js +37 -0
  496. package/dist/sealed-key.d.ts +54 -0
  497. package/dist/sealed-key.js +68 -3
  498. package/dist/security.d.ts +108 -0
  499. package/dist/security.js +145 -6
  500. package/dist/sema-registry.d.ts +21 -0
  501. package/dist/sema-registry.js +21 -0
  502. package/dist/session-leaf-bus.d.ts +31 -0
  503. package/dist/session-leaf-bus.js +32 -0
  504. package/dist/session-sync-content.d.ts +46 -0
  505. package/dist/session-sync-content.js +47 -1
  506. package/dist/session-sync-kernel.d.ts +89 -0
  507. package/dist/session-sync-kernel.js +48 -3
  508. package/dist/session-sync.d.ts +125 -0
  509. package/dist/session-sync.js +181 -8
  510. package/dist/session-titler.d.ts +26 -0
  511. package/dist/session-titler.js +41 -7
  512. package/dist/session-watch.d.ts +53 -1
  513. package/dist/session-watch.js +73 -9
  514. package/dist/sighup-idle.d.ts +30 -0
  515. package/dist/sighup-idle.js +12 -1
  516. package/dist/spec-fields.d.ts +91 -3
  517. package/dist/spec-fields.js +116 -4
  518. package/dist/task-cwd.d.ts +50 -0
  519. package/dist/task-cwd.js +68 -1
  520. package/dist/task-mcp.d.ts +47 -0
  521. package/dist/task-mcp.js +29 -0
  522. package/dist/task-settings.d.ts +175 -0
  523. package/dist/task-settings.js +226 -11
  524. package/dist/task-workflow.d.ts +67 -0
  525. package/dist/task-workflow.js +75 -8
  526. package/dist/tool-approval.d.ts +91 -0
  527. package/dist/tool-approval.js +215 -0
  528. package/dist/trace/artifacts.d.ts +9 -0
  529. package/dist/trace/artifacts.js +30 -5
  530. package/dist/trace/core-keyset-guard.d.ts +18 -0
  531. package/dist/trace/ledger-sink.d.ts +43 -0
  532. package/dist/trace/ledger-sink.js +64 -5
  533. package/dist/trace/project.d.ts +133 -0
  534. package/dist/trace/project.js +189 -2
  535. package/dist/trace/redact.d.ts +19 -0
  536. package/dist/trace/redact.js +66 -9
  537. package/dist/usage-analytics.d.ts +26 -0
  538. package/dist/usage-analytics.js +26 -3
  539. package/package.json +1 -1
@@ -1,14 +1,25 @@
1
+ /** wire 帧(SSE data 载荷)。`lagged`(慢消费丢帧标记)与 `task_settled`(中途终态信号,复审 #3:
2
+ * 三条 run 腿的 onTaskNotification 观察者顺手 publish——订阅期间子代 settle 不再只剩 heartbeat 永挂,
3
+ * 路由收到即写帧收流)是本总线自己的帧(非 core 事件)。`task_settled` 自 core 1.373 起携可选
4
+ * `seq`(settle 铸的 stop-cycle 世代号,TaskNotificationPayload.seq 透传)——流上实时拿到「第 N 世代
5
+ * 终结」,与 meta 帧的 seq(durable 终态跨实例 serve 时在场)成套。 */
1
6
  export type SubagentTailFrame = Record<string, unknown> & {
2
7
  type: string;
3
8
  };
9
+ /** core forward 事件 → wire 投影(sync 主流五分支同源;不认识的帧类型=null 不发——tail 面只承诺
10
+ * content 五类,新 core 帧类型先经这里显式收编再出 wire)。 */
4
11
  export declare function projectTailFrame(e: Record<string, unknown> & {
5
12
  type?: string;
6
13
  }): SubagentTailFrame | null;
7
14
  export declare class SubagentTailBus {
8
15
  private readonly subs;
16
+ /** 两条 run 腿的 fwdInternals 调用点:帧已投影(projectTailFrame),null 不进来。 */
9
17
  publish(bgAgentId: string, frame: SubagentTailFrame): void;
18
+ /** 有无订阅者(publish 侧的免投影快门:没人听就不投影)。 */
10
19
  hasSubscribers(bgAgentId: string): boolean;
11
20
  subscribe(bgAgentId: string): AsyncIterableIterator<SubagentTailFrame>;
12
21
  }
22
+ /** 进程单例(defaultTaskRegistry 同款姿势):bus 语义本就是进程内 replica-local,两条 run 腿与路由
23
+ * 直接 import,不穿长参数列表;测试自 new 独立实例。 */
13
24
  export declare const defaultSubagentTailBus: SubagentTailBus;
14
25
  //# sourceMappingURL=subagent-tail-bus.d.ts.map
@@ -1,6 +1,30 @@
1
+ /**
2
+ * SubagentTailBus(design/151 S2 server 半场,[1520]{core} 提货单)——per-agent **live tail** 的进程内
3
+ * 分发总线。core 1.370 起后台子代 lane 向宿主 `onForwardEvent` 转发的每一帧带 `bgAgentId`(a* 句柄,
4
+ * TaskEventIdentity 顶层平铺;sync/steer 子代无 tag,wa* 走自己的 observer lane)——两条 run 腿
5
+ * (sync=http/server.ts、bg=runs.ts)的 fwdInternals 按 tag 存在性把帧 publish 进来,
6
+ * `GET /v1/runs/:id/subagents/:handle/stream` 按句柄订阅。
7
+ *
8
+ * 语义边界(与 [1497] A2 的「replay+tail」故事各占一半):
9
+ * - **嵌套归并**(core 复审发现 #5):core recordingForward 在每层 bg 边界覆写 bgAgentId——host wire 上
10
+ * 整棵委托子树的帧一律带**最外层** a* 句柄;对嵌套 a* 行开 tail 流=只有 heartbeat(它的帧归并进外层
11
+ * 句柄的流,按 parentToolCallId 区分)。core JSDoc 补句已 ask。
12
+ * - **live-only**:从订阅时刻起,replica-local(帧只在宿主 run 所在副本产生)——历史/终报走 durable
13
+ * replay 面(`GET .../subagents/:handle/output` + AgentTranscript),meta 帧如实声明。
14
+ * - **有界背压**:每订阅者有界队列(TAIL_QUEUE_CAP),慢消费者丢**最旧**帧并在下一次 drain 前插入一枚
15
+ * `{type:"lagged", dropped}` 诚实标记帧——绝不无界缓冲(死对端=内存增长),绝不静默丢。
16
+ * - **投影在 publish 侧一次**(projectTailFrame):与 sync 主流的 forward 投影同 builder 同纪律
17
+ * (§E1:tool 帧走 whitelist+redact builder,text verbatim=owner 自己的模型输出同信任类,
18
+ * reasoning 过 redactSecrets)——每帧投影一次,N 个订阅者共享同一投影对象(只读约定)。
19
+ *
20
+ * 订阅形 = subscribeWorkflow 同姿势:push 迭代器,消费端显式驱动,断连调 `it.return()` 清订阅
21
+ * (parked next() 不观察 closed 旗——不清理=死订阅者队列永驻)。
22
+ */
1
23
  import { redactSecrets } from "../trace/redact.js";
2
24
  import { taskProgressEventData, toolStartEventData, toolEndEventData } from "../trace/project.js";
3
25
  const TAIL_QUEUE_CAP = 512;
26
+ /** core forward 事件 → wire 投影(sync 主流五分支同源;不认识的帧类型=null 不发——tail 面只承诺
27
+ * content 五类,新 core 帧类型先经这里显式收编再出 wire)。 */
4
28
  export function projectTailFrame(e) {
5
29
  const t = e.type;
6
30
  if (t === "task_progress") {
@@ -8,11 +32,11 @@ export function projectTailFrame(e) {
8
32
  }
9
33
  if (t === "tool_start") {
10
34
  const tsv = e;
11
- return { type: "tool_start", ...toolStartEventData(tsv) };
35
+ return { type: "tool_start", ...toolStartEventData(tsv) }; // label 现由 builder 自带(1.258),外拼冗余已清
12
36
  }
13
37
  if (t === "tool_end") {
14
38
  const te = e;
15
- return { type: "tool_end", ...toolEndEventData(te) };
39
+ return { type: "tool_end", ...toolEndEventData(te) }; // label 现由 builder 自带,外拼冗余已清(同 tool_start 1.258 先例)
16
40
  }
17
41
  if (t === "text_delta") {
18
42
  const td = e;
@@ -26,6 +50,7 @@ export function projectTailFrame(e) {
26
50
  }
27
51
  export class SubagentTailBus {
28
52
  subs = new Map();
53
+ /** 两条 run 腿的 fwdInternals 调用点:帧已投影(projectTailFrame),null 不进来。 */
29
54
  publish(bgAgentId, frame) {
30
55
  const set = this.subs.get(bgAgentId);
31
56
  if (!set)
@@ -41,6 +66,7 @@ export class SubagentTailBus {
41
66
  sub.wake?.();
42
67
  }
43
68
  }
69
+ /** 有无订阅者(publish 侧的免投影快门:没人听就不投影)。 */
44
70
  hasSubscribers(bgAgentId) {
45
71
  return (this.subs.get(bgAgentId)?.size ?? 0) > 0;
46
72
  }
@@ -53,6 +79,9 @@ export class SubagentTailBus {
53
79
  }
54
80
  set.add(sub);
55
81
  const cleanup = () => {
82
+ // 复审 #2(实证):路由对同一迭代器 return() 两次(close 钩+finally,设计如此)——非幂等 cleanup 在
83
+ // 两次调用之间若有新请求 subscribe 同句柄(map 重建新集),第二次会把**新订阅者的集**从 map 删掉
84
+ // (静默只剩 heartbeat)。幂等门+集同一性校验双保险。
56
85
  if (sub.closed)
57
86
  return;
58
87
  sub.closed = true;
@@ -91,5 +120,7 @@ export class SubagentTailBus {
91
120
  return it;
92
121
  }
93
122
  }
123
+ /** 进程单例(defaultTaskRegistry 同款姿势):bus 语义本就是进程内 replica-local,两条 run 腿与路由
124
+ * 直接 import,不穿长参数列表;测试自 new 独立实例。 */
94
125
  export const defaultSubagentTailBus = new SubagentTailBus();
95
126
  //# sourceMappingURL=subagent-tail-bus.js.map
@@ -1,5 +1,26 @@
1
+ /**
2
+ * Fleet worker-side wiring(announce/heartbeat + usage 批报;契约 = registry-core 0.1.48+
3
+ * `/fleet`,center 端点 = sema-registry `/api/fleet/*`)。设计要点:
4
+ * - **可选分层(D3)**:仅当 center 已配置(sema-registry lane 的 baseUrl+token+worker)∧ `FLEET_ADVERTISE_ADDRESS`
5
+ * 显式声明时才启动 —— 不配 center 的部署零行为变化。address 不自猜(k8s pod IP / docker alias / 127.0.0.1:port
6
+ * 只有部署环境自己知道,故用显式 env)。
7
+ * - **announce=注册=心跳同形状幂等 upsert**:boot 后 POST 一次 + 每 heartbeatMs 续;`ready = bootDone ∧ !draining`。
8
+ * - **draining 翻转即刻再 announce**(第一时间自摘流,比任何观测都快);退出前 DELETE(显式注销,幂等)。
9
+ * - **usage 批报**:tracer 的 `brain.call` 已带 ALS principal —— FleetUsageAccumulator 按 principal×model
10
+ * 累计,每窗口(默认 60s,半开 [windowStartMs, windowEndMs))POST /api/fleet/usage。幂等键
11
+ * (worker,instanceId,windowStartMs) 重发安全;**发送失败 → merge 回累计器**,并入下一窗(失败窗从未入账,
12
+ * 向前合并不会双计 —— 只延迟,不丢量)。
13
+ * - 全部 fire-and-forget + swallow-guarded:fleet 面是运维旁路,绝不影响任务面;网络错误只 warn 一次/连败类。
14
+ */
1
15
  import { UsageReport } from "@sema-agent/registry-core/fleet";
16
+ /** Bound on distinct principal×model keys per window — a runaway/multi-tenant burst collapses into
17
+ * `__other__` instead of growing unbounded (same posture as budget.ts cardinalityGuard). */
2
18
  export declare const FLEET_USAGE_KEY_CAP = 1024;
19
+ /**
20
+ * Per-window principal×model usage accumulator, fed from the tracer's `brain.call` hook (which carries the
21
+ * ALS principal — reaches council/team sub-task spend too, same attribution point costQuota uses). Sync,
22
+ * never throws (TracerHook contract).
23
+ */
3
24
  export declare class FleetUsageAccumulator {
4
25
  private cells;
5
26
  private runsSeen;
@@ -10,7 +31,10 @@ export declare class FleetUsageAccumulator {
10
31
  weightedTokens?: number;
11
32
  quotaWeightAtUse?: number;
12
33
  }): void;
34
+ /** Drain the window into UsageReport entries and RESET. Empty window → []. */
13
35
  drain(): UsageReport["entries"];
36
+ /** Merge a FAILED batch back (delivery error → carry the amounts into the next window; never double-counts
37
+ * because the failed window was never recorded center-side). */
14
38
  mergeBack(entries: UsageReport["entries"]): void;
15
39
  get size(): number;
16
40
  }
@@ -21,8 +45,10 @@ export interface FleetClientOpts {
21
45
  worker: string;
22
46
  };
23
47
  instanceId: string;
48
+ /** Reachable base URL of THIS instance — the operator's explicit declaration (`FLEET_ADVERTISE_ADDRESS`). */
24
49
  advertiseAddress: string;
25
50
  version: string;
51
+ /** Live drain flag (drainState) — read at every announce. */
26
52
  isDraining: () => boolean;
27
53
  usage?: FleetUsageAccumulator;
28
54
  heartbeatMs?: number;
@@ -31,13 +57,25 @@ export interface FleetClientOpts {
31
57
  info: (m: string, d?: Record<string, unknown>) => void;
32
58
  warn: (m: string, d?: Record<string, unknown>) => void;
33
59
  };
60
+ /** Injectable for tests. */
34
61
  fetchImpl?: typeof fetch;
35
62
  }
36
63
  export interface FleetClient {
64
+ /** Immediate out-of-cycle announce — call when `draining` flips (self-remove from routing FIRST). */
37
65
  announceNow: () => Promise<void>;
66
+ /** Stop timers + best-effort DELETE deregistration (bounded; never throws). */
38
67
  stop: () => Promise<void>;
39
68
  }
69
+ /**
70
+ * Start the worker-side fleet loops. Caller has already gated on "center configured ∧ advertise address set"
71
+ * (startFleetClientFromEnv below) — this function assumes a complete opts.
72
+ */
40
73
  export declare function startFleetClient(opts: FleetClientOpts): FleetClient;
74
+ /**
75
+ * Env/config gate (D3 可选分层): start ONLY when the sema-registry lane is configured (baseUrl+token+worker)
76
+ * AND the operator explicitly declared this instance's reachable address. Anything missing → undefined (zero
77
+ * behavior change for non-fleet deployments); worker missing is warned when the rest is present (half-configured).
78
+ */
41
79
  export declare function startFleetClientFromEnv(cfg: {
42
80
  configCenter?: {
43
81
  baseUrl: string;
@@ -1,10 +1,31 @@
1
+ /**
2
+ * Fleet worker-side wiring(announce/heartbeat + usage 批报;契约 = registry-core 0.1.48+
3
+ * `/fleet`,center 端点 = sema-registry `/api/fleet/*`)。设计要点:
4
+ * - **可选分层(D3)**:仅当 center 已配置(sema-registry lane 的 baseUrl+token+worker)∧ `FLEET_ADVERTISE_ADDRESS`
5
+ * 显式声明时才启动 —— 不配 center 的部署零行为变化。address 不自猜(k8s pod IP / docker alias / 127.0.0.1:port
6
+ * 只有部署环境自己知道,故用显式 env)。
7
+ * - **announce=注册=心跳同形状幂等 upsert**:boot 后 POST 一次 + 每 heartbeatMs 续;`ready = bootDone ∧ !draining`。
8
+ * - **draining 翻转即刻再 announce**(第一时间自摘流,比任何观测都快);退出前 DELETE(显式注销,幂等)。
9
+ * - **usage 批报**:tracer 的 `brain.call` 已带 ALS principal —— FleetUsageAccumulator 按 principal×model
10
+ * 累计,每窗口(默认 60s,半开 [windowStartMs, windowEndMs))POST /api/fleet/usage。幂等键
11
+ * (worker,instanceId,windowStartMs) 重发安全;**发送失败 → merge 回累计器**,并入下一窗(失败窗从未入账,
12
+ * 向前合并不会双计 —— 只延迟,不丢量)。
13
+ * - 全部 fire-and-forget + swallow-guarded:fleet 面是运维旁路,绝不影响任务面;网络错误只 warn 一次/连败类。
14
+ */
1
15
  import { InstanceAnnouncement, UsageReport, DEFAULT_HEARTBEAT_MS } from "@sema-agent/registry-core/fleet";
16
+ /** Bound on distinct principal×model keys per window — a runaway/multi-tenant burst collapses into
17
+ * `__other__` instead of growing unbounded (same posture as budget.ts cardinalityGuard). */
2
18
  export const FLEET_USAGE_KEY_CAP = 1024;
19
+ /**
20
+ * Per-window principal×model usage accumulator, fed from the tracer's `brain.call` hook (which carries the
21
+ * ALS principal — reaches council/team sub-task spend too, same attribution point costQuota uses). Sync,
22
+ * never throws (TracerHook contract).
23
+ */
3
24
  export class FleetUsageAccumulator {
4
- cells = new Map();
5
- runsSeen = new Set();
25
+ cells = new Map(); // key = principal <NUL> model
26
+ runsSeen = new Set(); // taskId per window → runs count (first brain.call of a run in this window)
6
27
  record(principal, model, taskId, d) {
7
- const p = principal ?? "__anonymous__";
28
+ const p = principal ?? "__anonymous__"; // single-user turnkey: no principal — still meter, under a stable bucket
8
29
  let key = `${p}\u0000${model}`;
9
30
  if (!this.cells.has(key) && this.cells.size >= FLEET_USAGE_KEY_CAP)
10
31
  key = `__other__\u0000__other__`;
@@ -18,7 +39,7 @@ export class FleetUsageAccumulator {
18
39
  cur.costMicroUsd += d.costMicroUsd;
19
40
  cur.weightedTokens += d.weightedTokens ?? 0;
20
41
  if (d.quotaWeightAtUse !== undefined)
21
- cur.quotaWeightAtUse = d.quotaWeightAtUse;
42
+ cur.quotaWeightAtUse = d.quotaWeightAtUse; // 审计尾迹=最新倍率(窗口内基本恒定)
22
43
  if (firstOfRun)
23
44
  cur.runs += 1;
24
45
  }
@@ -26,6 +47,7 @@ export class FleetUsageAccumulator {
26
47
  this.cells.set(key, { inputTokens: d.inputTokens, outputTokens: d.outputTokens, costMicroUsd: d.costMicroUsd, weightedTokens: d.weightedTokens ?? 0, quotaWeightAtUse: d.quotaWeightAtUse ?? 1, runs: firstOfRun ? 1 : 0 });
27
48
  }
28
49
  }
50
+ /** Drain the window into UsageReport entries and RESET. Empty window → []. */
29
51
  drain() {
30
52
  const out = [];
31
53
  for (const [key, c] of this.cells) {
@@ -36,6 +58,8 @@ export class FleetUsageAccumulator {
36
58
  this.runsSeen.clear();
37
59
  return out;
38
60
  }
61
+ /** Merge a FAILED batch back (delivery error → carry the amounts into the next window; never double-counts
62
+ * because the failed window was never recorded center-side). */
39
63
  mergeBack(entries) {
40
64
  for (const e of entries) {
41
65
  let key = `${e.principal}\u0000${e.model}`;
@@ -62,6 +86,10 @@ export class FleetUsageAccumulator {
62
86
  return this.cells.size;
63
87
  }
64
88
  }
89
+ /**
90
+ * Start the worker-side fleet loops. Caller has already gated on "center configured ∧ advertise address set"
91
+ * (startFleetClientFromEnv below) — this function assumes a complete opts.
92
+ */
65
93
  export function startFleetClient(opts) {
66
94
  const f = opts.fetchImpl ?? fetch;
67
95
  const heartbeatMs = opts.heartbeatMs ?? DEFAULT_HEARTBEAT_MS;
@@ -69,7 +97,7 @@ export function startFleetClient(opts) {
69
97
  const base = opts.center.baseUrl.replace(/\/+$/, "");
70
98
  const headers = { authorization: `Bearer ${opts.center.token}`, "content-type": "application/json" };
71
99
  let stopped = false;
72
- let failStreak = 0;
100
+ let failStreak = 0; // warn once per failure streak, not per tick (a down center must not spam logs)
73
101
  const announceNow = async () => {
74
102
  const body = {
75
103
  instanceId: opts.instanceId,
@@ -101,9 +129,9 @@ export function startFleetClient(opts) {
101
129
  const windowEndMs = Date.now();
102
130
  const entries = opts.usage.drain();
103
131
  const start = windowStartMs;
104
- windowStartMs = windowEndMs;
132
+ windowStartMs = windowEndMs; // half-open [start, end) — the next window starts exactly where this one ended
105
133
  if (entries.length === 0)
106
- return;
134
+ return; // nothing accrued — skip the POST entirely
107
135
  const report = { worker: opts.center.worker, instanceId: opts.instanceId, windowStartMs: start, windowEndMs, entries };
108
136
  try {
109
137
  const res = await f(`${base}/api/fleet/usage`, { method: "POST", headers, body: JSON.stringify({ reports: [report] }) });
@@ -111,11 +139,12 @@ export function startFleetClient(opts) {
111
139
  throw new Error(`usage ${res.status}`);
112
140
  }
113
141
  catch (err) {
142
+ // Delivery failed → the window was never recorded center-side; carry the amounts forward (no loss, no double).
114
143
  opts.usage.mergeBack(entries);
115
144
  opts.logger?.warn("fleet_usage_report_failed", { error: err instanceof Error ? err.message : String(err), entries: entries.length });
116
145
  }
117
146
  };
118
- void announceNow();
147
+ void announceNow(); // boot announce (registration = first heartbeat)
119
148
  const hb = setInterval(() => void announceNow(), heartbeatMs);
120
149
  hb.unref?.();
121
150
  const uw = opts.usage ? setInterval(() => void flushUsage(), usageWindowMs) : undefined;
@@ -127,15 +156,21 @@ export function startFleetClient(opts) {
127
156
  clearInterval(hb);
128
157
  if (uw)
129
158
  clearInterval(uw);
130
- await flushUsage();
159
+ await flushUsage(); // final partial window — best-effort
131
160
  try {
132
161
  await f(`${base}/api/fleet/instances`, { method: "DELETE", headers, body: JSON.stringify({ instanceId: opts.instanceId, worker: opts.center.worker }) });
133
162
  }
134
163
  catch {
164
+ /* deregistration is best-effort — staleness (2× heartbeatMs) reaps us anyway */
135
165
  }
136
166
  };
137
167
  return { announceNow, stop };
138
168
  }
169
+ /**
170
+ * Env/config gate (D3 可选分层): start ONLY when the sema-registry lane is configured (baseUrl+token+worker)
171
+ * AND the operator explicitly declared this instance's reachable address. Anything missing → undefined (zero
172
+ * behavior change for non-fleet deployments); worker missing is warned when the rest is present (half-configured).
173
+ */
139
174
  export function startFleetClientFromEnv(cfg, opts) {
140
175
  const cc = cfg.configCenter;
141
176
  const address = opts.advertiseAddress ?? process.env.FLEET_ADVERTISE_ADDRESS;
@@ -1,8 +1,40 @@
1
+ /**
2
+ * Fleet worker-side QUOTA-LEASE consumption(调度框架 D4=AP 模式的 worker 半场;
3
+ * 契约 = registry-core `/fleet` QuotaLease + center `POST /api/fleet/leases`,center 侧已实装并经
4
+ * chaos 测试验证)。
5
+ *
6
+ * ## 模型(roaming/CDN)
7
+ * center 把某 principal 全局预算的一片(默认 $5 slice / 1h TTL)预授权给 ONE worker;worker 本地扣减
8
+ * (`recordSpend`,零 per-call 往返),`shouldRenewLease`(任一维度 80% 或寿命 80%)提前后台续租;center 用
9
+ * usage 批报事后单调对账(`/api/fleet/usage` 入库顺手 reconcile —— worker 不需要单独上报 consumed)。
10
+ *
11
+ * ## 协商式发现(谁走 lease?)
12
+ * worker 不在本地解析 EntitlementBudget —— 首次 admit 向 center POST,center 用 resolveEntitlement 判:
13
+ * - 200 {lease} → 该 principal 是 lease-enforced,进入本地扣减周期;
14
+ * - 409 "principal is not lease-enforced" → 负缓存 {@link NOT_LEASE_TTL_MS},走既有本地 CostQuota 路径;
15
+ * - 409 `code:"quota_exhausted"` → 提交拒绝(429,镜像 quotaExceeded 姿势),短缓存防打爆 center;
16
+ * - 网络/5xx → **fail-open 放行**(AP 哲学:center 短暂不可达绝不停集群;对账兜底,
17
+ * 过花敞口 ≤ slice 尺寸 —— 正是 D4 承诺的 trade)。
18
+ * 单飞(single-flight):同 principal 并发首触/续租只发一个 RTT。
19
+ *
20
+ * ## 边界(documented,非疏漏)
21
+ * - lease 状态 **in-memory**:worker 重启丢本地 consumed → center 续租时用 reports+monotone guard 补账,
22
+ * 敞口同样 ≤ slice(AP 设计内)。
23
+ * - 409 判别靠 center 返回的结构化 code(两端常量);center 侧变更时此处同步。
24
+ * - 全部 swallow-guarded:lease 面绝不 fault 任务提交路径。
25
+ */
1
26
  import { QuotaLease } from "@sema-agent/registry-core/fleet";
27
+ /** 负缓存 TTL:非 lease-enforced 的 principal 多久后再问一次 center(entitlement 升级为 lease 的收敛上界)。 */
2
28
  export declare const NOT_LEASE_TTL_MS: number;
29
+ /** center 判 budget exhausted 后,多久内的重复提交直接拒绝而不再打 center(防 per-request 打爆)。 */
3
30
  export declare const EXHAUSTED_RETRY_MS: number;
31
+ /** principal 状态表上界(镜像 FLEET_USAGE_KEY_CAP 的姿势):超界丢最旧 —— 被丢的 principal 下次 admit
32
+ * 重新协商,一次多余 RTT,无正确性影响。 */
4
33
  export declare const LEASE_PRINCIPAL_CAP = 4096;
34
+ /** 复审 O1:lease 协商 RTT 的硬上限——leaseDenied 在提交热路径同步 await 它,一个 accept-but-hang 的
35
+ * center 必须迅速塌成 fail-open 而不是拖垮提交。取 2.5s(远小于任何续租余量,略紧于 registry 的 8s)。 */
5
36
  export declare const LEASE_FETCH_TIMEOUT_MS = 2500;
37
+ /** E4 定稿的 409 结构化字段(center verbatim → 我方 429 body verbatim 透传;人话归壳/web)。 */
6
38
  export type QuotaDenyDetail = {
7
39
  windowType?: "fiveHour" | "weekly" | "budget";
8
40
  remaining?: number;
@@ -55,16 +87,30 @@ export declare class FleetLeaseManager {
55
87
  private readonly now;
56
88
  private failStreak;
57
89
  constructor(opts: FleetLeaseOpts);
90
+ /**
91
+ * Admission check for one billed submission. Fast path is synchronous-shaped (live lease / fresh negative
92
+ * cache → no await beyond the microtask); only first-touch / expiry / exhaustion pays a center RTT.
93
+ */
58
94
  admit(principal: string): Promise<LeaseAdmission>;
95
+ /** Local deduction — wired at the SAME tracer `brain.call` point as the usage accumulator (ALS principal),
96
+ * sync + never throws (TracerHook contract). No-op unless the principal currently holds a lease.
97
+ * registry-core 0.6.1 双轴:weightedTokens(加权 tokens 配额轴,weight-at-burn 已在调用方固化)
98
+ * + costMicroUsd($ 轴,轴名沿用 0.5 既定)。任一轴耗尽=leaseExhausted 拒(deny-wins,registry 类型层定死)。 */
59
99
  recordSpend(principal: string | undefined, d: {
60
100
  weightedTokens?: number;
61
101
  costMicroUsd?: number;
62
102
  }): void;
103
+ /** Test/observability hook: the current state kind for a principal (never exposes the token). */
63
104
  peek(principal: string): PrincipalState["kind"] | undefined;
64
105
  private set;
65
106
  private issueOrRenew;
66
107
  private issueOrRenewInner;
67
108
  }
109
+ /**
110
+ * Env/config gate(与 startFleetClientFromEnv 同 D3 分层姿势,但 lease 不需要 FLEET_ADVERTISE_ADDRESS ——
111
+ * 它是出站消费面,不是入站可达性声明):sema-registry lane 配齐(baseUrl+token+worker)即启;任一缺失 →
112
+ * undefined,非 fleet 部署零行为变化。
113
+ */
68
114
  export declare function createFleetLeaseFromEnv(cfg: {
69
115
  configCenter?: {
70
116
  baseUrl: string;
@@ -1,17 +1,48 @@
1
+ /**
2
+ * Fleet worker-side QUOTA-LEASE consumption(调度框架 D4=AP 模式的 worker 半场;
3
+ * 契约 = registry-core `/fleet` QuotaLease + center `POST /api/fleet/leases`,center 侧已实装并经
4
+ * chaos 测试验证)。
5
+ *
6
+ * ## 模型(roaming/CDN)
7
+ * center 把某 principal 全局预算的一片(默认 $5 slice / 1h TTL)预授权给 ONE worker;worker 本地扣减
8
+ * (`recordSpend`,零 per-call 往返),`shouldRenewLease`(任一维度 80% 或寿命 80%)提前后台续租;center 用
9
+ * usage 批报事后单调对账(`/api/fleet/usage` 入库顺手 reconcile —— worker 不需要单独上报 consumed)。
10
+ *
11
+ * ## 协商式发现(谁走 lease?)
12
+ * worker 不在本地解析 EntitlementBudget —— 首次 admit 向 center POST,center 用 resolveEntitlement 判:
13
+ * - 200 {lease} → 该 principal 是 lease-enforced,进入本地扣减周期;
14
+ * - 409 "principal is not lease-enforced" → 负缓存 {@link NOT_LEASE_TTL_MS},走既有本地 CostQuota 路径;
15
+ * - 409 `code:"quota_exhausted"` → 提交拒绝(429,镜像 quotaExceeded 姿势),短缓存防打爆 center;
16
+ * - 网络/5xx → **fail-open 放行**(AP 哲学:center 短暂不可达绝不停集群;对账兜底,
17
+ * 过花敞口 ≤ slice 尺寸 —— 正是 D4 承诺的 trade)。
18
+ * 单飞(single-flight):同 principal 并发首触/续租只发一个 RTT。
19
+ *
20
+ * ## 边界(documented,非疏漏)
21
+ * - lease 状态 **in-memory**:worker 重启丢本地 consumed → center 续租时用 reports+monotone guard 补账,
22
+ * 敞口同样 ≤ slice(AP 设计内)。
23
+ * - 409 判别靠 center 返回的结构化 code(两端常量);center 侧变更时此处同步。
24
+ * - 全部 swallow-guarded:lease 面绝不 fault 任务提交路径。
25
+ */
1
26
  import { QuotaLease, leaseExhausted, shouldRenewLease } from "@sema-agent/registry-core/fleet";
27
+ /** 负缓存 TTL:非 lease-enforced 的 principal 多久后再问一次 center(entitlement 升级为 lease 的收敛上界)。 */
2
28
  export const NOT_LEASE_TTL_MS = 10 * 60 * 1000;
29
+ /** center 判 budget exhausted 后,多久内的重复提交直接拒绝而不再打 center(防 per-request 打爆)。 */
3
30
  export const EXHAUSTED_RETRY_MS = 30 * 1000;
31
+ /** principal 状态表上界(镜像 FLEET_USAGE_KEY_CAP 的姿势):超界丢最旧 —— 被丢的 principal 下次 admit
32
+ * 重新协商,一次多余 RTT,无正确性影响。 */
4
33
  export const LEASE_PRINCIPAL_CAP = 4096;
34
+ /** 复审 O1:lease 协商 RTT 的硬上限——leaseDenied 在提交热路径同步 await 它,一个 accept-but-hang 的
35
+ * center 必须迅速塌成 fail-open 而不是拖垮提交。取 2.5s(远小于任何续租余量,略紧于 registry 的 8s)。 */
5
36
  export const LEASE_FETCH_TIMEOUT_MS = 2500;
6
37
  export class FleetLeaseManager {
7
38
  opts;
8
39
  state = new Map();
9
- inflight = new Map();
40
+ inflight = new Map(); // single-flight issue/renew per principal
10
41
  f;
11
42
  base;
12
43
  headers;
13
44
  now;
14
- failStreak = 0;
45
+ failStreak = 0; // warn once per outage streak (mirrors fleet-client)
15
46
  constructor(opts) {
16
47
  this.opts = opts;
17
48
  this.f = opts.fetchImpl ?? fetch;
@@ -19,6 +50,10 @@ export class FleetLeaseManager {
19
50
  this.headers = { authorization: `Bearer ${opts.center.token}`, "content-type": "application/json" };
20
51
  this.now = opts.now ?? Date.now;
21
52
  }
53
+ /**
54
+ * Admission check for one billed submission. Fast path is synchronous-shaped (live lease / fresh negative
55
+ * cache → no await beyond the microtask); only first-touch / expiry / exhaustion pays a center RTT.
56
+ */
22
57
  async admit(principal) {
23
58
  const now = this.now();
24
59
  const st = this.state.get(principal);
@@ -28,12 +63,18 @@ export class FleetLeaseManager {
28
63
  return { ok: false, reason: "budget_exhausted", retryAfterSec: Math.ceil((st.until - now) / 1000), ...(st.detail ? { detail: st.detail } : {}) };
29
64
  }
30
65
  if (st?.kind === "lease" && !leaseExhausted(st.lease, now)) {
66
+ // Renew EARLY in the background so the refresh RTT overlaps remaining headroom (never blocks a call).
31
67
  if (shouldRenewLease(st.lease, now))
32
68
  void this.issueOrRenew(principal).catch(() => undefined);
33
69
  return { ok: true };
34
70
  }
71
+ // No usable state → negotiate with center (single-flight; blocks THIS submission only).
35
72
  return this.issueOrRenew(principal);
36
73
  }
74
+ /** Local deduction — wired at the SAME tracer `brain.call` point as the usage accumulator (ALS principal),
75
+ * sync + never throws (TracerHook contract). No-op unless the principal currently holds a lease.
76
+ * registry-core 0.6.1 双轴:weightedTokens(加权 tokens 配额轴,weight-at-burn 已在调用方固化)
77
+ * + costMicroUsd($ 轴,轴名沿用 0.5 既定)。任一轴耗尽=leaseExhausted 拒(deny-wins,registry 类型层定死)。 */
37
78
  recordSpend(principal, d) {
38
79
  if (!principal)
39
80
  return;
@@ -43,15 +84,16 @@ export class FleetLeaseManager {
43
84
  st.lease.consumed.weightedTokens += d.weightedTokens ?? 0;
44
85
  st.lease.consumed.costMicroUsd += d.costMicroUsd ?? 0;
45
86
  }
87
+ /** Test/observability hook: the current state kind for a principal (never exposes the token). */
46
88
  peek(principal) {
47
89
  return this.state.get(principal)?.kind;
48
90
  }
49
91
  set(principal, st) {
50
92
  if (!this.state.has(principal) && this.state.size >= LEASE_PRINCIPAL_CAP) {
51
- const oldest = this.state.keys().next().value;
93
+ const oldest = this.state.keys().next().value; // insertion order ≈ LRU-enough for a cap backstop
52
94
  this.state.delete(oldest);
53
95
  }
54
- this.state.delete(principal);
96
+ this.state.delete(principal); // re-insert at tail
55
97
  this.state.set(principal, st);
56
98
  }
57
99
  issueOrRenew(principal) {
@@ -64,6 +106,11 @@ export class FleetLeaseManager {
64
106
  }
65
107
  async issueOrRenewInner(principal) {
66
108
  try {
109
+ // 🔴 复审 O1(Opus,3 镜头独立命中):BOUND the negotiation RTT. leaseDenied awaits this on the SUBMISSION
110
+ // hot path (11 sites), so a center that ACCEPTS the TCP connection but never responds (brownout/half-open LB —
111
+ // exactly the outage AP is meant to ride out) would otherwise hang up to undici's ~300s default headersTimeout
112
+ // before the fail-open catch fires, stalling every first-touch/expired principal's submissions. A short abort
113
+ // lands in the catch below → prompt fail-open. Matches the codebase's outbound-to-center timeout convention.
67
114
  const res = await this.f(`${this.base}/api/fleet/leases`, {
68
115
  method: "POST",
69
116
  headers: this.headers,
@@ -72,7 +119,7 @@ export class FleetLeaseManager {
72
119
  });
73
120
  if (res.status === 200) {
74
121
  const body = (await res.json());
75
- const lease = QuotaLease.parse(body.lease);
122
+ const lease = QuotaLease.parse(body.lease); // zod — a malformed center response fails into the catch (fail-open)
76
123
  this.set(principal, { kind: "lease", lease });
77
124
  if (this.failStreak > 0)
78
125
  this.opts.logger?.info?.("fleet_lease_recovered", { after: this.failStreak });
@@ -82,8 +129,16 @@ export class FleetLeaseManager {
82
129
  }
83
130
  if (res.status === 409) {
84
131
  const body = (await res.json().catch(() => ({})));
132
+ // 🔴 复审 O3(Opus):discriminate on a POSITIVE exhaustion match; ANY OTHER 409 (incl. a reworded
133
+ // not-lease-enforced, or an unforeseen refusal) defaults to the PASS-THROUGH direction — a center wording
134
+ // drift must not flip legitimate traffic into repeated 429 denial. Failing OPEN on an ambiguous 409 keeps
135
+ // the AP posture (the local CostQuota path still governs); denying is reserved for an explicit exhaustion.
136
+ // typed 唯一语义:`code==="quota_exhausted"`(E4 定稿 typed code)。旧常量
137
+ // `error:"budget exhausted"` 的过渡 fallback 已删——center 侧旧常量已撤,该 fallback 成死分支,已删净。
85
138
  if (body.code === "quota_exhausted") {
86
139
  const until = this.now() + EXHAUSTED_RETRY_MS;
140
+ // E4 结构化字段(windowType/remaining/resetAt/isEstimate/pool)verbatim 缓存进 exhausted 态——
141
+ // EXHAUSTED_RETRY_MS 窗内的重复提交拒绝也带同一 detail(不再打 center),429 body 透传归 HTTP 层。
87
142
  const detail = {
88
143
  ...(body.windowType !== undefined ? { windowType: body.windowType } : {}),
89
144
  ...(body.remaining !== undefined ? { remaining: body.remaining } : {}),
@@ -96,9 +151,16 @@ export class FleetLeaseManager {
96
151
  this.opts.metrics?.inc("fleet_lease_exhausted_total");
97
152
  return { ok: false, reason: "budget_exhausted", retryAfterSec: Math.ceil(EXHAUSTED_RETRY_MS / 1000), ...(hasDetail ? { detail } : {}) };
98
153
  }
154
+ // not-lease-enforced (the common case) OR any other 409 → local CostQuota path governs this principal.
99
155
  this.set(principal, { kind: "not-lease", until: this.now() + NOT_LEASE_TTL_MS });
100
156
  return { ok: true };
101
157
  }
158
+ // 🔴 复审 O2(Opus):an auth/config error (401/403/400) is operator MISCONFIG (expired service token, wrong
159
+ // worker id, URL drift) — NOT an availability event. Failing open silently would disable budget enforcement
160
+ // indefinitely (a stealth bypass) with only a once-per-streak warn. Fail open STILL (never lock a tenant out
161
+ // on a token blip) but make it LOUD + observable: a dedicated metric + a warn EVERY occurrence (not deduped),
162
+ // and DON'T cache — so a persistent misconfig re-warns on every admit and can't hide. No negotiated state is
163
+ // recorded, so recovery is immediate once the config is fixed.
102
164
  if (res.status === 401 || res.status === 403 || res.status === 400) {
103
165
  this.opts.logger?.warn?.("fleet_lease_auth_error_fail_open", { status: res.status, principal, note: "center rejected the lease request — check the service token / worker id / center URL (budget NOT enforced until fixed)" });
104
166
  this.opts.metrics?.inc("fleet_lease_auth_error_total", { status: String(res.status) });
@@ -107,6 +169,7 @@ export class FleetLeaseManager {
107
169
  throw new Error(`lease ${res.status}`);
108
170
  }
109
171
  catch (err) {
172
+ // center unreachable / 5xx / timeout / malformed → FAIL-OPEN (AP posture): admit, keep whatever state we had.
110
173
  this.failStreak += 1;
111
174
  if (this.failStreak === 1)
112
175
  this.opts.logger?.warn?.("fleet_lease_unavailable_fail_open", { error: err instanceof Error ? err.message : String(err) });
@@ -115,6 +178,11 @@ export class FleetLeaseManager {
115
178
  }
116
179
  }
117
180
  }
181
+ /**
182
+ * Env/config gate(与 startFleetClientFromEnv 同 D3 分层姿势,但 lease 不需要 FLEET_ADVERTISE_ADDRESS ——
183
+ * 它是出站消费面,不是入站可达性声明):sema-registry lane 配齐(baseUrl+token+worker)即启;任一缺失 →
184
+ * undefined,非 fleet 部署零行为变化。
185
+ */
118
186
  export function createFleetLeaseFromEnv(cfg, opts) {
119
187
  const cc = cfg.configCenter;
120
188
  if (!cc?.baseUrl || !cc.token || !cc.worker)
@@ -1,4 +1,5 @@
1
1
  import type { SessionTreeEntry } from "@sema-agent/core";
2
+ /** 渲染结果。**判别式**:证据不足时调用方拿不到 `text`,想用也用不了(见顶注)。 */
2
3
  export type BranchTranscript = {
3
4
  sufficient: true;
4
5
  text: string;
@@ -8,7 +9,14 @@ export type BranchTranscript = {
8
9
  sufficient: false;
9
10
  reason: "no-entries" | "nothing-renderable" | "empty-after-render";
10
11
  };
12
+ /** 单次评估送进模型的 transcript 字符上限。超出保留**尾部**(最近的对话对"条件是否已达成"更相关)。 */
11
13
  export declare const BRANCH_TRANSCRIPT_MAX_CHARS = 60000;
14
+ /**
15
+ * 渲染成 transcript。
16
+ *
17
+ * ⚠️ **compaction 的 summary 也算证据**:一次压缩之后,早期内容**只**活在那段摘要里 ——
18
+ * 把它滤掉等于亲手制造「证据不足」(而那正好会被判成"拦")。
19
+ */
12
20
  export declare function renderBranchTranscript(entries: readonly SessionTreeEntry[] | undefined, opts?: {
13
21
  maxChars?: number;
14
22
  }): BranchTranscript;
@@ -1,5 +1,30 @@
1
+ /**
2
+ * 把 core 的 `StopHookContext.getBranch()` 交出来的 **entries** 渲染成评估者能读的 transcript。
3
+ *
4
+ * ── 为什么渲染这件事本身带一条安全判据 ──────────────────────────────────────────────────────────
5
+ * CC 的条件评估提示词里有这一句(我从语料逐字核过,见 `cc-stop-prompt.ts`):
6
+ * > If the transcript does not contain clear evidence that the condition is satisfied, return
7
+ * > `{"ok": false, "reason": "insufficient evidence in transcript"}`.
8
+ * 而 Stop 钩子的 `ok:false` = **拦住停止**。
9
+ * ⇒ **证据面为空时,一个完全守规矩的模型会给出一个格式良好的「拦」** —— 那不是解析失败(解析会成功、
10
+ * 判词有效),所以任何解析层的防线都救不了。**唯一的防线是不进这条路。**
11
+ *
12
+ * 🔴 判据必须挂在**真正决定结果的那个量**上,也就是**最终送进模型的那段文本**,
13
+ * **不是**挂在 `getBranch` 这个访问器的存在性上(core 黑板 [1758] 指出我原设计挂错了位置):
14
+ * · `getBranch` 在、返回 `[]` —— 结构上可能(还没产出条目的分支);
15
+ * · 更常见的一格:**渲染之后为空** —— entries 有,但我这边的过滤条件一条都没命中,
16
+ * 或预算把它截没了。**那是纯自伤,而且每一层看起来都正常。**
17
+ * ⇒ 所以本模块的返回类型是**判别式**的(`sufficient: true | false`),而不是"返回一个字符串,
18
+ * 调用方自己记得判空" —— 后者迟早会有人忘。
19
+ *
20
+ * ── 截断的第二个坑(同源) ──────────────────────────────────────────────────────────────────────
21
+ * **静默截断会自己制造「证据不足」**:证据在被截掉的那一段里,模型如实回 `ok:false` ⇒ 拦。
22
+ * ⇒ 截断时必须在文本里**明说截了**,让模型知道自己看到的是一个后缀,而不是全部。
23
+ */
1
24
  import { redactSecrets } from "../trace/redact.js";
25
+ /** 单次评估送进模型的 transcript 字符上限。超出保留**尾部**(最近的对话对"条件是否已达成"更相关)。 */
2
26
  export const BRANCH_TRANSCRIPT_MAX_CHARS = 60_000;
27
+ /** 从一条 message entry 里抽人类可读文本(只取 text 片段;工具结果等非文本片段不进 transcript)。 */
3
28
  function messageText(entry) {
4
29
  const m = entry.message;
5
30
  if (!m || typeof m.role !== "string")
@@ -18,6 +43,12 @@ function messageText(entry) {
18
43
  const text = parts.join("\n").trim();
19
44
  return text ? { role: m.role, text } : undefined;
20
45
  }
46
+ /**
47
+ * 渲染成 transcript。
48
+ *
49
+ * ⚠️ **compaction 的 summary 也算证据**:一次压缩之后,早期内容**只**活在那段摘要里 ——
50
+ * 把它滤掉等于亲手制造「证据不足」(而那正好会被判成"拦")。
51
+ */
21
52
  export function renderBranchTranscript(entries, opts) {
22
53
  if (!entries || entries.length === 0)
23
54
  return { sufficient: false, reason: "no-entries" };
@@ -38,9 +69,11 @@ export function renderBranchTranscript(entries, opts) {
38
69
  if (lines.length === 0)
39
70
  return { sufficient: false, reason: "nothing-renderable" };
40
71
  const max = opts?.maxChars ?? BRANCH_TRANSCRIPT_MAX_CHARS;
72
+ // UNTRUSTED:transcript 是会话内容,与 fleet 行 / workflow 名同一条脱敏纪律。
41
73
  let text = redactSecrets(lines.join("\n\n"));
42
74
  let truncated = false;
43
75
  if (text.length > max) {
76
+ // 保留**尾部**;并**明说截了** —— 静默截断会让模型把"证据在被截掉那段里"如实报成"证据不足" ⇒ 拦。
44
77
  text = `[earlier turns omitted — this transcript is truncated to the most recent portion]\n\n${text.slice(text.length - max)}`;
45
78
  truncated = true;
46
79
  }