@zergai/ztc 0.4.0-beta.1 → 0.5.0-beta.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 (718) hide show
  1. package/README.md +398 -45
  2. package/RUST_THIRD_PARTY_LICENSES.txt +1080 -822
  3. package/THIRD_PARTY_NOTICES.md +273 -12
  4. package/bin/zmux-darwin-arm64 +0 -0
  5. package/bin/ztc-audio-darwin-arm64 +0 -0
  6. package/bin/ztc-capture-darwin-arm64 +0 -0
  7. package/bin/ztc-computer-darwin-arm64 +0 -0
  8. package/bin/ztc-llm-darwin-arm64 +0 -0
  9. package/bin/ztc-tts-darwin-arm64 +0 -0
  10. package/bin/ztc-tui-darwin-arm64 +0 -0
  11. package/bin/ztc-zlicky-overlay-darwin-arm64 +0 -0
  12. package/bin/zterm-darwin-arm64 +0 -0
  13. package/dist/App.js +1206 -209
  14. package/dist/agent/agent.d.ts +74 -8
  15. package/dist/agent/agent.js +1073 -184
  16. package/dist/agent/backends/account_rotation.d.ts +4 -0
  17. package/dist/agent/backends/account_rotation.js +8 -2
  18. package/dist/agent/backends/anthropic.d.ts +13 -0
  19. package/dist/agent/backends/anthropic.js +169 -28
  20. package/dist/agent/backends/claude_cli.js +18 -8
  21. package/dist/agent/backends/codex_app_server.d.ts +1 -0
  22. package/dist/agent/backends/codex_app_server.js +55 -3
  23. package/dist/agent/backends/codex_auth.d.ts +1 -0
  24. package/dist/agent/backends/codex_auth.js +67 -13
  25. package/dist/agent/backends/codex_buffered_recovery.d.ts +27 -0
  26. package/dist/agent/backends/codex_buffered_recovery.js +293 -0
  27. package/dist/agent/backends/gemini.js +3 -1
  28. package/dist/agent/backends/http_error.d.ts +26 -0
  29. package/dist/agent/backends/http_error.js +221 -0
  30. package/dist/agent/backends/index.d.ts +9 -2
  31. package/dist/agent/backends/index.js +22 -2
  32. package/dist/agent/backends/openai.d.ts +0 -6
  33. package/dist/agent/backends/openai.js +5 -2
  34. package/dist/agent/backends/openai_compatible.d.ts +5 -4
  35. package/dist/agent/backends/openai_compatible.js +26 -19
  36. package/dist/agent/backends/openai_responses.d.ts +8 -3
  37. package/dist/agent/backends/openai_responses.js +77 -33
  38. package/dist/agent/backends/provider_ids.d.ts +1 -0
  39. package/dist/agent/backends/provider_ids.js +4 -0
  40. package/dist/agent/backends/request_metrics.js +12 -2
  41. package/dist/agent/backends/types.d.ts +109 -6
  42. package/dist/agent/backends/types.js +5 -1
  43. package/dist/agent/backends/zrouter_stream.d.ts +6 -1
  44. package/dist/agent/backends/zrouter_stream.js +160 -42
  45. package/dist/agent/background_registry.d.ts +2 -0
  46. package/dist/agent/background_registry.js +1 -0
  47. package/dist/agent/claim_observation.d.ts +6 -0
  48. package/dist/agent/claim_observation.js +54 -0
  49. package/dist/agent/commands/accounts.js +46 -177
  50. package/dist/agent/commands/attention.d.ts +2 -0
  51. package/dist/agent/commands/attention.js +67 -0
  52. package/dist/agent/commands/auth.js +18 -2
  53. package/dist/agent/commands/board.d.ts +2 -0
  54. package/dist/agent/commands/board.js +169 -0
  55. package/dist/agent/commands/clipboard.js +50 -1
  56. package/dist/agent/commands/compact.js +21 -13
  57. package/dist/agent/commands/config.js +4 -1
  58. package/dist/agent/commands/context.js +6 -1
  59. package/dist/agent/commands/desktop.d.ts +2 -0
  60. package/dist/agent/commands/desktop.js +29 -0
  61. package/dist/agent/commands/effort.js +14 -6
  62. package/dist/agent/commands/environment.d.ts +3 -0
  63. package/dist/agent/commands/environment.js +109 -0
  64. package/dist/agent/commands/evidence.d.ts +2 -0
  65. package/dist/agent/commands/evidence.js +9 -0
  66. package/dist/agent/commands/fork.js +4 -3
  67. package/dist/agent/commands/goal.d.ts +33 -1
  68. package/dist/agent/commands/goal.js +174 -14
  69. package/dist/agent/commands/goal_exit.d.ts +36 -0
  70. package/dist/agent/commands/goal_exit.js +120 -0
  71. package/dist/agent/commands/help.js +3 -1
  72. package/dist/agent/commands/history.js +3 -1
  73. package/dist/agent/commands/inbox.d.ts +2 -0
  74. package/dist/agent/commands/inbox.js +148 -0
  75. package/dist/agent/commands/index.js +16 -1
  76. package/dist/agent/commands/input_mode.js +8 -6
  77. package/dist/agent/commands/job.d.ts +2 -0
  78. package/dist/agent/commands/job.js +93 -0
  79. package/dist/agent/commands/keybindings.js +4 -1
  80. package/dist/agent/commands/label.d.ts +2 -0
  81. package/dist/agent/commands/label.js +77 -0
  82. package/dist/agent/commands/layout.d.ts +2 -0
  83. package/dist/agent/commands/layout.js +20 -0
  84. package/dist/agent/commands/mirror.js +16 -1
  85. package/dist/agent/commands/model.js +12 -2
  86. package/dist/agent/commands/permissions.d.ts +3 -1
  87. package/dist/agent/commands/permissions.js +79 -89
  88. package/dist/agent/commands/plan.js +5 -15
  89. package/dist/agent/commands/profile.js +21 -2
  90. package/dist/agent/commands/provider_selection.js +20 -1
  91. package/dist/agent/commands/rename.js +1 -1
  92. package/dist/agent/commands/resources.d.ts +2 -0
  93. package/dist/agent/commands/resources.js +67 -0
  94. package/dist/agent/commands/rewind.d.ts +3 -0
  95. package/dist/agent/commands/rewind.js +16 -0
  96. package/dist/agent/commands/runbooks.d.ts +2 -0
  97. package/dist/agent/commands/runbooks.js +73 -0
  98. package/dist/agent/commands/runbooks_lazy.d.ts +2 -0
  99. package/dist/agent/commands/runbooks_lazy.js +8 -0
  100. package/dist/agent/commands/sessions.d.ts +1 -1
  101. package/dist/agent/commands/sessions.js +33 -5
  102. package/dist/agent/commands/settings.js +185 -39
  103. package/dist/agent/commands/setup.d.ts +2 -0
  104. package/dist/agent/commands/setup.js +78 -0
  105. package/dist/agent/commands/share.d.ts +2 -0
  106. package/dist/agent/commands/share.js +64 -0
  107. package/dist/agent/commands/status.js +14 -2
  108. package/dist/agent/commands/types.d.ts +99 -6
  109. package/dist/agent/commands/update.js +8 -0
  110. package/dist/agent/commands/usage.d.ts +2 -0
  111. package/dist/agent/commands/usage.js +8 -0
  112. package/dist/agent/factory.d.ts +11 -0
  113. package/dist/agent/factory.js +113 -88
  114. package/dist/agent/loop_policy.d.ts +6 -3
  115. package/dist/agent/loop_policy.js +12 -3
  116. package/dist/agent/measurement_guidance.d.ts +2 -0
  117. package/dist/agent/measurement_guidance.js +5 -0
  118. package/dist/agent/request_encoder.d.ts +8 -1
  119. package/dist/agent/request_encoder.js +95 -23
  120. package/dist/agent/runtime/benchmark_comparison.d.ts +30 -0
  121. package/dist/agent/runtime/benchmark_comparison.js +94 -0
  122. package/dist/agent/runtime/benchmark_contract.d.ts +48 -0
  123. package/dist/agent/runtime/benchmark_contract.js +90 -0
  124. package/dist/agent/runtime/checked_commands.d.ts +32 -0
  125. package/dist/agent/runtime/checked_commands.js +119 -0
  126. package/dist/agent/runtime/command_execution_policy.d.ts +26 -0
  127. package/dist/agent/runtime/command_execution_policy.js +91 -0
  128. package/dist/agent/runtime/command_jobs.d.ts +36 -18
  129. package/dist/agent/runtime/command_jobs.js +151 -13
  130. package/dist/agent/runtime/command_panes.d.ts +59 -0
  131. package/dist/agent/runtime/command_panes.js +398 -0
  132. package/dist/agent/runtime/command_wait.d.ts +19 -0
  133. package/dist/agent/runtime/command_wait.js +167 -0
  134. package/dist/agent/runtime/cpu_benchmark.d.ts +30 -0
  135. package/dist/agent/runtime/cpu_benchmark.js +126 -0
  136. package/dist/agent/runtime/delegated_evidence.d.ts +26 -0
  137. package/dist/agent/runtime/delegated_evidence.js +80 -0
  138. package/dist/agent/runtime/evidence.d.ts +127 -0
  139. package/dist/agent/runtime/evidence.js +468 -0
  140. package/dist/agent/runtime/execution_context.d.ts +7 -0
  141. package/dist/agent/runtime/execution_context.js +39 -3
  142. package/dist/agent/runtime/json_verifier_recipe.d.ts +8 -0
  143. package/dist/agent/runtime/json_verifier_recipe.js +66 -0
  144. package/dist/agent/runtime/measurements.d.ts +110 -0
  145. package/dist/agent/runtime/measurements.js +317 -0
  146. package/dist/agent/runtime/policy.d.ts +4 -0
  147. package/dist/agent/runtime/policy.js +31 -20
  148. package/dist/agent/runtime/provider_native_evidence.d.ts +20 -0
  149. package/dist/agent/runtime/provider_native_evidence.js +86 -0
  150. package/dist/agent/runtime/recovery.d.ts +2 -0
  151. package/dist/agent/runtime/recovery.js +45 -2
  152. package/dist/agent/runtime/remote_broker_transport.d.ts +10 -0
  153. package/dist/agent/runtime/remote_broker_transport.js +84 -0
  154. package/dist/agent/runtime/remote_deletion_receipts.d.ts +3 -0
  155. package/dist/agent/runtime/remote_deletion_receipts.js +43 -0
  156. package/dist/agent/runtime/remote_journal_replay.d.ts +13 -0
  157. package/dist/agent/runtime/remote_journal_replay.js +233 -0
  158. package/dist/agent/runtime/remote_mutation_journal.d.ts +25 -0
  159. package/dist/agent/runtime/remote_mutation_journal.js +208 -0
  160. package/dist/agent/runtime/remote_resource_endpoint.d.ts +7 -0
  161. package/dist/agent/runtime/remote_resource_endpoint.js +6 -0
  162. package/dist/agent/runtime/remote_resource_errors.d.ts +5 -0
  163. package/dist/agent/runtime/remote_resource_errors.js +9 -0
  164. package/dist/agent/runtime/remote_resource_script.d.ts +2 -0
  165. package/dist/agent/runtime/remote_resource_script.js +1009 -0
  166. package/dist/agent/runtime/remote_resources.d.ts +29 -0
  167. package/dist/agent/runtime/remote_resources.js +160 -0
  168. package/dist/agent/runtime/source_verification.d.ts +12 -0
  169. package/dist/agent/runtime/source_verification.js +210 -0
  170. package/dist/agent/runtime/source_verification_contract.d.ts +75 -0
  171. package/dist/agent/runtime/source_verification_contract.js +203 -0
  172. package/dist/agent/runtime/tool_checkpoints.d.ts +11 -0
  173. package/dist/agent/runtime/tool_checkpoints.js +26 -0
  174. package/dist/agent/runtime/tool_effects.d.ts +5 -0
  175. package/dist/agent/runtime/tool_progress.d.ts +12 -0
  176. package/dist/agent/runtime/tool_progress.js +76 -0
  177. package/dist/agent/runtime/tool_runtime.d.ts +16 -1
  178. package/dist/agent/runtime/tool_runtime.js +204 -10
  179. package/dist/agent/runtime/tracing.d.ts +1 -1
  180. package/dist/agent/runtime/verifier_capture.d.ts +9 -0
  181. package/dist/agent/runtime/verifier_capture.js +100 -0
  182. package/dist/agent/runtime/verifier_contract.d.ts +24 -0
  183. package/dist/agent/runtime/verifier_contract.js +41 -0
  184. package/dist/agent/subagent.d.ts +20 -10
  185. package/dist/agent/subagent.js +266 -29
  186. package/dist/agent/tool_response_directory.d.ts +24 -0
  187. package/dist/agent/tool_response_directory.js +61 -0
  188. package/dist/agent/tool_response_source.d.ts +8 -0
  189. package/dist/agent/tool_response_source.js +49 -0
  190. package/dist/agent/tool_response_store.d.ts +75 -4
  191. package/dist/agent/tool_response_store.js +583 -64
  192. package/dist/agent/tools/ask_user.d.ts +3 -1
  193. package/dist/agent/tools/ask_user.js +30 -11
  194. package/dist/agent/tools/background.js +1 -0
  195. package/dist/agent/tools/benchmark_cpu.d.ts +2 -0
  196. package/dist/agent/tools/benchmark_cpu.js +102 -0
  197. package/dist/agent/tools/compare_benchmarks.d.ts +2 -0
  198. package/dist/agent/tools/compare_benchmarks.js +53 -0
  199. package/dist/agent/tools/deferred.js +1 -0
  200. package/dist/agent/tools/delegate.js +18 -2
  201. package/dist/agent/tools/helper_requirements.d.ts +7 -0
  202. package/dist/agent/tools/helper_requirements.js +19 -0
  203. package/dist/agent/tools/index.d.ts +1 -0
  204. package/dist/agent/tools/index.js +3 -0
  205. package/dist/agent/tools/measurement_report.d.ts +22 -0
  206. package/dist/agent/tools/measurement_report.js +190 -0
  207. package/dist/agent/tools/pane.d.ts +0 -7
  208. package/dist/agent/tools/pane.js +5 -4
  209. package/dist/agent/tools/project_context.d.ts +3 -0
  210. package/dist/agent/tools/project_context.js +45 -0
  211. package/dist/agent/tools/recall_tool_response.d.ts +3 -5
  212. package/dist/agent/tools/recall_tool_response.js +19 -29
  213. package/dist/agent/tools/registry.d.ts +1 -0
  214. package/dist/agent/tools/registry.js +23 -0
  215. package/dist/agent/tools/related_sessions.d.ts +2 -0
  216. package/dist/agent/tools/related_sessions.js +156 -0
  217. package/dist/agent/tools/routine.js +13 -3
  218. package/dist/agent/tools/session_evidence.d.ts +3 -0
  219. package/dist/agent/tools/session_evidence.js +72 -0
  220. package/dist/agent/tools/shell.d.ts +4 -3
  221. package/dist/agent/tools/shell.js +174 -47
  222. package/dist/agent/tools/tool_search.js +3 -2
  223. package/dist/agent/tools/types.d.ts +28 -0
  224. package/dist/agent/tools/verify_artifact.d.ts +2 -0
  225. package/dist/agent/tools/verify_artifact.js +60 -0
  226. package/dist/agent/tools/workflow.js +1 -0
  227. package/dist/app/activity.d.ts +6 -1
  228. package/dist/app/activity.js +81 -12
  229. package/dist/app/agent_runner.d.ts +6 -1
  230. package/dist/app/agent_runner.js +34 -19
  231. package/dist/app/command_context.js +106 -10
  232. package/dist/app/controller.d.ts +15 -4
  233. package/dist/app/controller.js +29 -3
  234. package/dist/app/escape_stop.d.ts +11 -0
  235. package/dist/app/escape_stop.js +15 -0
  236. package/dist/app/liveness.d.ts +6 -4
  237. package/dist/app/liveness.js +13 -3
  238. package/dist/app/model_catalog_cache.d.ts +5 -0
  239. package/dist/app/model_catalog_cache.js +138 -0
  240. package/dist/app/ordered_transcript.js +43 -4
  241. package/dist/app/prompt_turn.d.ts +14 -0
  242. package/dist/app/prompt_turn.js +53 -0
  243. package/dist/app/recap.d.ts +3 -0
  244. package/dist/app/recap.js +9 -3
  245. package/dist/app/restart.d.ts +3 -2
  246. package/dist/app/restart.js +22 -7
  247. package/dist/app/rewind.d.ts +3 -3
  248. package/dist/app/rewind.js +3 -3
  249. package/dist/app/selection_completion.d.ts +17 -2
  250. package/dist/app/selection_completion.js +84 -9
  251. package/dist/app/session_manager.d.ts +38 -6
  252. package/dist/app/session_manager.js +263 -60
  253. package/dist/app/session_messages.d.ts +3 -0
  254. package/dist/app/session_messages.js +60 -0
  255. package/dist/app/task_scope_router.d.ts +20 -0
  256. package/dist/app/task_scope_router.js +173 -0
  257. package/dist/app/transcript_window.d.ts +2 -0
  258. package/dist/app/transcript_window.js +4 -0
  259. package/dist/app/workspace_admission_details.d.ts +3 -0
  260. package/dist/app/workspace_admission_details.js +26 -0
  261. package/dist/app/workspace_layout_controller.d.ts +11 -0
  262. package/dist/app/workspace_layout_controller.js +88 -0
  263. package/dist/app/workspace_monitor.d.ts +1 -0
  264. package/dist/app/workspace_monitor.js +216 -0
  265. package/dist/app/workspace_presets.d.ts +29 -0
  266. package/dist/app/workspace_presets.js +192 -0
  267. package/dist/attention/queue.d.ts +37 -0
  268. package/dist/attention/queue.js +183 -0
  269. package/dist/bench/rf_shared.d.ts +2 -0
  270. package/dist/board/binding.d.ts +42 -0
  271. package/dist/board/binding.js +38 -0
  272. package/dist/board/client.d.ts +42 -0
  273. package/dist/board/client.js +60 -0
  274. package/dist/cli.js +1 -1
  275. package/dist/cli_args.js +19 -17
  276. package/dist/cli_main.js +110 -13
  277. package/dist/cli_ratatui.d.ts +183 -16
  278. package/dist/cli_ratatui.js +3989 -1255
  279. package/dist/components/ActivityLine.d.ts +3 -2
  280. package/dist/components/ActivityLine.js +2 -2
  281. package/dist/components/InputArea.d.ts +19 -1
  282. package/dist/components/InputArea.js +264 -190
  283. package/dist/components/MessageList.d.ts +2 -0
  284. package/dist/components/MessageList.js +3 -1
  285. package/dist/components/SingleMessage.d.ts +2 -0
  286. package/dist/components/SingleMessage.js +4 -2
  287. package/dist/components/StatusBar.d.ts +4 -2
  288. package/dist/components/StatusBar.js +3 -1
  289. package/dist/conductor_branch.js +3 -0
  290. package/dist/config/api_retry.d.ts +6 -1
  291. package/dist/config/api_retry.js +19 -1
  292. package/dist/config/defaults.d.ts +2 -1
  293. package/dist/config/defaults.js +9 -2
  294. package/dist/config/message_display.d.ts +1 -0
  295. package/dist/config/message_display.js +17 -2
  296. package/dist/config/permissions.d.ts +21 -0
  297. package/dist/config/permissions.js +89 -0
  298. package/dist/config/resolved.d.ts +2 -2
  299. package/dist/config/types.d.ts +32 -5
  300. package/dist/config.d.ts +38 -4
  301. package/dist/config.js +290 -42
  302. package/dist/context/project_intelligence.d.ts +44 -0
  303. package/dist/context/project_intelligence.js +246 -0
  304. package/dist/desktop/cli_launch.d.ts +8 -0
  305. package/dist/desktop/cli_launch.js +6 -0
  306. package/dist/desktop/cli_shim.d.ts +8 -0
  307. package/dist/desktop/cli_shim.js +120 -0
  308. package/dist/desktop/runtime.d.ts +16 -0
  309. package/dist/desktop/runtime.js +161 -0
  310. package/dist/desktop/worker_launch.d.ts +7 -0
  311. package/dist/desktop/worker_launch.js +7 -0
  312. package/dist/diagnostics/cargo_mutants_selection.d.ts +27 -0
  313. package/dist/diagnostics/cargo_mutants_selection.js +48 -0
  314. package/dist/diagnostics/native_terminal_benchmark.d.ts +58 -0
  315. package/dist/diagnostics/native_terminal_benchmark.js +1247 -0
  316. package/dist/diagnostics/session_evidence_package.d.ts +40 -0
  317. package/dist/diagnostics/session_evidence_package.js +234 -0
  318. package/dist/diagnostics/session_export.d.ts +93 -0
  319. package/dist/diagnostics/session_export.js +634 -0
  320. package/dist/emulation/tool_adapters.js +48 -18
  321. package/dist/emulation/ztc_addendum.d.ts +1 -0
  322. package/dist/emulation/ztc_addendum.js +13 -12
  323. package/dist/environment/service_runner.d.ts +1 -0
  324. package/dist/environment/service_runner.js +68 -0
  325. package/dist/environment/store.d.ts +120 -0
  326. package/dist/environment/store.js +387 -0
  327. package/dist/events.d.ts +40 -1
  328. package/dist/events.js +10 -17
  329. package/dist/goal_contract.d.ts +25 -0
  330. package/dist/goal_contract.js +44 -0
  331. package/dist/headless.d.ts +31 -0
  332. package/dist/headless.js +578 -70
  333. package/dist/headless_cli.js +8 -0
  334. package/dist/headless_cli_args.d.ts +1 -0
  335. package/dist/headless_cli_args.js +1 -0
  336. package/dist/intake/cli.d.ts +1 -0
  337. package/dist/intake/cli.js +33 -0
  338. package/dist/intake/format.d.ts +2 -0
  339. package/dist/intake/format.js +14 -0
  340. package/dist/intake/notifications.d.ts +16 -0
  341. package/dist/intake/notifications.js +132 -0
  342. package/dist/intake/store.d.ts +56 -0
  343. package/dist/intake/store.js +238 -0
  344. package/dist/library.d.ts +8 -0
  345. package/dist/library.js +19 -10
  346. package/dist/mcp/client.d.ts +1 -0
  347. package/dist/mcp/client.js +20 -0
  348. package/dist/modes/builtin/plan.yaml +2 -2
  349. package/dist/modes/handlers.js +1 -1
  350. package/dist/onboarding/first_run.d.ts +3 -0
  351. package/dist/onboarding/first_run.js +33 -25
  352. package/dist/onboarding/setup.d.ts +32 -0
  353. package/dist/onboarding/setup.js +133 -0
  354. package/dist/onboarding/setup_agent_health.d.ts +17 -0
  355. package/dist/onboarding/setup_agent_health.js +79 -0
  356. package/dist/onboarding/setup_environment.d.ts +66 -0
  357. package/dist/onboarding/setup_environment.js +219 -0
  358. package/dist/onboarding/setup_workspace.d.ts +17 -0
  359. package/dist/onboarding/setup_workspace.js +129 -0
  360. package/dist/optimize/adapters/index.d.ts +4 -1
  361. package/dist/optimize/adapters/index.js +7 -0
  362. package/dist/optimize/adapters/kernelbench.js +14 -5
  363. package/dist/optimize/adapters/popcorn.js +3 -2
  364. package/dist/optimize/adapters/profile_benchmark.js +13 -7
  365. package/dist/optimize/adapters/rfbench.js +25 -14
  366. package/dist/optimize/adapters/types.d.ts +3 -0
  367. package/dist/optimize/adapters/zergpod.js +5 -2
  368. package/dist/optimize/baseline.js +10 -21
  369. package/dist/optimize/branch.js +9 -12
  370. package/dist/optimize/combine.js +2 -3
  371. package/dist/optimize/executor.js +34 -48
  372. package/dist/optimize/measurements.d.ts +55 -0
  373. package/dist/optimize/measurements.js +173 -0
  374. package/dist/optimize/results.d.ts +1 -0
  375. package/dist/optimize/results.js +11 -33
  376. package/dist/optimize/tge.js +2 -1
  377. package/dist/panes/initial_input.d.ts +19 -0
  378. package/dist/panes/initial_input.js +206 -0
  379. package/dist/panes/labels.d.ts +16 -0
  380. package/dist/panes/labels.js +42 -0
  381. package/dist/panes/model_catalog.d.ts +3 -3
  382. package/dist/panes/model_catalog.js +28 -4
  383. package/dist/panes/pane_registry.js +6 -2
  384. package/dist/panes/types.d.ts +3 -0
  385. package/dist/panes/ztc_launch.js +19 -0
  386. package/dist/plugin/optimization.d.ts +2 -0
  387. package/dist/plugin/optimization.js +1 -0
  388. package/dist/plugin/runtime.d.ts +2 -0
  389. package/dist/plugin/simulation.d.ts +6 -1
  390. package/dist/plugin/simulation_contract.d.ts +836 -1
  391. package/dist/plugin/simulation_documents.d.ts +22 -0
  392. package/dist/plugin/simulation_documents.js +1 -0
  393. package/dist/plugin/simulation_interventions.d.ts +103 -0
  394. package/dist/plugin/simulation_interventions.js +1 -0
  395. package/dist/plugin/simulation_living.d.ts +1 -0
  396. package/dist/plugin/simulation_living.js +3 -0
  397. package/dist/plugin/simulation_meetings.d.ts +121 -0
  398. package/dist/plugin/simulation_meetings.js +1 -0
  399. package/dist/plugin/simulation_story_review.d.ts +111 -0
  400. package/dist/plugin/simulation_story_review.js +1 -0
  401. package/dist/plugin/simulation_storyteller.d.ts +91 -0
  402. package/dist/plugin/simulation_storyteller.js +1 -0
  403. package/dist/plugin/simulation_structured.d.ts +2 -0
  404. package/dist/plugin/simulation_structured.js +2 -0
  405. package/dist/plugin/simulation_toolkit.d.ts +21 -0
  406. package/dist/plugin/simulation_toolkit.js +24 -0
  407. package/dist/prompts/tool_delegate_task.j2 +1 -1
  408. package/dist/remote-broker/Dockerfile +10 -0
  409. package/dist/remote-broker/archive.py +1227 -0
  410. package/dist/remote-broker/cutover.py +761 -0
  411. package/dist/remote-broker/requirements.txt +5 -0
  412. package/dist/remote-broker/resources.json +6 -0
  413. package/dist/remote-broker/resources.write-staging.example.json +18 -0
  414. package/dist/remote-broker/retained.py +686 -0
  415. package/dist/remote-broker/retained_cleanup.py +550 -0
  416. package/dist/remote-broker/server.py +648 -0
  417. package/dist/remote-broker/worker.py +1007 -0
  418. package/dist/router_auth.d.ts +31 -0
  419. package/dist/router_auth.js +155 -9
  420. package/dist/runbooks/catalog.d.ts +3 -0
  421. package/dist/runbooks/catalog.js +26 -0
  422. package/dist/runbooks/library.d.ts +11 -0
  423. package/dist/runbooks/library.js +95 -0
  424. package/dist/runbooks/package.d.ts +43 -0
  425. package/dist/runbooks/package.js +102 -0
  426. package/dist/session.d.ts +65 -13
  427. package/dist/session.js +548 -43
  428. package/dist/session_handoff.d.ts +25 -0
  429. package/dist/session_handoff.js +322 -0
  430. package/dist/session_handoff_contract.d.ts +89 -0
  431. package/dist/session_handoff_contract.js +179 -0
  432. package/dist/session_media.d.ts +41 -0
  433. package/dist/session_media.js +357 -0
  434. package/dist/session_ownership.d.ts +16 -0
  435. package/dist/session_ownership.js +221 -0
  436. package/dist/session_public.d.ts +10 -2
  437. package/dist/session_public.js +6 -1
  438. package/dist/simulation/dynamic_history.d.ts +42 -0
  439. package/dist/simulation/dynamic_history.js +173 -0
  440. package/dist/simulation/engines/swarm/pane_manager.js +7 -6
  441. package/dist/simulation/inference.d.ts +3 -1
  442. package/dist/simulation/inference.js +19 -1
  443. package/dist/simulation/intervention_generation.d.ts +27 -0
  444. package/dist/simulation/intervention_generation.js +246 -0
  445. package/dist/simulation/intervention_material.d.ts +4 -0
  446. package/dist/simulation/intervention_material.js +81 -0
  447. package/dist/simulation/living/context.d.ts +3130 -0
  448. package/dist/simulation/living/context.js +944 -0
  449. package/dist/simulation/living/definer.d.ts +12 -0
  450. package/dist/simulation/living/definer.js +223 -0
  451. package/dist/simulation/living/definition.d.ts +257 -0
  452. package/dist/simulation/living/definition.js +341 -0
  453. package/dist/simulation/living/frame.d.ts +259 -0
  454. package/dist/simulation/living/frame.js +223 -0
  455. package/dist/simulation/living/identifiers.d.ts +2 -0
  456. package/dist/simulation/living/identifiers.js +12 -0
  457. package/dist/simulation/living/index.d.ts +15 -0
  458. package/dist/simulation/living/index.js +15 -0
  459. package/dist/simulation/living/inference.d.ts +219 -0
  460. package/dist/simulation/living/inference.js +576 -0
  461. package/dist/simulation/living/mechanics.d.ts +54 -0
  462. package/dist/simulation/living/mechanics.js +588 -0
  463. package/dist/simulation/living/model-input.d.ts +25 -0
  464. package/dist/simulation/living/model-input.js +215 -0
  465. package/dist/simulation/living/open-world.d.ts +257 -0
  466. package/dist/simulation/living/open-world.js +102 -0
  467. package/dist/simulation/living/projection.d.ts +7 -0
  468. package/dist/simulation/living/projection.js +31 -0
  469. package/dist/simulation/living/recall.d.ts +17 -0
  470. package/dist/simulation/living/recall.js +25 -0
  471. package/dist/simulation/living/reduce.d.ts +15 -0
  472. package/dist/simulation/living/reduce.js +1853 -0
  473. package/dist/simulation/living/replay.d.ts +6 -0
  474. package/dist/simulation/living/replay.js +22 -0
  475. package/dist/simulation/living/runtime.d.ts +140 -0
  476. package/dist/simulation/living/runtime.js +3020 -0
  477. package/dist/simulation/living/shared-kinds.d.ts +24 -0
  478. package/dist/simulation/living/shared-kinds.js +96 -0
  479. package/dist/simulation/living/types.d.ts +2785 -0
  480. package/dist/simulation/living/types.js +669 -0
  481. package/dist/simulation/llm.d.ts +3 -1
  482. package/dist/simulation/llm.js +90 -30
  483. package/dist/simulation/memory/embedding.d.ts +1 -1
  484. package/dist/simulation/memory/embedding.js +9 -3
  485. package/dist/simulation/memory/filesystem.d.ts +2 -0
  486. package/dist/simulation/memory/filesystem.js +5 -1
  487. package/dist/simulation/memory/filesystem_file_tree.d.ts +4 -1
  488. package/dist/simulation/memory/filesystem_file_tree.js +41 -10
  489. package/dist/simulation/memory/filesystem_invariants.js +1 -2
  490. package/dist/simulation/memory/filesystem_types.d.ts +1 -0
  491. package/dist/simulation/memory/memory.d.ts +2 -0
  492. package/dist/simulation/memory/memory.js +5 -1
  493. package/dist/simulation/orchestration/intent.js +0 -2
  494. package/dist/simulation/orchestration/lifecycle.js +0 -2
  495. package/dist/simulation/plugin_host.d.ts +25 -1
  496. package/dist/simulation/plugin_host.js +334 -17
  497. package/dist/simulation/session_documents.d.ts +20 -0
  498. package/dist/simulation/session_documents.js +62 -0
  499. package/dist/simulation/session_input_validation.d.ts +43 -0
  500. package/dist/simulation/session_input_validation.js +364 -0
  501. package/dist/simulation/session_inputs.d.ts +32 -0
  502. package/dist/simulation/session_inputs.js +154 -0
  503. package/dist/simulation/telemetry.d.ts +11 -14
  504. package/dist/simulation/telemetry.js +177 -54
  505. package/dist/simulation/toolkit/bounded_turns.d.ts +13 -0
  506. package/dist/simulation/toolkit/bounded_turns.js +80 -0
  507. package/dist/simulation/toolkit/dynamic_agents.d.ts +25 -0
  508. package/dist/simulation/toolkit/dynamic_agents.js +218 -0
  509. package/dist/simulation/toolkit/dynamic_digest.d.ts +1 -0
  510. package/dist/simulation/toolkit/dynamic_digest.js +8 -0
  511. package/dist/simulation/toolkit/dynamic_documents.d.ts +7 -0
  512. package/dist/simulation/toolkit/dynamic_documents.js +71 -0
  513. package/dist/simulation/toolkit/dynamic_driver.d.ts +8 -0
  514. package/dist/simulation/toolkit/dynamic_driver.js +269 -0
  515. package/dist/simulation/toolkit/dynamic_game.d.ts +53 -0
  516. package/dist/simulation/toolkit/dynamic_game.js +805 -0
  517. package/dist/simulation/toolkit/dynamic_knowledge.d.ts +15 -0
  518. package/dist/simulation/toolkit/dynamic_knowledge.js +91 -0
  519. package/dist/simulation/toolkit/dynamic_mechanics.d.ts +22 -0
  520. package/dist/simulation/toolkit/dynamic_mechanics.js +910 -0
  521. package/dist/simulation/toolkit/dynamic_meetings.d.ts +239 -0
  522. package/dist/simulation/toolkit/dynamic_meetings.js +350 -0
  523. package/dist/simulation/toolkit/dynamic_progress.d.ts +131 -0
  524. package/dist/simulation/toolkit/dynamic_progress.js +214 -0
  525. package/dist/simulation/toolkit/dynamic_projection.d.ts +9 -0
  526. package/dist/simulation/toolkit/dynamic_projection.js +219 -0
  527. package/dist/simulation/toolkit/dynamic_runtime.d.ts +412 -0
  528. package/dist/simulation/toolkit/dynamic_runtime.js +6536 -0
  529. package/dist/simulation/toolkit/dynamic_state.d.ts +111 -0
  530. package/dist/simulation/toolkit/dynamic_state.js +1967 -0
  531. package/dist/simulation/toolkit/dynamic_story_review.d.ts +508 -0
  532. package/dist/simulation/toolkit/dynamic_story_review.js +333 -0
  533. package/dist/simulation/toolkit/dynamic_storyteller.d.ts +77 -0
  534. package/dist/simulation/toolkit/dynamic_storyteller.js +114 -0
  535. package/dist/simulation/toolkit/dynamic_storyteller_runtime.d.ts +26 -0
  536. package/dist/simulation/toolkit/dynamic_storyteller_runtime.js +126 -0
  537. package/dist/simulation/toolkit/dynamic_world.d.ts +22 -0
  538. package/dist/simulation/toolkit/dynamic_world.js +377 -0
  539. package/dist/simulation/toolkit/structured_output.d.ts +5 -0
  540. package/dist/simulation/toolkit/structured_output.js +321 -0
  541. package/dist/simulation/types/world.d.ts +2 -0
  542. package/dist/simulation/world/artifact_store.js +1 -1
  543. package/dist/simulation/world/memory_manager.d.ts +5 -0
  544. package/dist/simulation/world/memory_manager.js +17 -2
  545. package/dist/simulation/world/state.d.ts +3 -2
  546. package/dist/simulation/world/state.js +15 -5
  547. package/dist/skills/bundled/measurement-validation/SKILL.md +144 -0
  548. package/dist/terminal_attach.d.ts +1 -0
  549. package/dist/terminal_attach.js +113 -0
  550. package/dist/tool_progress.d.ts +3 -0
  551. package/dist/tool_progress.js +27 -0
  552. package/dist/types.d.ts +145 -10
  553. package/dist/types.js +3 -0
  554. package/dist/ui/core/input.d.ts +3 -0
  555. package/dist/ui/core/input_segments.d.ts +18 -1
  556. package/dist/ui/core/input_segments.js +131 -47
  557. package/dist/ui/core/input_state.d.ts +12 -0
  558. package/dist/ui/core/layout_yoga.d.ts +1 -1
  559. package/dist/ui/core/turn_metadata.d.ts +5 -0
  560. package/dist/ui/core/turn_metadata.js +22 -0
  561. package/dist/ui/ink/render.d.ts +2 -1
  562. package/dist/ui/ink/render.js +6 -5
  563. package/dist/ui/ratatui/headless_pane_manager.d.ts +14 -1
  564. package/dist/ui/ratatui/headless_pane_manager.js +293 -104
  565. package/dist/ui/ratatui/index.d.ts +1 -0
  566. package/dist/ui/ratatui/input.d.ts +4 -0
  567. package/dist/ui/ratatui/input.js +15 -0
  568. package/dist/ui/ratatui/ipc_path.d.ts +2 -0
  569. package/dist/ui/ratatui/ipc_path.js +29 -1
  570. package/dist/ui/ratatui/mux_persistence.d.ts +3 -1
  571. package/dist/ui/ratatui/mux_persistence.js +139 -1
  572. package/dist/ui/ratatui/pane_relay.d.ts +1 -1
  573. package/dist/ui/ratatui/pane_relay.js +55 -27
  574. package/dist/ui/ratatui/process.d.ts +17 -1
  575. package/dist/ui/ratatui/process.js +80 -7
  576. package/dist/ui/ratatui/protocol.d.ts +236 -1
  577. package/dist/ui/ratatui/protocol.js +90 -0
  578. package/dist/ui/scrollback.d.ts +2 -1
  579. package/dist/ui/scrollback.js +9 -4
  580. package/dist/ui/stream_typewriter.d.ts +8 -3
  581. package/dist/ui/stream_typewriter.js +30 -1
  582. package/dist/ui/streaming_scrollback.d.ts +1 -0
  583. package/dist/ui/streaming_scrollback.js +1 -1
  584. package/dist/ui/transcript_render_cache.js +10 -0
  585. package/dist/ui/views/activity_line.d.ts +5 -3
  586. package/dist/ui/views/activity_line.js +65 -7
  587. package/dist/ui/views/app.d.ts +6 -3
  588. package/dist/ui/views/app.js +17 -6
  589. package/dist/ui/views/completion_menu.js +10 -5
  590. package/dist/ui/views/input_area.d.ts +7 -3
  591. package/dist/ui/views/input_area.js +15 -9
  592. package/dist/ui/views/message_list.d.ts +4 -1
  593. package/dist/ui/views/message_list.js +89 -19
  594. package/dist/ui/views/queue_panel.d.ts +3 -1
  595. package/dist/ui/views/queue_panel.js +9 -2
  596. package/dist/ui/views/status_bar.d.ts +4 -2
  597. package/dist/ui/views/status_bar.js +28 -13
  598. package/dist/ui/views/theme.d.ts +2 -0
  599. package/dist/ui/views/theme.js +2 -0
  600. package/dist/ui/widgets/color_panel.js +18 -0
  601. package/dist/ui/widgets/form.js +8 -0
  602. package/dist/ui/widgets/log_view.js +7 -0
  603. package/dist/ui/widgets/navigator_panel.js +8 -0
  604. package/dist/ui/widgets/prompt_viewer.js +2 -0
  605. package/dist/ui/widgets/questionnaire.d.ts +2 -0
  606. package/dist/ui/widgets/questionnaire.js +79 -16
  607. package/dist/ui/widgets/resume_panel.d.ts +2 -0
  608. package/dist/ui/widgets/resume_panel.js +26 -15
  609. package/dist/ui/widgets/rewind_panel.d.ts +2 -2
  610. package/dist/ui/widgets/rewind_panel.js +4 -2
  611. package/dist/ui/widgets/select.js +16 -27
  612. package/dist/ui/widgets/settings_panel.js +16 -0
  613. package/dist/ui/widgets/status_line_panel.d.ts +1 -0
  614. package/dist/ui/widgets/status_line_panel.js +30 -4
  615. package/dist/ui/widgets/text_input.d.ts +2 -0
  616. package/dist/ui/widgets/text_input.js +15 -1
  617. package/dist/ui/widgets/types.d.ts +2 -0
  618. package/dist/usage_projection.d.ts +24 -0
  619. package/dist/usage_projection.js +130 -0
  620. package/dist/usage_snapshot.d.ts +36 -0
  621. package/dist/usage_snapshot.js +131 -0
  622. package/dist/utils/assistant_message.d.ts +2 -0
  623. package/dist/utils/assistant_message.js +5 -0
  624. package/dist/utils/atomic_write.d.ts +6 -2
  625. package/dist/utils/atomic_write.js +29 -4
  626. package/dist/utils/checked_shell.d.ts +25 -0
  627. package/dist/utils/checked_shell.js +107 -0
  628. package/dist/utils/compaction.d.ts +4 -1
  629. package/dist/utils/compaction.js +31 -7
  630. package/dist/utils/context.d.ts +4 -4
  631. package/dist/utils/context.js +14 -12
  632. package/dist/utils/deepseek.d.ts +2 -2
  633. package/dist/utils/deepseek.js +13 -5
  634. package/dist/utils/ephemeral.js +4 -0
  635. package/dist/utils/ephemeral_tools.d.ts +18 -0
  636. package/dist/utils/ephemeral_tools.js +97 -0
  637. package/dist/utils/jev_client.d.ts +4 -0
  638. package/dist/utils/jev_client.js +15 -0
  639. package/dist/utils/model_cache.d.ts +15 -0
  640. package/dist/utils/model_cache.js +143 -0
  641. package/dist/utils/models.d.ts +4 -2
  642. package/dist/utils/models.js +12 -16
  643. package/dist/utils/reasoning.d.ts +8 -1
  644. package/dist/utils/reasoning.js +31 -11
  645. package/dist/utils/router_catalog.d.ts +49 -0
  646. package/dist/utils/router_catalog.js +271 -0
  647. package/dist/utils/sandbox.d.ts +9 -0
  648. package/dist/utils/sandbox.js +118 -15
  649. package/dist/utils/shell.d.ts +7 -0
  650. package/dist/utils/shell.js +98 -34
  651. package/dist/utils/subprocess_env.d.ts +3 -0
  652. package/dist/utils/subprocess_env.js +27 -1
  653. package/dist/web/accounts_mirror.d.ts +3 -1
  654. package/dist/web/accounts_mirror.js +13 -9
  655. package/dist/web/child_publication.d.ts +17 -0
  656. package/dist/web/child_publication.js +45 -0
  657. package/dist/web/mirror_authenticator.d.ts +31 -11
  658. package/dist/web/mirror_authenticator.js +67 -17
  659. package/dist/web/mirror_client.d.ts +31 -4
  660. package/dist/web/mirror_client.js +189 -23
  661. package/dist/web/mirror_stream.d.ts +84 -22
  662. package/dist/web/mirror_stream.js +676 -95
  663. package/dist/web/observer_query_redaction.d.ts +6 -0
  664. package/dist/web/observer_query_redaction.js +58 -0
  665. package/dist/web/pane_registry.d.ts +2 -0
  666. package/dist/web/pane_registry.js +86 -22
  667. package/dist/web/tool_image.d.ts +6 -0
  668. package/dist/web/tool_image.js +17 -0
  669. package/dist/web/view_plugin.d.ts +14 -0
  670. package/dist/web/view_plugin.js +23 -1
  671. package/dist/worker/executor.js +31 -12
  672. package/dist/worker/index.d.ts +1 -0
  673. package/dist/worker/toolsets.js +3 -1
  674. package/dist/worker/types.d.ts +12 -1
  675. package/dist/workflows/registry.js +1 -0
  676. package/dist/workflows/registry_handle.d.ts +2 -0
  677. package/dist/workflows/runtime.d.ts +2 -0
  678. package/dist/workflows/runtime.js +1 -0
  679. package/dist/workspace_agent.d.ts +7 -0
  680. package/dist/workspace_agent.js +36 -0
  681. package/dist/workspace_collision.d.ts +76 -0
  682. package/dist/workspace_collision.js +688 -0
  683. package/dist/workspace_layout.d.ts +18 -0
  684. package/dist/workspace_layout.js +121 -0
  685. package/dist/workspace_runtime.d.ts +44 -0
  686. package/dist/workspace_runtime.js +82 -0
  687. package/dist/workspace_session_context.d.ts +62 -0
  688. package/dist/workspace_session_context.js +160 -0
  689. package/dist/zlm-embed.mjs +32518 -9615
  690. package/dist/zlm.js +1 -0
  691. package/node_modules/@zerg/model-contracts/LICENSE.md +375 -0
  692. package/node_modules/@zerg/model-contracts/README.md +90 -0
  693. package/node_modules/@zerg/model-contracts/index.d.ts +20 -0
  694. package/node_modules/@zerg/model-contracts/index.js +223 -0
  695. package/node_modules/@zerg/model-contracts/package.json +8 -0
  696. package/node_modules/glob/node_modules/brace-expansion/index.js +78 -22
  697. package/node_modules/glob/node_modules/brace-expansion/package.json +1 -1
  698. package/node_modules/readdir-glob/node_modules/brace-expansion/index.js +78 -22
  699. package/node_modules/readdir-glob/node_modules/brace-expansion/package.json +1 -1
  700. package/package.json +45 -24
  701. package/packages/model-contracts/LICENSE.md +375 -0
  702. package/packages/model-contracts/README.md +90 -0
  703. package/packages/model-contracts/index.d.ts +20 -0
  704. package/packages/model-contracts/index.js +223 -0
  705. package/packages/model-contracts/package.json +8 -0
  706. package/remote-broker/Dockerfile +10 -0
  707. package/remote-broker/README.md +308 -0
  708. package/remote-broker/archive.py +1227 -0
  709. package/remote-broker/cutover.py +761 -0
  710. package/remote-broker/requirements.txt +5 -0
  711. package/remote-broker/resources.example.json +6 -0
  712. package/remote-broker/resources.write-staging.example.json +18 -0
  713. package/remote-broker/retained.py +686 -0
  714. package/remote-broker/retained_cleanup.py +550 -0
  715. package/remote-broker/server.py +648 -0
  716. package/scripts/build-remote-broker.mjs +13 -0
  717. package/scripts/ensure-local-packages.mjs +6 -0
  718. package/scripts/node-pty-helpers.mjs +103 -0
@@ -1,3 +1,5 @@
1
+ import { ZRouterStreamBackend } from './backends/zrouter_stream.js';
2
+ import { readRouterCatalog } from '../utils/router_catalog.js';
1
3
  /**
2
4
  * SubAgent - Isolated agent for context-heavy operations
3
5
  *
@@ -9,6 +11,8 @@
9
11
  * Only the final summary is returned to the main agent, keeping the main context clean.
10
12
  */
11
13
  import { randomUUID } from 'node:crypto';
14
+ import { realpathSync } from 'node:fs';
15
+ import { getSessionPathForCwd, saveSessionToFile } from '../session.js';
12
16
  import { getDefaultModel } from '../utils/models.js';
13
17
  import { debugLog } from '../utils/debug_log.js';
14
18
  import { createBackendForProvider } from './backends/index.js';
@@ -16,9 +20,16 @@ import { accountBackendOptions, resolveRotation } from './backends/account_pool.
16
20
  import { buildAccountRotation, subagentShouldRotate } from './backends/rotation_factory.js';
17
21
  import { describeExecutionContext, resolveExecutionSettings } from './runtime/execution_context.js';
18
22
  import { createRecoveryGuard } from './runtime/recovery.js';
23
+ import { listCommandJobs, shutdownCommandJobs } from './runtime/command_jobs.js';
24
+ import { awaitManagedCommandProgress, formatManagedCommandObservations } from './runtime/command_wait.js';
19
25
  import { scheduleToolBatch, commandStillRunning } from './runtime/tool_scheduler.js';
20
26
  import { configStore } from '../config.js';
21
- import { ToolResponseStore } from './tool_response_store.js';
27
+ import { RequestEncoder, nativeHistoryContextId } from './request_encoder.js';
28
+ import { ToolResponseIntegrityError, ToolResponseStore } from './tool_response_store.js';
29
+ import { formatEvidenceContext } from './runtime/evidence.js';
30
+ import { acquireDelegatedEvidenceWriter, bindDelegatedEvidence, createDelegatedEvidenceHandoff } from './runtime/delegated_evidence.js';
31
+ import { recallToolResponseTool } from './tools/recall_tool_response.js';
32
+ import { sessionEvidenceTool } from './tools/session_evidence.js';
22
33
  import { RESEARCH_TOOLS } from '../worker/toolsets.js';
23
34
  import { renderPrompt } from '../utils/template.js';
24
35
  import { executeToolWithRuntime } from './runtime/tool_runtime.js';
@@ -44,6 +55,18 @@ function isToolUseBlock(block) {
44
55
  function getSubAgentModel(provider, preferredModel) {
45
56
  if (preferredModel)
46
57
  return preferredModel;
58
+ if (configStore.resolveLLMBackendConfig({ provider }).useProxy) {
59
+ if (configStore.getProvider() === provider)
60
+ return configStore.getModel();
61
+ const catalog = configStore.getRouterCatalog();
62
+ const rows = catalog?.models.filter(row => row.owned_by === provider && (catalog.version === 0 || row.capabilities?.chat));
63
+ const selected = rows?.find(row => row.is_default) ?? rows?.[0];
64
+ if (selected)
65
+ return selected.id;
66
+ if (!configStore.getRouterCatalog() || configStore.getRouterCatalog()?.version === 0)
67
+ return getDefaultModel(provider, 'cheap');
68
+ throw new Error('Select a Router model for this subagent.');
69
+ }
47
70
  return getDefaultModel(provider, 'cheap');
48
71
  }
49
72
  /**
@@ -57,6 +80,12 @@ function getSubAgentModel(provider, preferredModel) {
57
80
  */
58
81
  function createBackend(provider, apiKey) {
59
82
  const config = configStore.get();
83
+ const resolved = configStore.resolveLLMBackendConfig({ provider, apiKeyOverride: apiKey });
84
+ if (resolved.useProxy) {
85
+ return new ZRouterStreamBackend({ apiKey: resolved.authToken, proxyUrl: resolved.proxyUrl, provider,
86
+ workspaceId: configStore.getRouterCatalogConnection()?.workspaceId,
87
+ catalog: readRouterCatalog({ origin: resolved.proxyUrl, token: resolved.authToken, workspaceId: configStore.getRouterCatalogConnection()?.workspaceId }) });
88
+ }
60
89
  const accountOpts = accountBackendOptions(config, provider);
61
90
  const rotationOpts = subagentShouldRotate(resolveRotation(config))
62
91
  ? buildAccountRotation(config) ?? {}
@@ -85,23 +114,27 @@ export class SubAgent {
85
114
  cwd;
86
115
  inputTokens = 0;
87
116
  outputTokens = 0;
88
- // Per-SubAgent offload store + discovery set. Subagent toolsets (RESEARCH /
89
- // WRITE) don't include `tool_search` or `recall_tool_response`, but the
90
- // ToolContext shape is required — and keeping these isolated guarantees a
91
- // subagent's tool results never leak into the parent's session store.
117
+ // Exact results remain in the child's owned session, separate from the parent.
92
118
  toolResponseStore = new ToolResponseStore();
119
+ sessionId;
93
120
  discoveredTools = new Set();
94
121
  hooks;
95
122
  approvalRequester;
96
123
  constructor(config) {
97
- this.config = config;
124
+ this.config = { ...config, commandPolicy: config.commandPolicy === undefined ? undefined : structuredClone(config.commandPolicy) };
125
+ this.sessionId = config.resumeSessionId ?? `subagent-${randomUUID()}`;
98
126
  this.backend = config.backend ?? createBackend(config.provider, config.apiKey);
99
127
  this.model = getSubAgentModel(config.provider, config.model);
100
- this.cwd = config.cwd || process.cwd();
128
+ this.cwd = realpathSync(config.cwd || process.cwd());
101
129
  this.hooks = config.hooks;
102
130
  this.approvalRequester = config.approvalRequester;
103
131
  debug('Created SubAgent with model=%s, cwd=%s, timeout=%dms', this.model, this.cwd, config.timeoutMs || 120000);
104
132
  }
133
+ getSessionId() { return this.sessionId; }
134
+ getEvidenceSnapshot() { return this.toolResponseStore.evidence.getSnapshot(); }
135
+ getEvidenceHandoff(summary = '') {
136
+ return createDelegatedEvidenceHandoff({ sessionId: this.sessionId, parentSessionId: this.config.parentSessionId }, this.getEvidenceSnapshot(), summary);
137
+ }
105
138
  /**
106
139
  * Run a task and return a summary.
107
140
  *
@@ -109,9 +142,15 @@ export class SubAgent {
109
142
  * @param opts Optional overrides (abort signal, custom system prompt, tools)
110
143
  */
111
144
  async run(task, opts) {
145
+ if (this.backend.getModelCapabilities?.(this.model)?.tools === false)
146
+ throw new Error('Chat-only models cannot run tool-dependent subagents.');
112
147
  const signal = opts?.signal;
113
148
  const startTime = Date.now();
114
149
  const timeoutMs = this.config.timeoutMs || 120000; // 2 minute default
150
+ const deadlineAt = startTime + timeoutMs;
151
+ const deadline = new AbortController();
152
+ const runSignal = signal ? AbortSignal.any([signal, deadline.signal]) : deadline.signal;
153
+ const commandSessionId = this.sessionId;
115
154
  const maxIterations = this.config.maxIterations || 5;
116
155
  let iterations = 0;
117
156
  let finalContent = '';
@@ -130,9 +169,18 @@ export class SubAgent {
130
169
  // This summary-producing worker does not own the parent checklist or
131
170
  // terminal answer lifecycle.
132
171
  const tools = (opts?.tools ?? RESEARCH_TOOLS).filter(tool => !tool.finalResponse);
172
+ // A native host supplies a closed, bounded vocabulary. Adding ambient
173
+ // helper schemas can reject that otherwise valid request before dispatch.
174
+ if (!this.backend.preservesNativeHistory || opts?.tools === undefined) {
175
+ for (const tool of [recallToolResponseTool, sessionEvidenceTool]) {
176
+ if (!tools.some(existing => existing.definition.name === tool.definition.name))
177
+ tools.push(tool);
178
+ }
179
+ }
133
180
  const messages = [
181
+ ...structuredClone(opts?.messages ?? []),
134
182
  {
135
- id: 'task_0',
183
+ id: `task_${randomUUID()}`,
136
184
  role: 'user',
137
185
  content: task,
138
186
  timestamp: new Date()
@@ -140,36 +188,69 @@ export class SubAgent {
140
188
  ];
141
189
  // Helper to check timeout
142
190
  const checkTimeout = () => {
191
+ if (signal?.aborted)
192
+ throw new Error('Sub-agent cancelled');
143
193
  const elapsed = Date.now() - startTime;
144
- if (elapsed > timeoutMs) {
194
+ if (elapsed >= timeoutMs || deadline.signal.aborted) {
145
195
  throw new Error(`Sub-agent timed out after ${Math.round(elapsed / 1000)}s (limit: ${Math.round(timeoutMs / 1000)}s)`);
146
196
  }
147
197
  };
198
+ const deadlineTimer = setTimeout(() => deadline.abort(), timeoutMs);
199
+ let releaseWriter;
200
+ let evidenceBound = false;
201
+ const publishEvidence = () => {
202
+ opts?.onEvent?.({ type: 'evidence', sessionId: this.sessionId, snapshot: this.getEvidenceSnapshot() });
203
+ };
148
204
  try {
205
+ releaseWriter = await acquireDelegatedEvidenceWriter({ sessionId: this.sessionId,
206
+ parentSessionId: this.config.parentSessionId, cwd: this.cwd });
207
+ await bindDelegatedEvidence(this.toolResponseStore, this.discoveredTools, { sessionId: this.sessionId, parentSessionId: this.config.parentSessionId, cwd: this.cwd }, this.config.resumeSessionId !== undefined);
208
+ evidenceBound = true;
209
+ await this.persistEvidenceCheckpoint();
210
+ publishEvidence();
149
211
  while (iterations < maxIterations) {
150
- if (signal?.aborted)
151
- throw new Error('Sub-agent cancelled');
152
212
  checkTimeout();
153
213
  iterations++;
154
214
  debug('Iteration %d/%d', iterations, maxIterations);
215
+ const evidence = formatEvidenceContext(this.getEvidenceSnapshot());
216
+ const executionContext = describeExecutionContext({
217
+ mode: 'delegated worker', cwd: this.cwd, tools: tools.map(tool => tool.definition.name),
218
+ mux: false, configScope: configStore.getConfigScope(), maxTokens: 2048,
219
+ outputLimitSource: 'delegated worker budget', settings: resolveExecutionSettings(configStore.get().execution), jobs: listCommandJobs(commandSessionId),
220
+ });
221
+ if (this.backend.preservesNativeHistory) {
222
+ // Stamp current host observations into a new user row. Earlier rows
223
+ // and the signed native system prefix keep their original bytes.
224
+ messages.push({ id: `host_context_${randomUUID()}`, role: 'user',
225
+ content: [evidence, executionContext].filter(Boolean).join('\n\n'), timestamp: new Date(),
226
+ metadata: { synthetic: true, hostContext: true } });
227
+ }
228
+ const system = pinnedTaskSystem(systemPrompt, task) + (this.backend.preservesNativeHistory
229
+ ? '' : '\n\n' + evidence + '\n\n' + executionContext);
230
+ const definitions = tools.map(tool => tool.definition);
231
+ const contextId = nativeHistoryContextId(system, definitions);
155
232
  const request = {
156
233
  model: this.model,
157
234
  maxTokens: 2048,
158
235
  // R7 parity: pin the task in request.system so a long subagent run
159
236
  // can't lose the task framing the same way the main loop could (F9).
160
- system: pinnedTaskSystem(systemPrompt, task) + '\n\n' + describeExecutionContext({
161
- mode: 'delegated worker', cwd: this.cwd, tools: tools.map(tool => tool.definition.name),
162
- mux: false, configScope: configStore.getConfigScope(), maxTokens: 2048,
163
- outputLimitSource: 'delegated worker budget', settings: resolveExecutionSettings(configStore.get().execution), jobs: [],
164
- }),
165
- messages: this.formatMessages(messages),
166
- tools: tools.map(t => t.definition),
237
+ system,
238
+ messages: this.formatMessages(messages, contextId),
239
+ tools: definitions,
167
240
  // The inherited backend is pinned to the parent conversation; this is
168
241
  // what tells it the prefix being sent is this run's instead.
169
242
  agentRunId: this.agentRunId,
170
- signal,
243
+ signal: runSignal,
171
244
  };
172
- const response = await this.backend.generate(request);
245
+ const response = await this.backend.generate(request).catch(error => {
246
+ opts?.onUsage?.({ inputTokens: 0, outputTokens: 0, totalTokens: 0, estimated: true, unreported: true });
247
+ throw error;
248
+ });
249
+ if (response.usage)
250
+ opts?.onUsage?.(response.usage);
251
+ else
252
+ opts?.onUsage?.({ inputTokens: 0, outputTokens: 0, totalTokens: 0, estimated: true, unreported: true });
253
+ checkTimeout();
173
254
  // Normalize content to array — some backends/proxies may return a string
174
255
  if (!Array.isArray(response.content)) {
175
256
  const raw = response.content;
@@ -189,8 +270,47 @@ export class SubAgent {
189
270
  if (isIncompleteModelResponse(response.stopReason)) {
190
271
  throw new Error(incompleteModelResponseMessage(response.stopReason, request.maxTokens, response.usage?.outputTokens));
191
272
  }
273
+ if (response.stopReason === 'refusal')
274
+ throw new Error('The model declined this request.');
192
275
  // Check for tool use
193
- const toolUseBlocks = response.content.filter(isToolUseBlock);
276
+ const requestedToolBlocks = response.content.filter(isToolUseBlock);
277
+ const requestedIds = new Set();
278
+ for (const block of requestedToolBlocks) {
279
+ if (requestedIds.has(block.id)) {
280
+ throw new Error(`Provider response contains duplicate tool invocation ID ${block.id}; no call in this batch was executed.`);
281
+ }
282
+ requestedIds.add(block.id);
283
+ }
284
+ // Provider IDs describe this response, rather than retries of an owned
285
+ // operation. Allocate storage-safe identities before any tool effect,
286
+ // retaining the delegated source store's narrower 200-byte boundary.
287
+ const historicalIds = new Set(messages.flatMap(message => message.toolCalls?.map(call => call.id) ?? []));
288
+ const occupiedIds = new Set([...historicalIds, ...requestedIds]);
289
+ const toolUseBlocks = [];
290
+ for (const block of requestedToolBlocks) {
291
+ if (/^[A-Za-z0-9_-]{1,200}$/.test(block.id)
292
+ && !historicalIds.has(block.id) && !await this.hasStoredToolIdentity(block.id)) {
293
+ toolUseBlocks.push(block);
294
+ continue;
295
+ }
296
+ let id;
297
+ let identityAttempts = 0;
298
+ do {
299
+ if (++identityAttempts > 16) {
300
+ throw new Error('Unable to allocate a fresh tool invocation identity. Inspect retained source availability before retrying.');
301
+ }
302
+ id = `tool_${randomUUID()}`;
303
+ } while (occupiedIds.has(id) || await this.hasStoredToolIdentity(id));
304
+ occupiedIds.add(id);
305
+ toolUseBlocks.push({ ...block, id });
306
+ }
307
+ if (this.backend.preservesNativeHistory && toolUseBlocks.length > 0) {
308
+ // Keep signed/opaque native blocks intact while pairing tool-use IDs
309
+ // with the canonical result identities admitted above.
310
+ const canonicalIds = new Map(requestedToolBlocks.map((block, index) => [block.id, toolUseBlocks[index].id]));
311
+ response.content = response.content.map(block => isToolUseBlock(block)
312
+ ? { ...block, id: canonicalIds.get(block.id) } : block);
313
+ }
194
314
  if (toolUseBlocks.length === 0) {
195
315
  // No tools, extract final response
196
316
  const textBlocks = response.content.filter(isTextBlock);
@@ -202,8 +322,15 @@ export class SubAgent {
202
322
  }
203
323
  debug('Executing %d tool(s): %s', toolUseBlocks.length, toolUseBlocks.map(tb => tb.name).join(', '));
204
324
  // Execute tools and track what was accessed
325
+ const toolUseMessageId = `assistant_${randomUUID()}`;
205
326
  const toolResults = await scheduleToolBatch(toolUseBlocks, tools, configStore.get().execution ?? {}, async (toolBlock, skipReason) => {
327
+ // Leave room for .json and its atomic-write suffix on 255-byte filesystems.
328
+ if (!/^[A-Za-z0-9_-]{1,200}$/.test(toolBlock.id))
329
+ throw new Error('Invalid delegated tool-call identity');
330
+ let retainingSource = false;
206
331
  try {
332
+ if (this.toolResponseStore.getMeta(toolBlock.id))
333
+ throw new Error('Delegated tool call identity already retained; recall the original source using a fresh call ID.');
207
334
  if (skipReason)
208
335
  throw new Error(skipReason);
209
336
  checkTimeout();
@@ -213,8 +340,12 @@ export class SubAgent {
213
340
  context: {
214
341
  cwd: this.cwd,
215
342
  toolCallId: toolBlock.id,
216
- signal,
343
+ onUsage: opts?.onUsage,
344
+ sessionId: commandSessionId,
345
+ managedCommandWaitSliceMs: 0,
346
+ signal: runSignal,
217
347
  temporaryWriteRoot: this.config.temporaryWriteRoot,
348
+ commandPolicy: this.config.commandPolicy,
218
349
  toolResponseStore: this.toolResponseStore,
219
350
  discoveredTools: this.discoveredTools,
220
351
  availableTools: tools,
@@ -229,21 +360,40 @@ export class SubAgent {
229
360
  if (!result.isError) {
230
361
  this.trackToolUsage(toolBlock.name, result.effectiveArgs, result.content);
231
362
  }
363
+ retainingSource = true;
364
+ const source = this.evidenceSource(toolBlock.id, toolBlock.name, result.effectiveArgs, result.managedCommand);
365
+ if (result.verificationReceipt) {
366
+ source.origin = 'host_receipt';
367
+ source.verification = result.verificationReceipt;
368
+ }
369
+ const rendered = this.toolResponseStore.put(toolBlock.id, toolBlock.name, result.content, Boolean(runSignal.aborted || result.contentTruncated || result.managedCommand?.result.has_more || result.managedCommand?.result.output_truncated), { args: result.effectiveArgs, isError: result.isError, source: { ...source, messageId: toolUseMessageId } }).rendered;
370
+ await this.toolResponseStore.flush();
371
+ retainingSource = false;
372
+ publishEvidence();
232
373
  return {
233
374
  is_error: result.isError,
234
375
  tool_use_id: toolBlock.id,
235
- content: applyRepeatGuard(toolBlock.name, toolBlock.input, result.isError ? `Error: ${result.content}` : result.content),
376
+ managedCommand: result.managedCommand,
377
+ content: applyRepeatGuard(toolBlock.name, toolBlock.input, result.isError ? `Error: ${rendered}` : rendered, result.isError ? undefined : result.managedCommand),
236
378
  };
237
379
  }
238
380
  catch (err) {
381
+ // Source retention failure or reused identity must stop inference;
382
+ // neither establishes that an already dispatched effect did not run.
383
+ if (retainingSource || this.toolResponseStore.getMeta(toolBlock.id))
384
+ throw err;
239
385
  debug('Tool %s failed: %s', toolBlock.name, err.message);
386
+ const content = `Error: ${err.message}`;
387
+ this.toolResponseStore.put(toolBlock.id, toolBlock.name, content, runSignal.aborted, { args: toolBlock.input, isError: true, source: { ...this.evidenceSource(toolBlock.id, toolBlock.name, toolBlock.input), messageId: toolUseMessageId } });
388
+ await this.toolResponseStore.flush();
389
+ publishEvidence();
240
390
  return {
241
391
  is_error: true,
242
392
  tool_use_id: toolBlock.id,
243
- content: `Error: ${err.message}`
393
+ content,
244
394
  };
245
395
  }
246
- }, result => result.is_error || commandStillRunning(result.content), signal);
396
+ }, result => result.is_error || result.managedCommand?.result.status === 'running' || commandStillRunning(result.content), runSignal);
247
397
  opts?.onIteration?.({
248
398
  iteration: iterations,
249
399
  max: maxIterations,
@@ -255,9 +405,10 @@ export class SubAgent {
255
405
  .map(b => b.text)
256
406
  .join('\n');
257
407
  messages.push({
258
- id: `assistant_${iterations}`,
408
+ id: toolUseMessageId,
259
409
  role: 'assistant',
260
410
  content: textContent || '[Using tools...]',
411
+ ...(this.backend.preservesNativeHistory ? { nativeContent: structuredClone(response.content), nativeModel: this.model, nativeContextId: contextId } : {}),
261
412
  timestamp: new Date(),
262
413
  toolCalls: toolUseBlocks.map(tb => ({
263
414
  id: tb.id,
@@ -274,19 +425,39 @@ export class SubAgent {
274
425
  messages.push({
275
426
  id: `tool_${iterations}`,
276
427
  role: 'user',
277
- content: JSON.stringify(toolResults),
428
+ content: JSON.stringify(toolResults.map(({ managedCommand: _observation, ...result }) => result)),
278
429
  timestamp: new Date()
279
430
  });
431
+ checkTimeout();
280
432
  const recoveryAction = recovery(toolResults.map((result, index) => ({
281
433
  name: toolUseBlocks[index].name, content: result.content, isError: result.is_error,
434
+ managedCommand: result.managedCommand,
282
435
  })));
283
436
  if (recoveryAction === 'stop')
284
437
  throw new Error('Automatic recovery budget exhausted after repeated tool failures.');
285
438
  if (recoveryAction === 'recover')
286
439
  messages.push({ id: `recovery_${iterations}`, role: 'user',
287
440
  content: 'Repeated failures: inspect current capabilities, then try one changed recovery approach. Do not repeat the failing sequence.', timestamp: new Date() });
441
+ if (iterations < maxIterations && toolResults.every(result => !result.is_error && result.managedCommand !== undefined)) {
442
+ const waiting = await awaitManagedCommandProgress(toolResults.map(result => ({
443
+ ...result.managedCommand, toolCallId: result.tool_use_id,
444
+ })), { signal: runSignal, deadlineAt, emit: opts?.onEvent });
445
+ checkTimeout();
446
+ if (waiting.waited) {
447
+ for (const observation of waiting.observations) {
448
+ this.toolResponseStore.put(`wait_${randomUUID()}`, 'read_command', JSON.stringify(observation.result), Boolean(observation.result.has_more || observation.result.output_truncated), { source: { ...this.evidenceSource(observation.toolCallId, 'read_command', {}, observation), originToolCallId: observation.toolCallId } });
449
+ }
450
+ await this.toolResponseStore.flush();
451
+ publishEvidence();
452
+ }
453
+ if (waiting.waited)
454
+ messages.push({ id: `command_observation_${randomUUID()}`, role: 'user',
455
+ content: formatManagedCommandObservations(waiting.observations), timestamp: new Date(),
456
+ metadata: { synthetic: true, hostContext: true } });
457
+ }
288
458
  }
289
459
  const durationMs = Date.now() - startTime;
460
+ await this.persistEvidenceCheckpoint();
290
461
  // Exhausted maxIterations while still requesting tools = did NOT finish.
291
462
  const exhausted = !completedCleanly;
292
463
  const success = !exhausted;
@@ -308,6 +479,7 @@ export class SubAgent {
308
479
  });
309
480
  }
310
481
  return {
482
+ evidence: this.getEvidenceHandoff(finalContent),
311
483
  summary: finalContent || 'Sub-agent completed but produced no summary.',
312
484
  filesRead: Array.from(this.filesRead),
313
485
  commandsRun: this.commandsRun,
@@ -324,7 +496,15 @@ export class SubAgent {
324
496
  }
325
497
  catch (err) {
326
498
  const durationMs = Date.now() - startTime;
327
- const errMsg = err.message;
499
+ let errMsg = err.message;
500
+ // Reads and inference receive the combined signal. Keep the public worker
501
+ // outcome specific to its controlling deadline or the user's cancellation.
502
+ try {
503
+ checkTimeout();
504
+ }
505
+ catch (controlError) {
506
+ errMsg = controlError.message;
507
+ }
328
508
  debug('Task failed after %dms: %s', durationMs, errMsg);
329
509
  if (this.hooks) {
330
510
  await this.hooks.dispatch('SubagentStop', {
@@ -341,6 +521,7 @@ export class SubAgent {
341
521
  });
342
522
  }
343
523
  return {
524
+ evidence: this.getEvidenceHandoff(''),
344
525
  summary: '',
345
526
  filesRead: Array.from(this.filesRead),
346
527
  commandsRun: this.commandsRun,
@@ -355,6 +536,54 @@ export class SubAgent {
355
536
  durationMs
356
537
  };
357
538
  }
539
+ finally {
540
+ clearTimeout(deadlineTimer);
541
+ if (releaseWriter) {
542
+ try {
543
+ if (evidenceBound)
544
+ await shutdownCommandJobs(commandSessionId);
545
+ }
546
+ finally {
547
+ await releaseWriter();
548
+ }
549
+ }
550
+ }
551
+ }
552
+ async hasStoredToolIdentity(id) {
553
+ if (this.toolResponseStore.getMeta(id)
554
+ || this.toolResponseStore.evidence.getSnapshot().records.some(record => record.source.toolCallId === id))
555
+ return true;
556
+ try {
557
+ // A source can outlive its conversation row or arrive after binding.
558
+ // Missing indexed bodies and malformed originals still reserve their ID.
559
+ return await this.toolResponseStore.get(id) !== null;
560
+ }
561
+ catch (error) {
562
+ if (error instanceof ToolResponseIntegrityError)
563
+ return true;
564
+ throw error;
565
+ }
566
+ }
567
+ async persistEvidenceCheckpoint() {
568
+ await this.toolResponseStore.flush();
569
+ // Delegated instructions originate with the parent model, not the user.
570
+ // Save a canonical evidence checkpoint without synthesizing user directives
571
+ // or transferring a child conversation's permissions through task handoff.
572
+ await saveSessionToFile(getSessionPathForCwd(this.cwd, this.sessionId), this.sessionId, this.cwd, [], this.model, this.config.provider, undefined, undefined, { evidence: this.getEvidenceSnapshot(), mode: 'delegated' });
573
+ }
574
+ evidenceSource(toolCallId, toolName, args, managed) {
575
+ const source = { origin: managed ? 'host_receipt' : 'host_tool', toolCallId, toolName, cwd: this.cwd,
576
+ ...(typeof args.path === 'string' ? { path: args.path } : {}) };
577
+ if (managed) {
578
+ const result = managed.result;
579
+ source.job = { sessionId: managed.sessionId, jobId: result.job_id, status: result.status, exitCode: result.exit_code ?? null,
580
+ startedAt: result.started_at, endedAt: result.ended_at, cursor: result.cursor, hasMore: result.has_more, outputTruncated: Boolean(result.output_truncated),
581
+ ...(result.checked === undefined ? {} : { checked: result.checked }) };
582
+ source.artifact = { path: result.log_path };
583
+ if (result.verification)
584
+ source.verification = result.verification;
585
+ }
586
+ return source;
358
587
  }
359
588
  /**
360
589
  * Track what the sub-agent accessed
@@ -378,7 +607,15 @@ export class SubAgent {
378
607
  /**
379
608
  * Format messages for the API
380
609
  */
381
- formatMessages(messages) {
610
+ formatMessages(messages, contextId) {
611
+ if (this.backend.preservesNativeHistory) {
612
+ return new RequestEncoder({ preserveNativeHistory: true, model: this.model,
613
+ nativeContextId: contextId,
614
+ selectorVerdict: null,
615
+ currentTurnToolIds: new Set(messages.flatMap(message => message.toolCalls?.map(call => call.id) ?? [])),
616
+ renderForContext: () => null, loadImageBlock: () => null, loadVideoBlock: () => null,
617
+ }).encode(messages).messages;
618
+ }
382
619
  return messages
383
620
  .filter(m => m.role === 'user' || m.role === 'assistant')
384
621
  .map(m => {
@@ -0,0 +1,24 @@
1
+ export declare const TOOL_RESPONSE_DIRECTORY_ENTRY_LIMIT = 1024;
2
+ export declare const TOOL_RESPONSE_DIRECTORY_NAME_BYTE_LIMIT: number;
3
+ export declare const TOOL_RESPONSE_DIRECTORY_BUFFER_SIZE = 16;
4
+ export interface ToolResponseDirectoryAdmission {
5
+ status: 'not_bound' | 'complete' | 'limited' | 'failed';
6
+ complete: boolean;
7
+ directoryComplete: boolean;
8
+ reasons: Array<'directory_entry_limit' | 'candidate_name_byte_limit' | 'source_retention_limit' | 'directory_error'>;
9
+ directoryEntriesRead: number;
10
+ directoryEntryLimit: number;
11
+ candidateNames: number;
12
+ candidateNameBytes: number;
13
+ candidateNameByteLimit: number;
14
+ bufferSize: number;
15
+ admittedSources: number;
16
+ skippedSources: number;
17
+ errorCode?: string;
18
+ }
19
+ export declare function emptyDirectoryAdmission(): ToolResponseDirectoryAdmission;
20
+ /** Bound discovery independently of unrelated directory size; known index names take priority. */
21
+ export declare function collectResponseFilenames(directory: string, indexedNames: readonly string[]): Promise<{
22
+ files: string[];
23
+ admission: ToolResponseDirectoryAdmission;
24
+ }>;
@@ -0,0 +1,61 @@
1
+ import { opendir } from 'node:fs/promises';
2
+ import { EVIDENCE_MAX_RECORDS } from './runtime/evidence.js';
3
+ export const TOOL_RESPONSE_DIRECTORY_ENTRY_LIMIT = 1024;
4
+ export const TOOL_RESPONSE_DIRECTORY_NAME_BYTE_LIMIT = 64 * 1024;
5
+ export const TOOL_RESPONSE_DIRECTORY_BUFFER_SIZE = 16;
6
+ export function emptyDirectoryAdmission() {
7
+ return { status: 'not_bound', complete: false, directoryComplete: false, reasons: [],
8
+ directoryEntriesRead: 0, directoryEntryLimit: TOOL_RESPONSE_DIRECTORY_ENTRY_LIMIT,
9
+ candidateNames: 0, candidateNameBytes: 0, candidateNameByteLimit: TOOL_RESPONSE_DIRECTORY_NAME_BYTE_LIMIT,
10
+ bufferSize: TOOL_RESPONSE_DIRECTORY_BUFFER_SIZE, admittedSources: 0, skippedSources: 0 };
11
+ }
12
+ /** Bound discovery independently of unrelated directory size; known index names take priority. */
13
+ export async function collectResponseFilenames(directory, indexedNames) {
14
+ const admission = emptyDirectoryAdmission();
15
+ if (indexedNames.length > EVIDENCE_MAX_RECORDS * 2)
16
+ throw new RangeError('Indexed source filenames exceed the bounded evidence capacity');
17
+ const indexed = new Set(indexedNames);
18
+ const files = [...indexed].sort();
19
+ const discovered = new Set();
20
+ admission.candidateNameBytes = files.reduce((sum, name) => sum + Buffer.byteLength(name), 0);
21
+ if (admission.candidateNameBytes > admission.candidateNameByteLimit)
22
+ throw new RangeError('Indexed source filename metadata exceeds its admission byte limit');
23
+ const handle = await opendir(directory, { bufferSize: TOOL_RESPONSE_DIRECTORY_BUFFER_SIZE });
24
+ // A boundary failure must close the descriptor even when an iterator rejects its next read.
25
+ try {
26
+ for await (const entry of handle) {
27
+ admission.directoryEntriesRead++;
28
+ if (admission.directoryEntriesRead > admission.directoryEntryLimit) {
29
+ admission.reasons.push('directory_entry_limit');
30
+ break;
31
+ }
32
+ const name = entry.name;
33
+ if (name === '.evidence.json' || !name.endsWith('.json') || indexed.has(name))
34
+ continue;
35
+ const size = Buffer.byteLength(name);
36
+ if (admission.candidateNameBytes + size > admission.candidateNameByteLimit) {
37
+ admission.reasons.push('candidate_name_byte_limit');
38
+ break;
39
+ }
40
+ if (discovered.has(name))
41
+ continue;
42
+ discovered.add(name);
43
+ admission.candidateNameBytes += size;
44
+ }
45
+ }
46
+ finally {
47
+ try {
48
+ await handle.close();
49
+ }
50
+ catch (error) {
51
+ if (error.code !== 'ERR_DIR_CLOSED')
52
+ throw error;
53
+ }
54
+ }
55
+ files.push(...[...discovered].sort());
56
+ admission.candidateNames = files.length;
57
+ admission.directoryComplete = admission.reasons.length === 0;
58
+ admission.complete = admission.directoryComplete;
59
+ admission.status = admission.complete ? 'complete' : 'limited';
60
+ return { files, admission };
61
+ }
@@ -0,0 +1,8 @@
1
+ import { type Stats } from 'node:fs';
2
+ /** A source cannot be admitted without its complete, stable, bounded bytes. */
3
+ export declare class SourceAdmissionError extends Error {
4
+ }
5
+ export declare function readBoundedSource(path: string, maximumBytes: number): Promise<{
6
+ text: string;
7
+ info: Stats;
8
+ }>;
@@ -0,0 +1,49 @@
1
+ import { constants } from 'node:fs';
2
+ import { lstat, open } from 'node:fs/promises';
3
+ import { TextDecoder } from 'node:util';
4
+ /** A source cannot be admitted without its complete, stable, bounded bytes. */
5
+ export class SourceAdmissionError extends Error {
6
+ }
7
+ export async function readBoundedSource(path, maximumBytes) {
8
+ if (!Number.isSafeInteger(maximumBytes) || maximumBytes < 1)
9
+ throw new RangeError('Invalid source byte admission limit');
10
+ // Nonblocking/no-follow protects a regular name changed to a FIFO or symlink.
11
+ const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
12
+ try {
13
+ const before = await handle.stat();
14
+ if (!before.isFile())
15
+ throw new SourceAdmissionError('Source admission requires a regular file');
16
+ if (!Number.isSafeInteger(before.size) || before.size < 0 || before.size > maximumBytes) {
17
+ throw new SourceAdmissionError(`Source exceeds byte admission limit (${maximumBytes})`);
18
+ }
19
+ // One sentinel byte catches growth even when a filesystem's stat timestamps are coarse.
20
+ const buffer = Buffer.allocUnsafe(before.size + 1);
21
+ let count = 0;
22
+ while (count < buffer.length) {
23
+ const { bytesRead } = await handle.read(buffer, count, Math.min(65536, buffer.length - count), count);
24
+ if (bytesRead === 0)
25
+ break;
26
+ count += bytesRead;
27
+ }
28
+ const after = await handle.stat();
29
+ const named = await lstat(path);
30
+ if (count > maximumBytes)
31
+ throw new SourceAdmissionError(`Source exceeds byte admission limit (${maximumBytes})`);
32
+ if (count !== before.size || after.size !== before.size || after.mtimeMs !== before.mtimeMs || after.ctimeMs !== before.ctimeMs
33
+ || !named.isFile() || named.dev !== before.dev || named.ino !== before.ino
34
+ || named.size !== before.size || named.mtimeMs !== before.mtimeMs || named.ctimeMs !== before.ctimeMs) {
35
+ throw new SourceAdmissionError('Source changed during bounded admission');
36
+ }
37
+ let text;
38
+ try {
39
+ text = new TextDecoder('utf-8', { fatal: true }).decode(buffer.subarray(0, count));
40
+ }
41
+ catch {
42
+ throw new SourceAdmissionError('Source admission requires valid UTF-8 bytes');
43
+ }
44
+ return { text, info: before };
45
+ }
46
+ finally {
47
+ await handle.close();
48
+ }
49
+ }