@sema-agent/core 7.48.0 → 7.49.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 (421) hide show
  1. package/CHANGELOG.md +457 -0
  2. package/README.md +2 -2
  3. package/dist/agents/cascade.d.ts +2 -5
  4. package/dist/agents/child-failure.d.ts +20 -0
  5. package/dist/agents/child-failure.js +28 -0
  6. package/dist/agents/cross-session-ref.d.ts +11 -3
  7. package/dist/agents/cross-session-ref.js +6 -0
  8. package/dist/agents/cumulative-stats.d.ts +12 -15
  9. package/dist/agents/cumulative-stats.js +1 -1
  10. package/dist/agents/extra-tool-names.js +1 -1
  11. package/dist/agents/inherited-tool-pool.d.ts +17 -13
  12. package/dist/agents/inherited-tool-pool.js +4 -3
  13. package/dist/agents/peer-session-drain.d.ts +3 -2
  14. package/dist/agents/peer-session-drain.js +5 -4
  15. package/dist/agents/send-message-tool.js +2 -9
  16. package/dist/agents/subagent.d.ts +10 -29
  17. package/dist/agents/subagent.js +65 -53
  18. package/dist/agents/suspend-guard.d.ts +1 -1
  19. package/dist/agents/tool-filter.d.ts +76 -65
  20. package/dist/agents/tool-filter.js +122 -92
  21. package/dist/agents/verify.d.ts +4 -7
  22. package/dist/agents/verify.js +6 -7
  23. package/dist/bench/metrics.d.ts +1 -2
  24. package/dist/brain/anthropic.js +133 -79
  25. package/dist/brain/errors.d.ts +53 -6
  26. package/dist/brain/errors.js +22 -2
  27. package/dist/brain/input-too-long.d.ts +40 -19
  28. package/dist/brain/input-too-long.js +3 -16
  29. package/dist/brain/open-responses.js +19 -10
  30. package/dist/brain/openai.js +123 -32
  31. package/dist/brain/provider-dialect.d.ts +214 -0
  32. package/dist/brain/provider-dialect.js +186 -0
  33. package/dist/brain/request-params.d.ts +27 -8
  34. package/dist/brain/request-params.js +7 -12
  35. package/dist/brain/request-route.d.ts +84 -0
  36. package/dist/brain/request-route.js +41 -0
  37. package/dist/brain/retry.d.ts +8 -0
  38. package/dist/brain/retry.js +10 -4
  39. package/dist/brain/route-adjudicator.d.ts +7 -0
  40. package/dist/brain/route-adjudicator.js +5 -1
  41. package/dist/brain/status-sink.d.ts +20 -0
  42. package/dist/brain/status-sink.js +11 -0
  43. package/dist/brain/stream-engine.d.ts +52 -1
  44. package/dist/brain/stream-engine.js +81 -24
  45. package/dist/brain/stream-shared.d.ts +57 -11
  46. package/dist/brain/stream-shared.js +28 -2
  47. package/dist/core/a2a.d.ts +1 -0
  48. package/dist/core/agent-config-dir.js +3 -2
  49. package/dist/core/allow-entry.d.ts +21 -12
  50. package/dist/core/allow-entry.js +38 -31
  51. package/dist/core/arg-summary.d.ts +21 -28
  52. package/dist/core/arg-summary.js +235 -88
  53. package/dist/core/ask-origin.d.ts +42 -24
  54. package/dist/core/ask-origin.js +18 -13
  55. package/dist/core/auto-mode-prompt-assets.d.ts +2 -2
  56. package/dist/core/auto-mode-prompt-assets.js +1 -1
  57. package/dist/core/auto-mode-prompt.d.ts +11 -1
  58. package/dist/core/auto-mode-prompt.js +13 -10
  59. package/dist/core/auto-mode-rebuild.d.ts +7 -0
  60. package/dist/core/auto-mode-rebuild.js +4 -1
  61. package/dist/core/canonical-json.d.ts +3 -0
  62. package/dist/core/canonical-json.js +2 -1
  63. package/dist/core/checkpoint-requirements.d.ts +892 -0
  64. package/dist/core/checkpoint-requirements.js +333 -0
  65. package/dist/core/checkpoint-store.d.ts +94 -65
  66. package/dist/core/checkpoint-store.js +14 -26
  67. package/dist/core/child-clamp-seats.d.ts +228 -69
  68. package/dist/core/child-clamp-seats.js +211 -17
  69. package/dist/core/classifier-unavailable-arm.d.ts +5 -1
  70. package/dist/core/classifier-unavailable-arm.js +3 -3
  71. package/dist/core/compliance.d.ts +3 -0
  72. package/dist/core/compliance.js +9 -4
  73. package/dist/core/credential-vocabulary.d.ts +140 -0
  74. package/dist/core/credential-vocabulary.js +131 -0
  75. package/dist/core/decision-receipt.js +1 -1
  76. package/dist/core/effective-path-target.d.ts +73 -16
  77. package/dist/core/effective-path-target.js +63 -33
  78. package/dist/core/engine-notice.d.ts +43 -11
  79. package/dist/core/file-history-store.js +2 -2
  80. package/dist/core/fs-write-gate-policy.d.ts +4 -0
  81. package/dist/core/fs-write-gate-policy.js +22 -5
  82. package/dist/core/gate-bounded-await.d.ts +28 -13
  83. package/dist/core/gate-bounded-await.js +41 -4
  84. package/dist/core/gate-fold.d.ts +1 -1
  85. package/dist/core/gate-fold.js +24 -25
  86. package/dist/core/gate-lanes.js +16 -15
  87. package/dist/core/gate-outcome.d.ts +20 -5
  88. package/dist/core/gate-outcome.js +5 -0
  89. package/dist/core/governance-codes.d.ts +11 -4
  90. package/dist/core/governance-codes.js +14 -3
  91. package/dist/core/hooks.d.ts +21 -0
  92. package/dist/core/locked-config.d.ts +8 -0
  93. package/dist/core/locked-config.js +14 -2
  94. package/dist/core/lsp.js +3 -5
  95. package/dist/core/mailbox-store.d.ts +3 -4
  96. package/dist/core/mcp-connection-pool.d.ts +75 -0
  97. package/dist/core/mcp-connection-pool.js +128 -0
  98. package/dist/core/mcp-failure.d.ts +2 -1
  99. package/dist/core/mcp-failure.js +13 -2
  100. package/dist/core/mcp.d.ts +4 -0
  101. package/dist/core/mcp.js +70 -43
  102. package/dist/core/memory-engine/content-origin.js +2 -14
  103. package/dist/core/memory-engine/engine.d.ts +32 -22
  104. package/dist/core/memory-engine/engine.js +103 -55
  105. package/dist/core/memory-engine/file-backend.d.ts +13 -30
  106. package/dist/core/memory-engine/file-backend.js +37 -252
  107. package/dist/core/memory-engine/index.d.ts +1 -1
  108. package/dist/core/memory-engine/index.js +1 -1
  109. package/dist/core/memory-engine/layout.d.ts +139 -9
  110. package/dist/core/memory-engine/layout.js +350 -7
  111. package/dist/core/memory-engine/scope-contract.d.ts +10 -0
  112. package/dist/core/memory-engine/scope-contract.js +8 -0
  113. package/dist/core/memory-engine/session-incarnation.d.ts +14 -4
  114. package/dist/core/memory-engine/session-incarnation.js +5 -2
  115. package/dist/core/memory-engine/types.d.ts +10 -1
  116. package/dist/core/memory.js +5 -17
  117. package/dist/core/model-seat.d.ts +4 -4
  118. package/dist/core/model-seat.js +1 -1
  119. package/dist/core/mounted-mcp.d.ts +57 -0
  120. package/dist/core/mounted-mcp.js +19 -0
  121. package/dist/core/namespaced-rule-name.d.ts +29 -0
  122. package/dist/core/namespaced-rule-name.js +52 -0
  123. package/dist/core/park-selfcheck.d.ts +1 -1
  124. package/dist/core/park-selfcheck.js +16 -6
  125. package/dist/core/path-guard-rows.d.ts +99 -0
  126. package/dist/core/path-guard-rows.js +45 -0
  127. package/dist/core/path-identity.d.ts +22 -16
  128. package/dist/core/path-identity.js +10 -10
  129. package/dist/core/path-rule-binding.d.ts +2 -1
  130. package/dist/core/path-rule-binding.js +3 -1
  131. package/dist/core/pause-registry.d.ts +16 -2
  132. package/dist/core/pause-registry.js +6 -0
  133. package/dist/core/permission-rule-consent.js +0 -7
  134. package/dist/core/permission-rule-model.d.ts +68 -24
  135. package/dist/core/permission-rule-model.js +105 -24
  136. package/dist/core/permission-rule-store.js +2 -2
  137. package/dist/core/permission-rules.d.ts +3 -30
  138. package/dist/core/permission-rules.js +4 -54
  139. package/dist/core/read-root-candidate.d.ts +1 -3
  140. package/dist/core/read-root-candidate.js +4 -15
  141. package/dist/core/real-approval.d.ts +4 -3
  142. package/dist/core/retired-keys.d.ts +13 -0
  143. package/dist/core/retired-keys.js +14 -0
  144. package/dist/core/roles.d.ts +2 -3
  145. package/dist/core/roles.js +15 -6
  146. package/dist/core/runner/assemble-result.d.ts +0 -7
  147. package/dist/core/runner/assemble-result.js +19 -31
  148. package/dist/core/runner/caller-roster.d.ts +78 -0
  149. package/dist/core/runner/caller-roster.js +219 -0
  150. package/dist/core/runner/checkpoint-scope.d.ts +16 -16
  151. package/dist/core/runner/checkpoint-scope.js +2 -2
  152. package/dist/core/runner/child-tree.js +2 -2
  153. package/dist/core/runner/contracts.d.ts +68 -35
  154. package/dist/core/runner/decide-continuation.d.ts +51 -3
  155. package/dist/core/runner/decide-continuation.js +76 -21
  156. package/dist/core/runner/denial-limit-arms.d.ts +17 -5
  157. package/dist/core/runner/denial-limit-arms.js +11 -9
  158. package/dist/core/runner/extra-body-dropped-seat.d.ts +8 -0
  159. package/dist/core/runner/extra-body-dropped-seat.js +22 -0
  160. package/dist/core/runner/finish-reason-seat.d.ts +9 -0
  161. package/dist/core/runner/finish-reason-seat.js +40 -0
  162. package/dist/core/runner/gate-exit.d.ts +44 -32
  163. package/dist/core/runner/gate-exit.js +112 -25
  164. package/dist/core/runner/inherited-ask-grants.js +6 -4
  165. package/dist/core/runner/mcp-redial.d.ts +3 -3
  166. package/dist/core/runner/mcp-redial.js +3 -4
  167. package/dist/core/runner/permission-rule-lanes.d.ts +1 -2
  168. package/dist/core/runner/permission-rule-lanes.js +5 -4
  169. package/dist/core/runner/prepare-artifact.d.ts +4 -0
  170. package/dist/core/runner/prepare-artifact.js +2 -1
  171. package/dist/core/runner/prepare-ask-lane.d.ts +2 -0
  172. package/dist/core/runner/prepare-ask-lane.js +12 -6
  173. package/dist/core/runner/prepare-boundary-parks.d.ts +5 -8
  174. package/dist/core/runner/prepare-boundary-parks.js +4 -7
  175. package/dist/core/runner/prepare-caps-and-workflow.d.ts +11 -15
  176. package/dist/core/runner/prepare-caps-and-workflow.js +19 -27
  177. package/dist/core/runner/prepare-config-doors.d.ts +9 -9
  178. package/dist/core/runner/prepare-config-doors.js +10 -5
  179. package/dist/core/runner/prepare-defer-classify.d.ts +2 -2
  180. package/dist/core/runner/prepare-defer-classify.js +5 -3
  181. package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
  182. package/dist/core/runner/prepare-delegation-surface.js +3 -3
  183. package/dist/core/runner/prepare-gate-stations.d.ts +4 -4
  184. package/dist/core/runner/prepare-gate-stations.js +9 -7
  185. package/dist/core/runner/prepare-hands-readface.d.ts +7 -7
  186. package/dist/core/runner/prepare-hands-readface.js +7 -7
  187. package/dist/core/runner/prepare-inherited-gate.d.ts +7 -6
  188. package/dist/core/runner/prepare-inherited-gate.js +14 -15
  189. package/dist/core/runner/prepare-listings.d.ts +7 -24
  190. package/dist/core/runner/prepare-listings.js +4 -5
  191. package/dist/core/runner/prepare-memory-engine-session.d.ts +2 -0
  192. package/dist/core/runner/prepare-memory-engine-session.js +4 -3
  193. package/dist/core/runner/prepare-memory.d.ts +6 -0
  194. package/dist/core/runner/prepare-memory.js +13 -13
  195. package/dist/core/runner/prepare-offload-wrappers.d.ts +5 -0
  196. package/dist/core/runner/prepare-offload-wrappers.js +3 -3
  197. package/dist/core/runner/prepare-park-ask.d.ts +7 -8
  198. package/dist/core/runner/prepare-park-ask.js +17 -10
  199. package/dist/core/runner/prepare-policy-chain.js +24 -44
  200. package/dist/core/runner/prepare-project-context.d.ts +1 -1
  201. package/dist/core/runner/prepare-project-context.js +3 -4
  202. package/dist/core/runner/prepare-protocol-tools.d.ts +9 -3
  203. package/dist/core/runner/prepare-protocol-tools.js +3 -4
  204. package/dist/core/runner/prepare-run-refs.d.ts +3 -0
  205. package/dist/core/runner/prepare-run-refs.js +2 -1
  206. package/dist/core/runner/prepare-safety-scan.d.ts +4 -8
  207. package/dist/core/runner/prepare-safety-scan.js +1 -2
  208. package/dist/core/runner/prepare-suspend-saga.d.ts +7 -1
  209. package/dist/core/runner/prepare-suspend-saga.js +28 -12
  210. package/dist/core/runner/prepare-task.d.ts +1 -1
  211. package/dist/core/runner/prepare-task.js +67 -56
  212. package/dist/core/runner/prepare-wiring-manifest.d.ts +11 -10
  213. package/dist/core/runner/prepare-wiring-manifest.js +5 -8
  214. package/dist/core/runner/resume-apply.js +7 -14
  215. package/dist/core/runner/resume-checkpoint-screen.js +11 -4
  216. package/dist/core/runner/resume-internals-and-config.js +2 -2
  217. package/dist/core/runner/resume-policy-outcome.js +5 -32
  218. package/dist/core/runner/resume-review-outcome.js +4 -1
  219. package/dist/core/runner/retired-runner-deps.d.ts +6 -0
  220. package/dist/core/runner/retired-runner-deps.js +10 -1
  221. package/dist/core/runner/run-brain-sinks.d.ts +4 -0
  222. package/dist/core/runner/run-brain-sinks.js +5 -2
  223. package/dist/core/runner/run-harness-handlers.js +29 -36
  224. package/dist/core/runner/run-leg.d.ts +0 -2
  225. package/dist/core/runner/run-leg.js +32 -33
  226. package/dist/core/runner/run-terminal-adoption.js +4 -3
  227. package/dist/core/runner/runtask.js +8 -8
  228. package/dist/core/runner/session-rule-policy.js +5 -5
  229. package/dist/core/runner/stream-settle-backstop.js +7 -4
  230. package/dist/core/runner/sub-agent-deny-lists.d.ts +51 -12
  231. package/dist/core/runner/sub-agent-deny-lists.js +111 -80
  232. package/dist/core/runner/terminal-account.d.ts +48 -0
  233. package/dist/core/runner/terminal-account.js +186 -0
  234. package/dist/core/runner/tool-end-body.d.ts +54 -17
  235. package/dist/core/runner/tool-end-body.js +27 -2
  236. package/dist/core/runner/tool-face-overlay.d.ts +3 -1
  237. package/dist/core/runner/tool-face-overlay.js +6 -4
  238. package/dist/core/runner/tool-occurrence.d.ts +106 -0
  239. package/dist/core/runner/tool-occurrence.js +123 -0
  240. package/dist/core/runner/tool-progress-lane.d.ts +16 -8
  241. package/dist/core/runner/tool-progress-lane.js +25 -34
  242. package/dist/core/runner/tool-turn-repair-seat.d.ts +28 -4
  243. package/dist/core/runner/tool-turn-repair-seat.js +36 -13
  244. package/dist/core/runner/turn-attachments.d.ts +1 -1
  245. package/dist/core/runner/write-protection-station.d.ts +21 -9
  246. package/dist/core/runner/write-protection-station.js +20 -17
  247. package/dist/core/runner-deps.d.ts +12 -22
  248. package/dist/core/secret-env.d.ts +16 -5
  249. package/dist/core/secret-env.js +23 -63
  250. package/dist/core/sensitive-path-policy.d.ts +19 -18
  251. package/dist/core/sensitive-path-policy.js +73 -49
  252. package/dist/core/session-reconcile.d.ts +3 -0
  253. package/dist/core/session-reconcile.js +5 -4
  254. package/dist/core/session-store.d.ts +5 -0
  255. package/dist/core/session-store.js +12 -0
  256. package/dist/core/session.d.ts +13 -0
  257. package/dist/core/shared-memory/normalize.d.ts +17 -4
  258. package/dist/core/shared-memory/normalize.js +7 -7
  259. package/dist/core/shell-lexer.js +5 -4
  260. package/dist/core/shell-wrapper-projection.js +1 -1
  261. package/dist/core/skill-grant.js +1 -1
  262. package/dist/core/store-contracts/checkpoint-store-contract.js +13 -0
  263. package/dist/core/store-contracts/mailbox-store-contract.d.ts +7 -14
  264. package/dist/core/store-contracts/session-store-incarnation-contract.d.ts +27 -0
  265. package/dist/core/store-contracts/session-store-incarnation-contract.js +92 -0
  266. package/dist/core/stub-env.d.ts +2 -0
  267. package/dist/core/stub-env.js +1 -0
  268. package/dist/core/synthetic-read-verdict.js +2 -2
  269. package/dist/core/task-event.d.ts +59 -5
  270. package/dist/core/task-result.d.ts +1 -1
  271. package/dist/core/task-spec.d.ts +42 -9
  272. package/dist/core/terminal-cause.d.ts +94 -11
  273. package/dist/core/tighten-task-spec.d.ts +5 -4
  274. package/dist/core/tighten-task-spec.js +20 -25
  275. package/dist/core/tool-catalog-entries.d.ts +5 -7
  276. package/dist/core/tool-catalog-entries.js +14 -15
  277. package/dist/core/tool-face.d.ts +47 -0
  278. package/dist/core/tool-face.js +5 -0
  279. package/dist/core/tool-model-gate.d.ts +5 -5
  280. package/dist/core/tool-name-aliases.d.ts +26 -2
  281. package/dist/core/tool-name-aliases.js +13 -0
  282. package/dist/core/tool-name-list.d.ts +30 -0
  283. package/dist/core/tool-name-list.js +55 -0
  284. package/dist/core/tool-name-readings.d.ts +1 -9
  285. package/dist/core/tool-name-readings.js +1 -3
  286. package/dist/core/tool-policy.d.ts +195 -85
  287. package/dist/core/tool-policy.js +165 -380
  288. package/dist/core/tool-registry.d.ts +44 -1
  289. package/dist/core/tool-registry.js +26 -0
  290. package/dist/core/tool-roster.d.ts +19 -1
  291. package/dist/core/tool-roster.js +21 -2
  292. package/dist/core/tool-spec-members.d.ts +45 -0
  293. package/dist/core/tool-spec-members.js +169 -0
  294. package/dist/core/tool-spec.d.ts +46 -8
  295. package/dist/core/tools.d.ts +6 -2
  296. package/dist/core/tools.js +8 -4
  297. package/dist/core/untrusted-egress.js +29 -26
  298. package/dist/core/untrusted-text.d.ts +13 -10
  299. package/dist/core/untrusted-text.js +6 -44
  300. package/dist/core/workflow-journal-store.d.ts +4 -1
  301. package/dist/core/write-protect.d.ts +65 -29
  302. package/dist/core/write-protect.js +235 -177
  303. package/dist/engine/compaction/compaction.d.ts +2 -2
  304. package/dist/engine/execution-env/node-execution-env.d.ts +5 -23
  305. package/dist/engine/execution-env/node-execution-env.js +16 -38
  306. package/dist/engine/execution-env/symlink-chain.d.ts +23 -0
  307. package/dist/engine/execution-env/symlink-chain.js +32 -0
  308. package/dist/engine/harness/types.d.ts +7 -0
  309. package/dist/engine/llm/tool-turns.d.ts +3 -0
  310. package/dist/engine/llm/tool-turns.js +1 -0
  311. package/dist/engine/llm/types.d.ts +59 -23
  312. package/dist/engine/loop/agent-loop.js +16 -2
  313. package/dist/engine/session/memory-repo.js +11 -3
  314. package/dist/engine/session/repo-utils.d.ts +8 -0
  315. package/dist/engine/session/repo-utils.js +13 -0
  316. package/dist/index.d.ts +20 -23
  317. package/dist/index.js +17 -20
  318. package/dist/internal/harness.d.ts +1 -1
  319. package/dist/internal/harness.js +1 -1
  320. package/dist/internal/llm.d.ts +2 -2
  321. package/dist/internal/llm.js +1 -1
  322. package/dist/orchestration/governance-baseline-validity.js +1 -1
  323. package/dist/orchestration/run-spec.js +3 -3
  324. package/dist/orchestration/run-workflow-tool.d.ts +16 -35
  325. package/dist/orchestration/run-workflow-tool.js +38 -78
  326. package/dist/orchestration/workflow-governance.d.ts +21 -25
  327. package/dist/orchestration/workflow-governance.js +38 -78
  328. package/dist/orchestration/workflow-primitives.d.ts +7 -22
  329. package/dist/orchestration/workflow-primitives.js +5 -12
  330. package/dist/orchestration/workflow-types.d.ts +1 -1
  331. package/dist/orchestration/workflow.d.ts +61 -11
  332. package/dist/orchestration/workflow.js +189 -117
  333. package/dist/scenarios/full-body.d.ts +1 -1
  334. package/dist/shell/lex.d.ts +0 -21
  335. package/dist/shell/lex.js +250 -68
  336. package/dist/shell/shell-words.d.ts +35 -0
  337. package/dist/shell/shell-words.js +65 -0
  338. package/dist/stores/file/checkpoint-store.d.ts +5 -5
  339. package/dist/stores/file/checkpoint-store.js +5 -2
  340. package/dist/stores/file/index.d.ts +0 -8
  341. package/dist/stores/file/index.js +0 -12
  342. package/dist/stores/file/session-store.d.ts +3 -0
  343. package/dist/stores/file/session-store.js +44 -19
  344. package/dist/tools/artifact/artifact-tool.js +2 -0
  345. package/dist/tools/fs/bash-program-position.d.ts +12 -4
  346. package/dist/tools/fs/bash-program-position.js +32 -9
  347. package/dist/tools/fs/bash-readonly-classifier.d.ts +1 -1
  348. package/dist/tools/fs/bash-readonly-classifier.js +8 -7
  349. package/dist/tools/fs/containment-face.d.ts +4 -0
  350. package/dist/tools/fs/containment-face.js +3 -0
  351. package/dist/tools/fs/fs-shared.d.ts +10 -0
  352. package/dist/tools/fs/fs-shared.js +18 -0
  353. package/dist/tools/fs/fs-write.js +4 -2
  354. package/dist/tools/fs/index.d.ts +1 -1
  355. package/dist/tools/fs/program-read-model.d.ts +46 -20
  356. package/dist/tools/fs/program-read-model.js +50 -20
  357. package/dist/tools/fs/program-read-model.rows.d.ts +0 -14
  358. package/dist/tools/fs/program-read-model.rows.js +16 -15
  359. package/dist/tools/fs/read-deny-home.d.ts +33 -47
  360. package/dist/tools/fs/read-deny-home.js +35 -49
  361. package/dist/tools/fs/read-deny.d.ts +23 -22
  362. package/dist/tools/fs/read-deny.js +114 -89
  363. package/dist/tools/fs/removal-targets.d.ts +56 -23
  364. package/dist/tools/fs/removal-targets.js +65 -87
  365. package/dist/tools/fs/safety.d.ts +29 -22
  366. package/dist/tools/fs/safety.js +17 -11
  367. package/dist/tools/fs/search.js +10 -8
  368. package/dist/tools/fs/shell-read-argv.js +1 -1
  369. package/dist/tools/fs/shell-read-bindings.d.ts +169 -37
  370. package/dist/tools/fs/shell-read-bindings.js +324 -86
  371. package/dist/tools/fs/shell-read-builtins.d.ts +35 -0
  372. package/dist/tools/fs/shell-read-builtins.js +43 -0
  373. package/dist/tools/fs/shell-read-check.d.ts +15 -1
  374. package/dist/tools/fs/shell-read-check.js +67 -43
  375. package/dist/tools/fs/shell-read-establish.js +6 -6
  376. package/dist/tools/fs/shell-read-functions.d.ts +22 -0
  377. package/dist/tools/fs/shell-read-functions.js +29 -0
  378. package/dist/tools/fs/shell-read-judge.d.ts +51 -18
  379. package/dist/tools/fs/shell-read-judge.js +40 -4
  380. package/dist/tools/fs/shell-read-plan.d.ts +12 -6
  381. package/dist/tools/fs/shell-read-plan.js +118 -113
  382. package/dist/tools/fs/shell-read-start.d.ts +29 -6
  383. package/dist/tools/fs/shell-read-start.js +16 -9
  384. package/dist/tools/fs/shell-read-word.js +4 -0
  385. package/dist/tools/fs/shell-read-workdir.d.ts +156 -0
  386. package/dist/tools/fs/shell-read-workdir.js +281 -0
  387. package/dist/tools/fs/shell-read-write-targets.d.ts +5 -2
  388. package/dist/tools/fs/shell-read-write-targets.js +14 -5
  389. package/dist/tools/fs/shell-reentry-text.d.ts +4 -6
  390. package/dist/tools/fs/shell-reentry-text.js +3 -11
  391. package/dist/tools/task-list.d.ts +1 -2
  392. package/dist/tools/web.js +1 -1
  393. package/package.json +4 -1
  394. package/test/export-surface.snapshot.json +107 -143
  395. package/wire-changes/core@7.49.0.json +4765 -0
  396. package/dist/agents/teacher.d.ts +0 -159
  397. package/dist/agents/teacher.js +0 -577
  398. package/dist/agents/team.d.ts +0 -226
  399. package/dist/agents/team.js +0 -257
  400. package/dist/core/strategy-store.d.ts +0 -238
  401. package/dist/core/strategy-store.js +0 -253
  402. package/dist/orchestration/builtin-workflows.d.ts +0 -133
  403. package/dist/orchestration/builtin-workflows.js +0 -159
  404. package/dist/scenarios/env.d.ts +0 -40
  405. package/dist/scenarios/env.js +0 -39
  406. package/dist/scenarios/scenario-registry.d.ts +0 -110
  407. package/dist/scenarios/scenario-registry.js +0 -140
  408. package/dist/scenarios/teacher-quickstart.d.ts +0 -40
  409. package/dist/scenarios/teacher-quickstart.js +0 -12
  410. package/dist/stores/cc/lockfile.d.ts +0 -10
  411. package/dist/stores/cc/lockfile.js +0 -98
  412. package/dist/stores/cc/mailbox-store.d.ts +0 -20
  413. package/dist/stores/cc/mailbox-store.js +0 -255
  414. package/dist/stores/cc/roster-adapter.d.ts +0 -12
  415. package/dist/stores/cc/roster-adapter.js +0 -117
  416. package/dist/stores/cc/sidecar-transcript.d.ts +0 -97
  417. package/dist/stores/cc/sidecar-transcript.js +0 -264
  418. package/dist/stores/cc/task-list-store.d.ts +0 -2
  419. package/dist/stores/cc/task-list-store.js +0 -125
  420. package/dist/stores/file/strategy-store.d.ts +0 -97
  421. package/dist/stores/file/strategy-store.js +0 -341
@@ -3,13 +3,13 @@ import { randomUUID } from "node:crypto";
3
3
  import { closeSync, constants, createReadStream, mkdtempSync, openSync, readSync, statSync, truncateSync, unlinkSync } from "node:fs";
4
4
  import { access, appendFile, lstat, mkdir, mkdtemp, open, readdir, readFile, readlink, rename, rm, stat, unlink, writeFile, } from "node:fs/promises";
5
5
  import { tmpdir } from "node:os";
6
- import { dirname, isAbsolute, join, resolve, sep } from "node:path";
6
+ import { isAbsolute, join, resolve } from "node:path";
7
7
  import { createInterface } from "node:readline";
8
8
  import { ExecutionError, err, FileError, ok, toError, } from "../harness/types.js";
9
9
  import { killProcessTree, shutdownDebug } from "./kill-tree.js";
10
10
  import { __resetSecretEnvScrubNoticeAnnouncement, announceSecretEnvScrub, inheritEnvPolicyProblem, inheritedHostEnv, scrubSecretEnv } from "../../core/secret-env.js";
11
11
  import { physicalPathOfAsync } from "../../core/physical-path.js";
12
- import { isUncSpelling } from "../../tools/fs/safety.js";
12
+ import { walkSymlinkChain } from "./symlink-chain.js";
13
13
  import { RollingTailBuffer, markTruncated, newStreamCursorState, sliceStreamIncrement, } from "../../core/exec-output-tail.js";
14
14
  import { BackgroundShellError } from "../../core/background-shell.js";
15
15
  import { SchedulerError } from "../../core/scheduler.js";
@@ -42,11 +42,6 @@ function fileKindFromStats(stats) {
42
42
  return undefined;
43
43
  }
44
44
  const HAS_POSIX_MODE_FACE = process.platform !== "win32";
45
- export function anchorAtLinkDir(linkDir, target, separator) {
46
- const endsInSeparator = linkDir.endsWith(separator) || (separator === "\\" && linkDir.endsWith("/"));
47
- return endsInSeparator ? `${linkDir}${target}` : `${linkDir}${separator}${target}`;
48
- }
49
- const SYMLINK_CHAIN_HOP_BOUND = 64;
50
45
  function fileInfoFromStats(path, stats) {
51
46
  const kind = fileKindFromStats(stats);
52
47
  if (!kind) {
@@ -94,6 +89,14 @@ function toFileError(error, path) {
94
89
  }
95
90
  return new FileError("unknown", cause.message, path, cause);
96
91
  }
92
+ async function readLinkTarget(resolved) {
93
+ try {
94
+ return ok(await readlink(resolved));
95
+ }
96
+ catch (error) {
97
+ return err(toFileError(error, resolved));
98
+ }
99
+ }
97
100
  function abortResult(signal, path) {
98
101
  return signal?.aborted ? err(new FileError("aborted", "aborted", path)) : undefined;
99
102
  }
@@ -279,6 +282,10 @@ export class NodeExecutionEnv {
279
282
  get homeDir() {
280
283
  return getShellEnv(this.inheritEnv, this.shellEnv, undefined, () => { }).HOME;
281
284
  }
285
+ get cdPath() {
286
+ const value = getShellEnv(this.inheritEnv, this.shellEnv, undefined, () => { }).CDPATH;
287
+ return value === undefined || value === "" ? [] : value.split(":");
288
+ }
282
289
  shellPath;
283
290
  shellEnv;
284
291
  inheritEnv;
@@ -1024,39 +1031,10 @@ export class NodeExecutionEnv {
1024
1031
  }
1025
1032
  }
1026
1033
  async readLink(path) {
1027
- const resolved = resolvePath(this.cwd, path);
1028
- try {
1029
- return ok(await readlink(resolved));
1030
- }
1031
- catch (error) {
1032
- return err(toFileError(error, resolved));
1033
- }
1034
+ return readLinkTarget(resolvePath(this.cwd, path));
1034
1035
  }
1035
1036
  async canonicalChain(path) {
1036
- const resolved = resolvePath(this.cwd, path);
1037
- const hops = [];
1038
- const seen = new Set([resolved]);
1039
- let cur = resolved;
1040
- for (let hop = 0; hop < SYMLINK_CHAIN_HOP_BOUND; hop++) {
1041
- let target;
1042
- try {
1043
- target = await readlink(cur);
1044
- }
1045
- catch (error) {
1046
- if (isNodeError(error) && (error.code === "EINVAL" || error.code === "ENOENT" || error.code === "ENOTDIR"))
1047
- return ok({ hops });
1048
- return err(toFileError(error, cur));
1049
- }
1050
- const next = isAbsolute(target) ? target : anchorAtLinkDir(dirname(cur), target, sep);
1051
- if (seen.has(next))
1052
- break;
1053
- hops.push(next);
1054
- if (process.platform === "win32" && isUncSpelling(next))
1055
- break;
1056
- seen.add(next);
1057
- cur = next;
1058
- }
1059
- return ok({ hops });
1037
+ return walkSymlinkChain(resolvePath(this.cwd, path), readLinkTarget);
1060
1038
  }
1061
1039
  async exists(path) {
1062
1040
  const result = await this.fileInfo(path);
@@ -0,0 +1,23 @@
1
+ import { type FileError, type Result, type SymlinkChain } from "../harness/types.js";
2
+ /**
3
+ * Anchor a RELATIVE symlink target at its link's own directory, UNFOLDED, with exactly one separator between the two.
4
+ * A root directory (`/`, `C:\`, `\\host\share\`) already ends in its own separator, and a second one mints a spelling
5
+ * (`//private/tmp`) that no guarded row matches; `path.resolve`/`join` would fix the separator and fold `..`, which
6
+ * this walk may not do. `separator` is the one the caller's `dirname` writes (a pure function of its inputs); a
7
+ * backslash terminates only where it IS a separator — on a POSIX tree `/a/b\` is an ordinary name.
8
+ */
9
+ export declare function anchorAtLinkDir(linkDir: string, target: string, separator: string): string;
10
+ /** The walk's bound (the reference CLI's own); the terminal canonicalizer refuses at 16, so this only bounds what is REPORTED. */
11
+ export declare const SYMLINK_CHAIN_MAX_HOPS = 64;
12
+ /** The one-hop primitive (`FileSystem.readLink`'s signature): the target a symlink NAMES, not followed. The walk reads `invalid` / `not_found` / `not_directory` as the end of the chain. */
13
+ export type SymlinkHopReader = (path: string) => Promise<Result<string, FileError>>;
14
+ /**
15
+ * THE leaf symlink chain walk ({@link import("../harness/types.js").FileSystem.canonicalChain}'s answer) over the
16
+ * smallest primitive: `readLink` on `start` (resolved, absolute), then on each target, until a hop is not a link, is
17
+ * absent, repeats, or the bound is reached. A relative target is anchored at its link's directory and never folded
18
+ * (`..` is the filesystem's to resolve in the next lookup: a lexical fold reads `bridge/../next` as `next` and misses
19
+ * every link behind `bridge`). The addressed spelling seeds the cycle table, so it is never a hop of its own chain;
20
+ * on win32 a share-shaped hop is kept and ends the walk unprobed. Any other failure is `err`, never a shortened chain.
21
+ * `NodeExecutionEnv.canonicalChain` is this function over its own read; a non-`node:fs` host supplies its own.
22
+ */
23
+ export declare function walkSymlinkChain(start: string, readLink: SymlinkHopReader): Promise<Result<SymlinkChain, FileError>>;
@@ -0,0 +1,32 @@
1
+ import { dirname, isAbsolute, sep } from "node:path";
2
+ import { isUncSpelling } from "../../tools/fs/safety.js";
3
+ import { err, ok } from "../harness/types.js";
4
+ export function anchorAtLinkDir(linkDir, target, separator) {
5
+ const endsInSeparator = linkDir.endsWith(separator) || (separator === "\\" && linkDir.endsWith("/"));
6
+ return endsInSeparator ? `${linkDir}${target}` : `${linkDir}${separator}${target}`;
7
+ }
8
+ export const SYMLINK_CHAIN_MAX_HOPS = 64;
9
+ export async function walkSymlinkChain(start, readLink) {
10
+ const hops = [];
11
+ const seen = new Set([start]);
12
+ let cur = start;
13
+ for (let hop = 0; hop < SYMLINK_CHAIN_MAX_HOPS; hop++) {
14
+ const read = await readLink(cur);
15
+ if (!read.ok) {
16
+ const code = read.error.code;
17
+ if (code === "invalid" || code === "not_found" || code === "not_directory")
18
+ return ok({ hops });
19
+ return err(read.error);
20
+ }
21
+ const target = read.value;
22
+ const next = isAbsolute(target) ? target : anchorAtLinkDir(dirname(cur), target, sep);
23
+ if (seen.has(next))
24
+ break;
25
+ hops.push(next);
26
+ if (process.platform === "win32" && isUncSpelling(next))
27
+ break;
28
+ seen.add(next);
29
+ cur = next;
30
+ }
31
+ return ok({ hops });
32
+ }
@@ -518,6 +518,8 @@ export interface ExecutionEnv extends FileSystem, Shell {
518
518
  * an absolute path is refused at prepare (`config.execution_env_home_dir_invalid`), never read as absent.
519
519
  */
520
520
  readonly homeDir?: string;
521
+ /** #1554 — the `CDPATH` entries the shell child receives (`[]` = none), or `"unknown"` when the adapter cannot say. */
522
+ readonly cdPath: readonly string[] | "unknown";
521
523
  }
522
524
  /** Base fields shared by append-only session tree entries. */
523
525
  export interface SessionTreeEntryBase {
@@ -868,6 +870,10 @@ export interface SessionMetadata {
868
870
  * {@link SessionPlacementRecord}). Absent on every ordinary (host-lane) session; a repo that does
869
871
  * not understand placement never surfaces it (additive, old readers tolerate). */
870
872
  placement?: SessionPlacementRecord;
873
+ /** WHICH occupant this row is: minted by the repo once when the row comes into existence (create / fork / import onto an absent id), carried by every other write; only compared; absent = UNKNOWN, never backfilled; not wire / model-context material. */
874
+ incarnation?: string;
875
+ /** Fork lineage's OCCUPANT half: the source row's `incarnation` at fork time (the occupant copied, not whoever holds `forkedFrom` later); absent = unknown. */
876
+ forkedFromIncarnation?: string;
871
877
  }
872
878
  export interface JsonlSessionMetadata extends SessionMetadata {
873
879
  cwd: string;
@@ -1030,6 +1036,7 @@ export interface SessionRepo<TMetadata extends SessionMetadata = SessionMetadata
1030
1036
  open(metadata: TMetadata): Promise<Session<TMetadata>>;
1031
1037
  list(options?: TListOptions): Promise<TMetadata[]>;
1032
1038
  delete(metadata: TMetadata): Promise<void>;
1039
+ /** A fork is a NEW row: `options.id` equal to the source's id is refused (`invalid_fork_target`) — onto its source it would mint a new occupant over the source's own transcript. */
1033
1040
  fork(source: TMetadata, options: SessionForkOptions & TCreateOptions): Promise<Session<TMetadata>>;
1034
1041
  /**
1035
1042
  * 2c session-sync: the FULL durable entry log for `sessionId`, oldest-first, with
@@ -83,6 +83,9 @@ export declare const TOOL_TURN_INCOMPLETE_CAUSES: readonly ["truncated", "unname
83
83
  export type ToolTurnIncompleteCause = (typeof TOOL_TURN_INCOMPLETE_CAUSES)[number];
84
84
  /** The causes a brain's stream parse finds — what a turn's own message can report. */
85
85
  export type StreamDropCause = Exclude<ToolTurnIncompleteCause, "missing_result_synthesized">;
86
+ /** The drop causes that can FAIL a turn (dropped calls; a dropped frame only notes a gap): `modelOutputInvalid.cause`. */
87
+ export declare const MODEL_OUTPUT_INVALID_CAUSES: readonly ["truncated", "unnamed"];
88
+ export type ModelOutputInvalidCause = (typeof MODEL_OUTPUT_INVALID_CAUSES)[number];
86
89
  /** One cause a turn's stream dropped content for, and how many calls (or frames) it dropped. */
87
90
  export interface StreamDrop {
88
91
  readonly cause: StreamDropCause;
@@ -9,6 +9,7 @@ export const TOOL_TURN_REPAIR_DROPS = {
9
9
  orphan_result: true,
10
10
  };
11
11
  export const TOOL_TURN_INCOMPLETE_CAUSES = Object.freeze(["truncated", "unnamed", "bad_frame", "missing_result_synthesized"]);
12
+ export const MODEL_OUTPUT_INVALID_CAUSES = Object.freeze(["truncated", "unnamed"]);
12
13
  const STREAM_DROPS_DIAGNOSTIC = "stream_drops";
13
14
  const STREAM_DROP_CAUSES = new Set(["truncated", "unnamed", "bad_frame"]);
14
15
  export function stampStreamDrops(message, drops) {
@@ -1,6 +1,10 @@
1
1
  export type { AssistantMessageDiagnostic, DiagnosticErrorInfo } from "./diagnostics.js";
2
2
  import type { AssistantMessageDiagnostic } from "./diagnostics.js";
3
3
  import type { RepetitionEvent } from "../../brain/repetition.js";
4
+ import type { ProviderCondition, ProviderConditionSource } from "../../brain/provider-dialect.js";
5
+ import type { RequestRoute, RouteCarrierBag, RouteCredentialSource } from "../../brain/request-route.js";
6
+ export type { RouteCredentialSource } from "../../brain/request-route.js";
7
+ import type { ModelOutputInvalidCause } from "./tool-turns.js";
4
8
  export type KnownApi = "openai-completions" | "mistral-conversations" | "openai-responses" | "azure-openai-responses" | "openai-chatgpt-responses" | "anthropic-messages" | "bedrock-converse-stream" | "google-generative-ai" | "google-vertex";
5
9
  export type Api = KnownApi | (string & {});
6
10
  export type KnownImagesApi = "openrouter-images";
@@ -383,6 +387,19 @@ export interface UserMessage {
383
387
  */
384
388
  actor?: ActorAssertion;
385
389
  }
390
+ /** A cut turn's output-cap facts: the lane's own cap stop fired, the output the provider counted, the cap the request
391
+ * carried. The cap cut the call when `capStop` or `outputTokens >= capTokens`. */
392
+ export interface OutputLimit {
393
+ capStop: boolean;
394
+ outputTokens?: number;
395
+ capTokens?: number;
396
+ }
397
+ /** Why a turn's tool calls could not be executed: the drop cause (`truncated` wins over `unnamed`); `outputLimit` rides
398
+ * with `truncated`. */
399
+ export interface ModelOutputInvalid {
400
+ cause: ModelOutputInvalidCause;
401
+ outputLimit?: OutputLimit;
402
+ }
386
403
  export interface AssistantMessage {
387
404
  role: "assistant";
388
405
  content: (TextContent | ThinkingContent | ToolCall)[];
@@ -439,12 +456,24 @@ export interface AssistantMessage {
439
456
  * `error.type`) — e.g. `invalid_request_error`, `context_length_exceeded`. Only meaningful together with
440
457
  * {@link isApiErrorMessage}; provider vocabulary, never an engine closed set.
441
458
  *
442
- * PRESENCE: only beside a 4xx {@link apiErrorStatus} (the provider refused the request as sent) whose envelope stated
443
- * such a word in the provider echo shape (visible ASCII, 1–128 characters). ABSENT otherwise — any other status, a
444
- * plain-text or torn body, an envelope with neither member, or a word outside the shape (dropped whole, never
445
- * truncated). The run's `terminal.detail.code` is this value.
459
+ * PRESENCE: beside a 4xx {@link apiErrorStatus} (the provider refused the request as sent) or an in-band error
460
+ * frame (no status), whose envelope stated such a word in the provider echo shape (visible ASCII, 1–128
461
+ * characters). ABSENT otherwise — any other status, a plain-text or torn body, an envelope with neither member, or
462
+ * a word outside the shape (dropped whole, never truncated). The run's `terminal.detail.code` is this value.
446
463
  */
447
464
  apiErrorCode?: string;
465
+ /** The provider-condition verdict of this failure (`PROVIDER_CONDITIONS`, judged off `brain/provider-dialect.ts`),
466
+ * with {@link isApiErrorMessage}; on a 4xx it is also `terminal.detail.providerCondition`. PRESENCE: every failure
467
+ * the provider stated (an HTTP failure status, an in-band error frame); absent ⇒ not judged, read as `unknown`. */
468
+ providerCondition?: ProviderCondition;
469
+ /** Its evidence word, beside it. */
470
+ providerConditionSource?: ProviderConditionSource;
471
+ /** With `quota_exhausted` whose evidence stated it: when the quota lifts (wall-clock epoch ms). */
472
+ providerResetAtMs?: number;
473
+ /** The failing request's route as its brain stated it ({@link RequestRoute}; never a key value or a URL); on a 4xx also
474
+ * `terminal.detail.route`. PRESENCE: beside {@link isApiErrorMessage} on an engine-minted provider failure whose
475
+ * committed request stated one; absent on success, an abort, a refusal minted before any request was built. */
476
+ apiErrorRoute?: RequestRoute;
448
477
  diagnostics?: AssistantMessageDiagnostic[];
449
478
  usage: Usage;
450
479
  /** TB 尸检 T1-5: the provider never delivered a usage frame for this message (e.g. a
@@ -483,15 +512,21 @@ export interface AssistantMessage {
483
512
  * stamping obligation above extends to this member for cuts a Brain can classify structurally,
484
513
  * but unlike the two cut kinds there is no retired fallback: prose detection still works). */
485
514
  errorKind?: "length_empty" | "degenerate" | "input_too_long";
486
- /** design/374 slice 2, the AUTHORITATIVE-NEGATIVE twin of `errorKind: "input_too_long"`: the
487
- * brain's provenance-checked classifier RAN and ruled this failure NOT input-too-long (wrong
488
- * status family, or the provider's own diagnostic envelope states a different error). The
489
- * loop's prompt-too-long recovery treats it as a hard negative and SKIPS its prose fallback —
490
- * a "prompt is too long" sentence reflected inside an unrelated error body must never drive a
491
- * context-shrinking recovery (adversarial-review r1). Absent = classification could not
492
- * establish provenance (prose-only gateway, truncated body, non-classifying custom Brain), and
493
- * the historic prose fallback keeps its reach. Mutually exclusive with the positive stamp. */
515
+ /** The AUTHORITATIVE-NEGATIVE twin of `errorKind: "input_too_long"`: the brain's provenance-checked
516
+ * classifier RAN and ruled this failure NOT input-too-long (wrong status family, or the provider's
517
+ * own envelope states a different error). The loop's prompt-too-long recovery treats it as a hard
518
+ * negative and skips its prose fallback — a "prompt is too long" sentence reflected inside an
519
+ * unrelated error body must never shrink a context. Absent = no provenance (prose-only gateway,
520
+ * non-classifying custom Brain): the prose fallback keeps its reach unless `errorBodyIncomplete`.
521
+ * Mutually exclusive with the positive stamp. */
494
522
  inputTooLongRuledOut?: true;
523
+ /** The provider's error body did not end (cut at the read bound, torn): nothing was read from it — no verdict,
524
+ * `apiErrorCode` or context-limit reading, nor the loop's prose fallback over `errorMessage`; a status reading stands. */
525
+ errorBodyIncomplete?: true;
526
+ /** The turn failed because its tool calls could not be executed ({@link ModelOutputInvalid}) — the structured twin of
527
+ * that `errorMessage` sentence; `terminal.detail` `model_output_invalid` when the turn names the run's result.
528
+ * PRESENCE: only on that `stopReason: "error"` turn (no louder cause won it); never beside {@link isApiErrorMessage}. */
529
+ modelOutputInvalid?: ModelOutputInvalid;
495
530
  /**
496
531
  * design/124 tier A: this final message was PARTIALLY FINALIZED after a mid-stream connection
497
532
  * loss/stall — the substantive streamed prefix (text and/or completed tool calls) was promoted to
@@ -505,6 +540,17 @@ export interface AssistantMessage {
505
540
  * trailing call was already dropped by the finalize malformed path). Additive — absent everywhere else.
506
541
  */
507
542
  partialFinalized?: true;
543
+ /** A stream-end word (`finish_reason`) outside the set the brain reads, in the echo shape (`?` past it): the turn
544
+ * is kept, the Runner announces it (`route.finish_reason_unknown`), a completed run states it on `terminal.detail`. */
545
+ finishReasonUnknown?: string;
546
+ /** Frames after the stream's first terminal statement (which decided this turn) that were not acted on — a later
547
+ * ending (finish / stop reason), error or content — announced by the Runner (`route.stream_end_ignored`): the
548
+ * first one's kind and word (echo shape, `?` past it; for content, its kind), and how many came. */
549
+ streamEndIgnored?: {
550
+ statement: "ending" | "error" | "content";
551
+ word: string;
552
+ frames: number;
553
+ };
508
554
  /**
509
555
  * Degenerate-repetition telemetry for THIS call (2026-07-10: counts + detected segment, not just
510
556
  * a boolean). `cut` = the event that cancelled the stream (always paired with the DEGENERATE_MESSAGE
@@ -884,16 +930,6 @@ export interface ImagesModel<TApi extends ImagesApi = ImagesApi> extends Omit<Mo
884
930
  provider: ImagesProvider;
885
931
  output: ("text" | "image")[];
886
932
  }
887
- /** Where the credential a request would carry came from.
888
- * - `"per-model"` — resolved FOR this model: a per-call key/headers from the per-model auth hook
889
- * (`getApiKeyAndHeaders`), or an auth-bearing header declared on `Model.headers`. Paired by
890
- * construction (the resolver was asked about THIS entry), so the adjudicator never refuses it.
891
- * - `"deployment-config"` — the brain construction-time fallback (`config.apiKey` / an auth header
892
- * in `config.headers`). Paired only with the deployment's own declared root (`config.baseUrl`).
893
- * - `"absent"` — no credential anywhere. Legal for keyless gateways; refused only where an entry
894
- * declares its OWN URL away from a declared deployment root (a distinct endpoint with no
895
- * credential route is a configuration hole, not a keyless deployment). */
896
- export type RouteCredentialSource = "per-model" | "deployment-config" | "absent";
897
933
  /** The resolved credential a request would carry, tagged with its source (see {@link RouteCredentialSource}). */
898
934
  export interface RouteCredential {
899
935
  source: RouteCredentialSource;
@@ -906,7 +942,7 @@ export interface RouteCredential {
906
942
  /** Which header bag carries a headers-borne credential (resolution precedence:
907
943
  * options > model > config; the apiKey knob outranks headers within options, while the config's
908
944
  * knob+header pair counts as ONE deployment credential — see `resolveRouteCredential`). */
909
- carrierBag?: "options" | "model" | "config";
945
+ carrierBag?: RouteCarrierBag;
910
946
  }
911
947
  /** The deployment half of the pairing judgment: the brain construction config's DECLARED root.
912
948
  * Absent/empty ⇒ the deployment did not declare its credential's URL half (the unpinned
@@ -1,5 +1,6 @@
1
1
  import { findToolByName, validateToolArguments } from "../llm/index.js";
2
2
  import { truncateError } from "../../core/tool-errors.js";
3
+ import { judgeToolNameMiss, mountedToolNames } from "../../core/tool-name-aliases.js";
3
4
  import { INTERRUPTED_BY_USER_FOR_TOOL_USE_MARKER, INTERRUPTED_BY_USER_MARKER, } from "../../core/session-reconcile.js";
4
5
  import { resolveAgentCoreStreamFn } from "./runtime-deps.js";
5
6
  import { isErrorLike, readMember, thrownMarksOf, thrownText } from "../../core/thrown-value.js";
@@ -137,6 +138,8 @@ function defaultDetectPromptTooLong(message) {
137
138
  return true;
138
139
  if (message.inputTooLongRuledOut === true)
139
140
  return false;
141
+ if (message.errorBodyIncomplete === true)
142
+ return false;
140
143
  return PROMPT_TOO_LONG_RE.test(message.errorMessage ?? "");
141
144
  }
142
145
  function createPtlWithholdBuffer(emit, detect) {
@@ -1296,10 +1299,21 @@ function validationRefusedOutcome(tool, refusal) {
1296
1299
  async function prepareToolCall(currentContext, assistantMessage, toolCall, config, signal) {
1297
1300
  const tool = findToolByName(currentContext.tools, toolCall.name);
1298
1301
  if (!tool) {
1299
- const availableTools = (currentContext.tools ?? []).map((t) => t.name);
1302
+ const tools = currentContext.tools ?? [];
1303
+ const availableTools = tools.map((t) => t.name);
1304
+ const miss = judgeToolNameMiss(toolCall.name, mountedToolNames(tools));
1305
+ const retiredClause = miss.kind === "expected-absent" ? ` That name is retired: ${miss.detail}.` : "";
1300
1306
  return {
1301
1307
  kind: "immediate",
1302
- result: createErrorToolResult(`Tool ${toolCall.name} not found.${formatRosterRecovery(availableTools)}`, { details: { code: "tool.not_found", toolName: toolCall.name, availableTools } }),
1308
+ result: createErrorToolResult(`Tool ${toolCall.name} not found.${retiredClause}${formatRosterRecovery(availableTools)}`, {
1309
+ details: {
1310
+ code: "tool.not_found",
1311
+ toolName: toolCall.name,
1312
+ availableTools,
1313
+ absence: miss.kind,
1314
+ ...(miss.kind === "expected-absent" ? { detail: miss.detail, ...(miss.successor !== undefined ? { successor: miss.successor } : {}) } : {}),
1315
+ },
1316
+ }),
1303
1317
  isError: true,
1304
1318
  };
1305
1319
  }
@@ -1,7 +1,7 @@
1
1
  import { SessionError } from "../harness/types.js";
2
2
  import { validateEntriesForImport } from "./import-validate.js";
3
3
  import { InMemorySessionStorage } from "./memory-storage.js";
4
- import { createSessionId, createTimestamp, getEntriesToFork, toSession } from "./repo-utils.js";
4
+ import { assertForkTarget, createSessionId, createTimestamp, forkRowCells, getEntriesToFork, incarnationCell, toSession } from "./repo-utils.js";
5
5
  export class InMemorySessionRepo {
6
6
  sessions = new Map();
7
7
  async create(options = {}) {
@@ -13,6 +13,7 @@ export class InMemorySessionRepo {
13
13
  const metadata = {
14
14
  id: options.id ?? createSessionId(),
15
15
  createdAt: createTimestamp(),
16
+ ...incarnationCell(undefined),
16
17
  };
17
18
  const storage = new InMemorySessionStorage({ metadata });
18
19
  const session = toSession(storage);
@@ -33,12 +34,13 @@ export class InMemorySessionRepo {
33
34
  this.sessions.delete(metadata.id);
34
35
  }
35
36
  async fork(sourceMetadata, options) {
37
+ assertForkTarget(sourceMetadata.id, options.id);
36
38
  const source = await this.open(sourceMetadata);
37
39
  const forkedEntries = await getEntriesToFork(source.getStorage(), options);
38
40
  const metadata = {
39
41
  id: options.id ?? createSessionId(),
40
42
  createdAt: createTimestamp(),
41
- forkedFrom: sourceMetadata.id,
43
+ ...forkRowCells(await source.getMetadata()),
42
44
  };
43
45
  const storage = new InMemorySessionStorage({ metadata, entries: forkedEntries });
44
46
  const session = toSession(storage);
@@ -52,7 +54,13 @@ export class InMemorySessionRepo {
52
54
  async importEntries(sessionId, owner, entries, options) {
53
55
  void owner;
54
56
  const validated = validateEntriesForImport(entries, options);
55
- const metadata = { id: sessionId, createdAt: createTimestamp() };
57
+ let prior = this.sessions.get(sessionId);
58
+ let header = prior !== undefined ? await prior.getMetadata() : undefined;
59
+ while (this.sessions.get(sessionId) !== prior) {
60
+ prior = this.sessions.get(sessionId);
61
+ header = prior !== undefined ? await prior.getMetadata() : undefined;
62
+ }
63
+ const metadata = { id: sessionId, createdAt: createTimestamp(), ...incarnationCell(header) };
56
64
  this.sessions.set(sessionId, toSession(new InMemorySessionStorage({ metadata, entries: validated })));
57
65
  }
58
66
  }
@@ -1,6 +1,14 @@
1
1
  import { type SessionMetadata, type SessionStorage, type SessionTreeEntry } from "../harness/types.js";
2
2
  import type { Session } from "../harness/types.js";
3
3
  export declare function createSessionId(): string;
4
+ /** The {@link SessionMetadata.incarnation} cell for a write laying a row's metadata down — the bundled repos' ONE mint point.
5
+ * `existing` = the row before the write (`undefined`: none). A new row gets a fresh random v4 token (no time, no host); an
6
+ * existing row keeps exactly what it had, including nothing (no token is minted for an occupant that predates the cell). */
7
+ export declare function incarnationCell(existing: Pick<SessionMetadata, "incarnation"> | undefined): Pick<SessionMetadata, "incarnation">;
8
+ /** A fork lands on a row OTHER than its source: onto its own id it would mint a new occupant over the source's transcript and erase the lineage that carries the source's records. */
9
+ export declare function assertForkTarget(sourceId: string, targetId: string | undefined): void;
10
+ /** A fork row's cells, minted from the SOURCE row as it stands at fork time: the lineage (`forkedFrom` + the occupant copied) and a fresh occupant of its own. */
11
+ export declare function forkRowCells(source: SessionMetadata): Pick<SessionMetadata, "forkedFrom" | "forkedFromIncarnation" | "incarnation">;
4
12
  export declare function createTimestamp(): string;
5
13
  export declare function toSession<TMetadata extends SessionMetadata>(storage: SessionStorage<TMetadata>): Session<TMetadata>;
6
14
  export declare function getEntriesToFork(storage: SessionStorage, options: {
@@ -1,9 +1,22 @@
1
1
  import { SessionError, } from "../harness/types.js";
2
2
  import { StoredSession } from "./session.js";
3
3
  import { uuidv7 } from "./uuid.js";
4
+ import { randomUUID } from "node:crypto";
4
5
  export function createSessionId() {
5
6
  return uuidv7();
6
7
  }
8
+ export function incarnationCell(existing) {
9
+ if (existing === undefined)
10
+ return { incarnation: randomUUID() };
11
+ return existing.incarnation !== undefined ? { incarnation: existing.incarnation } : {};
12
+ }
13
+ export function assertForkTarget(sourceId, targetId) {
14
+ if (targetId === sourceId)
15
+ throw new SessionError("invalid_fork_target", `cannot fork session ${sourceId} onto its own id — fork into a new id`);
16
+ }
17
+ export function forkRowCells(source) {
18
+ return { forkedFrom: source.id, ...(source.incarnation !== undefined ? { forkedFromIncarnation: source.incarnation } : {}), ...incarnationCell(undefined) };
19
+ }
7
20
  export function createTimestamp() {
8
21
  return new Date().toISOString();
9
22
  }