@cjhyy/code-shell-core 0.5.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (484) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/dist/agent/coordinator.d.ts +49 -0
  4. package/dist/agent/coordinator.js +77 -0
  5. package/dist/arena/arena.d.ts +43 -0
  6. package/dist/arena/arena.js +334 -0
  7. package/dist/arena/context/context-tools.d.ts +16 -0
  8. package/dist/arena/context/context-tools.js +231 -0
  9. package/dist/arena/detect-mode.d.ts +20 -0
  10. package/dist/arena/detect-mode.js +78 -0
  11. package/dist/arena/digest-builder.d.ts +25 -0
  12. package/dist/arena/digest-builder.js +120 -0
  13. package/dist/arena/index.d.ts +29 -0
  14. package/dist/arena/index.js +29 -0
  15. package/dist/arena/iterate/convergence.d.ts +25 -0
  16. package/dist/arena/iterate/convergence.js +103 -0
  17. package/dist/arena/iterate/formats/index.d.ts +22 -0
  18. package/dist/arena/iterate/formats/index.js +283 -0
  19. package/dist/arena/iterate/index.d.ts +11 -0
  20. package/dist/arena/iterate/index.js +9 -0
  21. package/dist/arena/iterate/iterative-arena.d.ts +23 -0
  22. package/dist/arena/iterate/iterative-arena.js +237 -0
  23. package/dist/arena/iterate/parse.d.ts +42 -0
  24. package/dist/arena/iterate/parse.js +123 -0
  25. package/dist/arena/iterate/phases/argue.d.ts +22 -0
  26. package/dist/arena/iterate/phases/argue.js +159 -0
  27. package/dist/arena/iterate/phases/revise.d.ts +16 -0
  28. package/dist/arena/iterate/phases/revise.js +62 -0
  29. package/dist/arena/iterate/phases/tournament.d.ts +34 -0
  30. package/dist/arena/iterate/phases/tournament.js +113 -0
  31. package/dist/arena/iterate/tools/web-tools.d.ts +13 -0
  32. package/dist/arena/iterate/tools/web-tools.js +54 -0
  33. package/dist/arena/iterate/types.d.ts +152 -0
  34. package/dist/arena/iterate/types.js +8 -0
  35. package/dist/arena/ledger.d.ts +47 -0
  36. package/dist/arena/ledger.js +151 -0
  37. package/dist/arena/lenses/architecture.d.ts +5 -0
  38. package/dist/arena/lenses/architecture.js +22 -0
  39. package/dist/arena/lenses/engineering.d.ts +5 -0
  40. package/dist/arena/lenses/engineering.js +22 -0
  41. package/dist/arena/lenses/general.d.ts +5 -0
  42. package/dist/arena/lenses/general.js +20 -0
  43. package/dist/arena/lenses/index.d.ts +16 -0
  44. package/dist/arena/lenses/index.js +47 -0
  45. package/dist/arena/lenses/product.d.ts +5 -0
  46. package/dist/arena/lenses/product.js +22 -0
  47. package/dist/arena/model-presets.d.ts +23 -0
  48. package/dist/arena/model-presets.js +44 -0
  49. package/dist/arena/phases/adjudication.d.ts +24 -0
  50. package/dist/arena/phases/adjudication.js +144 -0
  51. package/dist/arena/phases/build-consensus.d.ts +29 -0
  52. package/dist/arena/phases/build-consensus.js +86 -0
  53. package/dist/arena/phases/claim-registry.d.ts +26 -0
  54. package/dist/arena/phases/claim-registry.js +60 -0
  55. package/dist/arena/phases/cross-review.d.ts +45 -0
  56. package/dist/arena/phases/cross-review.js +224 -0
  57. package/dist/arena/phases/debate-rounds.d.ts +27 -0
  58. package/dist/arena/phases/debate-rounds.js +162 -0
  59. package/dist/arena/phases/participant-research.d.ts +38 -0
  60. package/dist/arena/phases/participant-research.js +317 -0
  61. package/dist/arena/phases/planning-detail-expansion.d.ts +38 -0
  62. package/dist/arena/phases/planning-detail-expansion.js +121 -0
  63. package/dist/arena/planner.d.ts +27 -0
  64. package/dist/arena/planner.js +312 -0
  65. package/dist/arena/providers/docs.d.ts +6 -0
  66. package/dist/arena/providers/docs.js +108 -0
  67. package/dist/arena/providers/git.d.ts +8 -0
  68. package/dist/arena/providers/git.js +174 -0
  69. package/dist/arena/providers/index.d.ts +32 -0
  70. package/dist/arena/providers/index.js +132 -0
  71. package/dist/arena/providers/none.d.ts +7 -0
  72. package/dist/arena/providers/none.js +11 -0
  73. package/dist/arena/providers/repo.d.ts +6 -0
  74. package/dist/arena/providers/repo.js +255 -0
  75. package/dist/arena/render/session.d.ts +17 -0
  76. package/dist/arena/render/session.js +190 -0
  77. package/dist/arena/render/terminal.d.ts +34 -0
  78. package/dist/arena/render/terminal.js +286 -0
  79. package/dist/arena/strategies/discussion.d.ts +25 -0
  80. package/dist/arena/strategies/discussion.js +143 -0
  81. package/dist/arena/strategies/index.d.ts +15 -0
  82. package/dist/arena/strategies/index.js +28 -0
  83. package/dist/arena/strategies/language-wrapper.d.ts +17 -0
  84. package/dist/arena/strategies/language-wrapper.js +102 -0
  85. package/dist/arena/strategies/lens-wrapper.d.ts +16 -0
  86. package/dist/arena/strategies/lens-wrapper.js +236 -0
  87. package/dist/arena/strategies/planning.d.ts +30 -0
  88. package/dist/arena/strategies/planning.js +225 -0
  89. package/dist/arena/strategies/review.d.ts +26 -0
  90. package/dist/arena/strategies/review.js +168 -0
  91. package/dist/arena/strategies/utils.d.ts +39 -0
  92. package/dist/arena/strategies/utils.js +647 -0
  93. package/dist/arena/tools/selector.d.ts +17 -0
  94. package/dist/arena/tools/selector.js +61 -0
  95. package/dist/arena/transitions.d.ts +48 -0
  96. package/dist/arena/transitions.js +92 -0
  97. package/dist/arena/types.d.ts +508 -0
  98. package/dist/arena/types.js +27 -0
  99. package/dist/cli/agent-server-stdio.d.ts +32 -0
  100. package/dist/cli/agent-server-stdio.js +116 -0
  101. package/dist/colorizer.d.ts +23 -0
  102. package/dist/colorizer.js +12 -0
  103. package/dist/context/compaction.d.ts +116 -0
  104. package/dist/context/compaction.js +534 -0
  105. package/dist/context/manager.d.ts +145 -0
  106. package/dist/context/manager.js +423 -0
  107. package/dist/context/token-counter.d.ts +27 -0
  108. package/dist/context/token-counter.js +91 -0
  109. package/dist/context/tool-result-storage.d.ts +96 -0
  110. package/dist/context/tool-result-storage.js +296 -0
  111. package/dist/cost-tracker.d.ts +64 -0
  112. package/dist/cost-tracker.js +314 -0
  113. package/dist/cron/scheduler.d.ts +34 -0
  114. package/dist/cron/scheduler.js +115 -0
  115. package/dist/data/deepseek-models.json +46 -0
  116. package/dist/data/gemini-models.json +67 -0
  117. package/dist/data/openai-models.json +175 -0
  118. package/dist/data/openrouter-models.d.ts +35 -0
  119. package/dist/data/openrouter-models.js +36 -0
  120. package/dist/data/openrouter-models.json +4626 -0
  121. package/dist/data/openrouter-sync.d.ts +16 -0
  122. package/dist/data/openrouter-sync.js +53 -0
  123. package/dist/data/static-catalogs.d.ts +25 -0
  124. package/dist/data/static-catalogs.js +26 -0
  125. package/dist/data/zai-models.json +56 -0
  126. package/dist/engine/cost-store.d.ts +22 -0
  127. package/dist/engine/cost-store.js +15 -0
  128. package/dist/engine/engine.d.ts +295 -0
  129. package/dist/engine/engine.js +1467 -0
  130. package/dist/engine/model-facade.d.ts +24 -0
  131. package/dist/engine/model-facade.js +194 -0
  132. package/dist/engine/parse-task.d.ts +59 -0
  133. package/dist/engine/parse-task.js +135 -0
  134. package/dist/engine/patch-orphaned-tools.d.ts +52 -0
  135. package/dist/engine/patch-orphaned-tools.js +95 -0
  136. package/dist/engine/query.d.ts +50 -0
  137. package/dist/engine/query.js +107 -0
  138. package/dist/engine/runtime.d.ts +50 -0
  139. package/dist/engine/runtime.js +59 -0
  140. package/dist/engine/streaming-tool-queue.d.ts +34 -0
  141. package/dist/engine/streaming-tool-queue.js +61 -0
  142. package/dist/engine/token-budget.d.ts +22 -0
  143. package/dist/engine/token-budget.js +40 -0
  144. package/dist/engine/tool-summary.d.ts +13 -0
  145. package/dist/engine/tool-summary.js +35 -0
  146. package/dist/engine/turn-loop.d.ts +122 -0
  147. package/dist/engine/turn-loop.js +602 -0
  148. package/dist/engine/turn-state.d.ts +20 -0
  149. package/dist/engine/turn-state.js +17 -0
  150. package/dist/exceptions.d.ts +61 -0
  151. package/dist/exceptions.js +116 -0
  152. package/dist/git/utils.d.ts +35 -0
  153. package/dist/git/utils.js +98 -0
  154. package/dist/git/worktree.d.ts +36 -0
  155. package/dist/git/worktree.js +139 -0
  156. package/dist/hooks/events.d.ts +114 -0
  157. package/dist/hooks/events.js +4 -0
  158. package/dist/hooks/inject.d.ts +19 -0
  159. package/dist/hooks/inject.js +29 -0
  160. package/dist/hooks/registry.d.ts +15 -0
  161. package/dist/hooks/registry.js +84 -0
  162. package/dist/hooks/shell-runner.d.ts +45 -0
  163. package/dist/hooks/shell-runner.js +173 -0
  164. package/dist/index.d.ts +117 -0
  165. package/dist/index.js +145 -0
  166. package/dist/llm/api-key-sanitize.d.ts +22 -0
  167. package/dist/llm/api-key-sanitize.js +81 -0
  168. package/dist/llm/capabilities/index.d.ts +20 -0
  169. package/dist/llm/capabilities/index.js +39 -0
  170. package/dist/llm/capabilities/rules.d.ts +26 -0
  171. package/dist/llm/capabilities/rules.js +215 -0
  172. package/dist/llm/capabilities/types.d.ts +114 -0
  173. package/dist/llm/capabilities/types.js +24 -0
  174. package/dist/llm/client-base.d.ts +29 -0
  175. package/dist/llm/client-base.js +137 -0
  176. package/dist/llm/client-factory.d.ts +10 -0
  177. package/dist/llm/client-factory.js +29 -0
  178. package/dist/llm/model-cache.d.ts +21 -0
  179. package/dist/llm/model-cache.js +46 -0
  180. package/dist/llm/model-fetcher.d.ts +29 -0
  181. package/dist/llm/model-fetcher.js +282 -0
  182. package/dist/llm/model-pool.d.ts +95 -0
  183. package/dist/llm/model-pool.js +246 -0
  184. package/dist/llm/provider-catalog.d.ts +32 -0
  185. package/dist/llm/provider-catalog.js +50 -0
  186. package/dist/llm/provider-kinds.d.ts +21 -0
  187. package/dist/llm/provider-kinds.js +132 -0
  188. package/dist/llm/providers/anthropic.d.ts +19 -0
  189. package/dist/llm/providers/anthropic.js +267 -0
  190. package/dist/llm/providers/openai.d.ts +64 -0
  191. package/dist/llm/providers/openai.js +606 -0
  192. package/dist/llm/retry.d.ts +12 -0
  193. package/dist/llm/retry.js +17 -0
  194. package/dist/llm/stream-watchdog.d.ts +42 -0
  195. package/dist/llm/stream-watchdog.js +70 -0
  196. package/dist/llm/token-counter.d.ts +17 -0
  197. package/dist/llm/token-counter.js +36 -0
  198. package/dist/llm/types.d.ts +37 -0
  199. package/dist/llm/types.js +4 -0
  200. package/dist/logging/logger.d.ts +109 -0
  201. package/dist/logging/logger.js +390 -0
  202. package/dist/logging/sanitize-messages.d.ts +42 -0
  203. package/dist/logging/sanitize-messages.js +150 -0
  204. package/dist/logging/session-recorder.d.ts +90 -0
  205. package/dist/logging/session-recorder.js +304 -0
  206. package/dist/lsp/client.d.ts +41 -0
  207. package/dist/lsp/client.js +166 -0
  208. package/dist/lsp/manager.d.ts +40 -0
  209. package/dist/lsp/manager.js +124 -0
  210. package/dist/lsp/servers.d.ts +16 -0
  211. package/dist/lsp/servers.js +60 -0
  212. package/dist/migrate-models.d.ts +45 -0
  213. package/dist/migrate-models.js +179 -0
  214. package/dist/onboarding.d.ts +189 -0
  215. package/dist/onboarding.js +625 -0
  216. package/dist/plugins/gitOps.d.ts +32 -0
  217. package/dist/plugins/gitOps.js +62 -0
  218. package/dist/plugins/installedPlugins.d.ts +15 -0
  219. package/dist/plugins/installedPlugins.js +56 -0
  220. package/dist/plugins/knownMarketplaces.d.ts +10 -0
  221. package/dist/plugins/knownMarketplaces.js +46 -0
  222. package/dist/plugins/loadPluginHooks.d.ts +52 -0
  223. package/dist/plugins/loadPluginHooks.js +162 -0
  224. package/dist/plugins/marketplaceManager.d.ts +49 -0
  225. package/dist/plugins/marketplaceManager.js +142 -0
  226. package/dist/plugins/parseMarketplaceInput.d.ts +16 -0
  227. package/dist/plugins/parseMarketplaceInput.js +73 -0
  228. package/dist/plugins/pluginCommandHook.d.ts +54 -0
  229. package/dist/plugins/pluginCommandHook.js +180 -0
  230. package/dist/plugins/pluginCommandsLoader.d.ts +25 -0
  231. package/dist/plugins/pluginCommandsLoader.js +114 -0
  232. package/dist/plugins/pluginInstaller.d.ts +36 -0
  233. package/dist/plugins/pluginInstaller.js +228 -0
  234. package/dist/plugins/schemas.d.ts +9 -0
  235. package/dist/plugins/schemas.js +136 -0
  236. package/dist/plugins/types.d.ts +75 -0
  237. package/dist/plugins/types.js +7 -0
  238. package/dist/plugins/varRewrite.d.ts +42 -0
  239. package/dist/plugins/varRewrite.js +129 -0
  240. package/dist/preset/index.d.ts +60 -0
  241. package/dist/preset/index.js +159 -0
  242. package/dist/product/define.d.ts +60 -0
  243. package/dist/product/define.js +123 -0
  244. package/dist/product/index.d.ts +5 -0
  245. package/dist/product/index.js +4 -0
  246. package/dist/product/types.d.ts +111 -0
  247. package/dist/product/types.js +21 -0
  248. package/dist/prompt/composer.d.ts +49 -0
  249. package/dist/prompt/composer.js +168 -0
  250. package/dist/prompt/instruction-scanner.d.ts +54 -0
  251. package/dist/prompt/instruction-scanner.js +187 -0
  252. package/dist/prompt/section-cache.d.ts +15 -0
  253. package/dist/prompt/section-cache.js +31 -0
  254. package/dist/prompt/section-loader.d.ts +26 -0
  255. package/dist/prompt/section-loader.js +53 -0
  256. package/dist/prompt/sections/base.md +35 -0
  257. package/dist/prompt/sections/coding.md +31 -0
  258. package/dist/prompt/sections/orchestration.md +16 -0
  259. package/dist/prompt/sections/tone.md +9 -0
  260. package/dist/protocol/chat-session-manager.d.ts +33 -0
  261. package/dist/protocol/chat-session-manager.js +65 -0
  262. package/dist/protocol/chat-session.d.ts +49 -0
  263. package/dist/protocol/chat-session.js +86 -0
  264. package/dist/protocol/client.d.ts +104 -0
  265. package/dist/protocol/client.js +260 -0
  266. package/dist/protocol/factories.d.ts +93 -0
  267. package/dist/protocol/factories.js +64 -0
  268. package/dist/protocol/helpers.d.ts +42 -0
  269. package/dist/protocol/helpers.js +55 -0
  270. package/dist/protocol/index.d.ts +4 -0
  271. package/dist/protocol/index.js +4 -0
  272. package/dist/protocol/server.d.ts +80 -0
  273. package/dist/protocol/server.js +855 -0
  274. package/dist/protocol/transport.d.ts +37 -0
  275. package/dist/protocol/transport.js +85 -0
  276. package/dist/protocol/types.d.ts +221 -0
  277. package/dist/protocol/types.js +61 -0
  278. package/dist/remote/bridge.d.ts +37 -0
  279. package/dist/remote/bridge.js +103 -0
  280. package/dist/run/ArtifactTracker.d.ts +38 -0
  281. package/dist/run/ArtifactTracker.js +132 -0
  282. package/dist/run/CheckpointWriter.d.ts +53 -0
  283. package/dist/run/CheckpointWriter.js +135 -0
  284. package/dist/run/EngineRunner.d.ts +72 -0
  285. package/dist/run/EngineRunner.js +119 -0
  286. package/dist/run/Evaluator.d.ts +56 -0
  287. package/dist/run/Evaluator.js +62 -0
  288. package/dist/run/FileRunStore.d.ts +39 -0
  289. package/dist/run/FileRunStore.js +176 -0
  290. package/dist/run/Heartbeat.d.ts +54 -0
  291. package/dist/run/Heartbeat.js +123 -0
  292. package/dist/run/RunApprovalBackend.d.ts +53 -0
  293. package/dist/run/RunApprovalBackend.js +85 -0
  294. package/dist/run/RunLock.d.ts +40 -0
  295. package/dist/run/RunLock.js +98 -0
  296. package/dist/run/RunManager.d.ts +82 -0
  297. package/dist/run/RunManager.js +587 -0
  298. package/dist/run/RunQueue.d.ts +27 -0
  299. package/dist/run/RunQueue.js +73 -0
  300. package/dist/run/RunStore.d.ts +25 -0
  301. package/dist/run/RunStore.js +9 -0
  302. package/dist/run/factory.d.ts +63 -0
  303. package/dist/run/factory.js +51 -0
  304. package/dist/run/index.d.ts +17 -0
  305. package/dist/run/index.js +23 -0
  306. package/dist/run/types.d.ts +136 -0
  307. package/dist/run/types.js +28 -0
  308. package/dist/runtime/safe-spawn.d.ts +118 -0
  309. package/dist/runtime/safe-spawn.js +268 -0
  310. package/dist/services/analytics.d.ts +29 -0
  311. package/dist/services/analytics.js +84 -0
  312. package/dist/services/auto-dream.d.ts +49 -0
  313. package/dist/services/auto-dream.js +124 -0
  314. package/dist/services/diagnostics.d.ts +41 -0
  315. package/dist/services/diagnostics.js +99 -0
  316. package/dist/services/extract-memories.d.ts +31 -0
  317. package/dist/services/extract-memories.js +71 -0
  318. package/dist/services/index.d.ts +11 -0
  319. package/dist/services/index.js +17 -0
  320. package/dist/services/memory-orchestrator.d.ts +60 -0
  321. package/dist/services/memory-orchestrator.js +133 -0
  322. package/dist/services/notifier.d.ts +25 -0
  323. package/dist/services/notifier.js +69 -0
  324. package/dist/services/oauth.d.ts +27 -0
  325. package/dist/services/oauth.js +153 -0
  326. package/dist/services/session-memory.d.ts +37 -0
  327. package/dist/services/session-memory.js +81 -0
  328. package/dist/session/file-history.d.ts +41 -0
  329. package/dist/session/file-history.js +115 -0
  330. package/dist/session/memory.d.ts +104 -0
  331. package/dist/session/memory.js +310 -0
  332. package/dist/session/session-manager.d.ts +41 -0
  333. package/dist/session/session-manager.js +261 -0
  334. package/dist/session/transcript.d.ts +39 -0
  335. package/dist/session/transcript.js +186 -0
  336. package/dist/settings/manager.d.ts +36 -0
  337. package/dist/settings/manager.js +187 -0
  338. package/dist/settings/schema.d.ts +1219 -0
  339. package/dist/settings/schema.js +246 -0
  340. package/dist/skills/frontmatter.d.ts +13 -0
  341. package/dist/skills/frontmatter.js +70 -0
  342. package/dist/skills/index.d.ts +7 -0
  343. package/dist/skills/index.js +6 -0
  344. package/dist/skills/scanner.d.ts +31 -0
  345. package/dist/skills/scanner.js +171 -0
  346. package/dist/state.d.ts +160 -0
  347. package/dist/state.js +267 -0
  348. package/dist/tool-system/builtin/agent-notifications.d.ts +84 -0
  349. package/dist/tool-system/builtin/agent-notifications.js +197 -0
  350. package/dist/tool-system/builtin/agent-registry.d.ts +67 -0
  351. package/dist/tool-system/builtin/agent-registry.js +126 -0
  352. package/dist/tool-system/builtin/agent-transcript-translator.d.ts +22 -0
  353. package/dist/tool-system/builtin/agent-transcript-translator.js +160 -0
  354. package/dist/tool-system/builtin/agent.d.ts +16 -0
  355. package/dist/tool-system/builtin/agent.js +364 -0
  356. package/dist/tool-system/builtin/apply-patch/applier.d.ts +26 -0
  357. package/dist/tool-system/builtin/apply-patch/applier.js +250 -0
  358. package/dist/tool-system/builtin/apply-patch/index.d.ts +20 -0
  359. package/dist/tool-system/builtin/apply-patch/index.js +101 -0
  360. package/dist/tool-system/builtin/apply-patch/parser.d.ts +17 -0
  361. package/dist/tool-system/builtin/apply-patch/parser.js +212 -0
  362. package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +18 -0
  363. package/dist/tool-system/builtin/apply-patch/seek-sequence.js +123 -0
  364. package/dist/tool-system/builtin/apply-patch/types.d.ts +49 -0
  365. package/dist/tool-system/builtin/apply-patch/types.js +13 -0
  366. package/dist/tool-system/builtin/arena.d.ts +31 -0
  367. package/dist/tool-system/builtin/arena.js +416 -0
  368. package/dist/tool-system/builtin/ask-user.d.ts +20 -0
  369. package/dist/tool-system/builtin/ask-user.js +99 -0
  370. package/dist/tool-system/builtin/bash.d.ts +21 -0
  371. package/dist/tool-system/builtin/bash.js +149 -0
  372. package/dist/tool-system/builtin/brief.d.ts +6 -0
  373. package/dist/tool-system/builtin/brief.js +41 -0
  374. package/dist/tool-system/builtin/config.d.ts +6 -0
  375. package/dist/tool-system/builtin/config.js +67 -0
  376. package/dist/tool-system/builtin/cron.d.ts +10 -0
  377. package/dist/tool-system/builtin/cron.js +61 -0
  378. package/dist/tool-system/builtin/edit.d.ts +6 -0
  379. package/dist/tool-system/builtin/edit.js +100 -0
  380. package/dist/tool-system/builtin/file-cache.d.ts +11 -0
  381. package/dist/tool-system/builtin/file-cache.js +39 -0
  382. package/dist/tool-system/builtin/glob.d.ts +7 -0
  383. package/dist/tool-system/builtin/glob.js +76 -0
  384. package/dist/tool-system/builtin/grep.d.ts +7 -0
  385. package/dist/tool-system/builtin/grep.js +150 -0
  386. package/dist/tool-system/builtin/index.d.ts +20 -0
  387. package/dist/tool-system/builtin/index.js +449 -0
  388. package/dist/tool-system/builtin/lsp.d.ts +6 -0
  389. package/dist/tool-system/builtin/lsp.js +141 -0
  390. package/dist/tool-system/builtin/mcp-tools.d.ts +10 -0
  391. package/dist/tool-system/builtin/mcp-tools.js +102 -0
  392. package/dist/tool-system/builtin/memory.d.ts +26 -0
  393. package/dist/tool-system/builtin/memory.js +226 -0
  394. package/dist/tool-system/builtin/notebook-edit.d.ts +6 -0
  395. package/dist/tool-system/builtin/notebook-edit.js +124 -0
  396. package/dist/tool-system/builtin/plan.d.ts +15 -0
  397. package/dist/tool-system/builtin/plan.js +55 -0
  398. package/dist/tool-system/builtin/powershell.d.ts +11 -0
  399. package/dist/tool-system/builtin/powershell.js +64 -0
  400. package/dist/tool-system/builtin/read.d.ts +6 -0
  401. package/dist/tool-system/builtin/read.js +70 -0
  402. package/dist/tool-system/builtin/remote-trigger.d.ts +6 -0
  403. package/dist/tool-system/builtin/remote-trigger.js +54 -0
  404. package/dist/tool-system/builtin/repl.d.ts +11 -0
  405. package/dist/tool-system/builtin/repl.js +82 -0
  406. package/dist/tool-system/builtin/send-message.d.ts +6 -0
  407. package/dist/tool-system/builtin/send-message.js +47 -0
  408. package/dist/tool-system/builtin/skill-prompt.d.ts +20 -0
  409. package/dist/tool-system/builtin/skill-prompt.js +52 -0
  410. package/dist/tool-system/builtin/skill.d.ts +9 -0
  411. package/dist/tool-system/builtin/skill.js +55 -0
  412. package/dist/tool-system/builtin/sleep.d.ts +6 -0
  413. package/dist/tool-system/builtin/sleep.js +33 -0
  414. package/dist/tool-system/builtin/task.d.ts +48 -0
  415. package/dist/tool-system/builtin/task.js +139 -0
  416. package/dist/tool-system/builtin/tool-search.d.ts +11 -0
  417. package/dist/tool-system/builtin/tool-search.js +90 -0
  418. package/dist/tool-system/builtin/web-fetch.d.ts +10 -0
  419. package/dist/tool-system/builtin/web-fetch.js +328 -0
  420. package/dist/tool-system/builtin/web-search.d.ts +25 -0
  421. package/dist/tool-system/builtin/web-search.js +174 -0
  422. package/dist/tool-system/builtin/worktree.d.ts +10 -0
  423. package/dist/tool-system/builtin/worktree.js +95 -0
  424. package/dist/tool-system/builtin/write.d.ts +6 -0
  425. package/dist/tool-system/builtin/write.js +36 -0
  426. package/dist/tool-system/context.d.ts +165 -0
  427. package/dist/tool-system/context.js +18 -0
  428. package/dist/tool-system/executor.d.ts +49 -0
  429. package/dist/tool-system/executor.js +495 -0
  430. package/dist/tool-system/investigation-guard.d.ts +46 -0
  431. package/dist/tool-system/investigation-guard.js +155 -0
  432. package/dist/tool-system/mcp-manager.d.ts +67 -0
  433. package/dist/tool-system/mcp-manager.js +249 -0
  434. package/dist/tool-system/permission.d.ts +111 -0
  435. package/dist/tool-system/permission.js +774 -0
  436. package/dist/tool-system/registry.d.ts +32 -0
  437. package/dist/tool-system/registry.js +131 -0
  438. package/dist/tool-system/sandbox/bwrap.d.ts +13 -0
  439. package/dist/tool-system/sandbox/bwrap.js +63 -0
  440. package/dist/tool-system/sandbox/index.d.ts +78 -0
  441. package/dist/tool-system/sandbox/index.js +222 -0
  442. package/dist/tool-system/sandbox/off.d.ts +2 -0
  443. package/dist/tool-system/sandbox/off.js +8 -0
  444. package/dist/tool-system/sandbox/seatbelt.d.ts +18 -0
  445. package/dist/tool-system/sandbox/seatbelt.js +109 -0
  446. package/dist/tool-system/task-guard.d.ts +29 -0
  447. package/dist/tool-system/task-guard.js +70 -0
  448. package/dist/tool-system/validation.d.ts +5 -0
  449. package/dist/tool-system/validation.js +39 -0
  450. package/dist/types.d.ts +376 -0
  451. package/dist/types.js +4 -0
  452. package/dist/updater.d.ts +65 -0
  453. package/dist/updater.js +405 -0
  454. package/dist/utils/debug.d.ts +41 -0
  455. package/dist/utils/debug.js +110 -0
  456. package/dist/utils/earlyInput.d.ts +43 -0
  457. package/dist/utils/earlyInput.js +166 -0
  458. package/dist/utils/env.d.ts +24 -0
  459. package/dist/utils/env.js +104 -0
  460. package/dist/utils/envUtils.d.ts +51 -0
  461. package/dist/utils/envUtils.js +135 -0
  462. package/dist/utils/execFileNoThrow.d.ts +39 -0
  463. package/dist/utils/execFileNoThrow.js +74 -0
  464. package/dist/utils/format.d.ts +44 -0
  465. package/dist/utils/format.js +236 -0
  466. package/dist/utils/intl.d.ts +22 -0
  467. package/dist/utils/intl.js +83 -0
  468. package/dist/utils/lockfile.d.ts +15 -0
  469. package/dist/utils/lockfile.js +30 -0
  470. package/dist/utils/memoize.d.ts +19 -0
  471. package/dist/utils/memoize.js +14 -0
  472. package/dist/utils/semver.d.ts +6 -0
  473. package/dist/utils/semver.js +13 -0
  474. package/dist/utils/sliceAnsi.d.ts +12 -0
  475. package/dist/utils/sliceAnsi.js +62 -0
  476. package/dist/utils/systemTheme.d.ts +40 -0
  477. package/dist/utils/systemTheme.js +108 -0
  478. package/dist/utils/task-sanitizer.d.ts +6 -0
  479. package/dist/utils/task-sanitizer.js +24 -0
  480. package/dist/utils/theme.d.ts +93 -0
  481. package/dist/utils/theme.js +544 -0
  482. package/dist/utils/toolDisplay.d.ts +31 -0
  483. package/dist/utils/toolDisplay.js +188 -0
  484. package/package.json +72 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Model call facade — wraps LLM client with transcript integration.
3
+ */
4
+ import type { LLMClientBase } from "../llm/client-base.js";
5
+ import type { Message, ToolDefinition, LLMResponse, StreamCallback } from "../types.js";
6
+ import { Transcript } from "../session/transcript.js";
7
+ export declare class ModelFacade {
8
+ private readonly client;
9
+ private readonly transcript;
10
+ constructor(client: LLMClientBase, transcript: Transcript);
11
+ call(systemPrompt: string, messages: Message[], tools: ToolDefinition[], onStream?: StreamCallback, signal?: AbortSignal): Promise<LLMResponse>;
12
+ /**
13
+ * Call without streaming — used as fallback when streaming fails.
14
+ */
15
+ callWithoutStreaming(systemPrompt: string, messages: Message[], tools: ToolDefinition[], signal?: AbortSignal): Promise<LLMResponse>;
16
+ /** Record API timing and token usage to bootstrap state. */
17
+ private recordUsage;
18
+ /** Optional summarize function for tool use summaries. */
19
+ summarize?: (systemPrompt: string, userMessage: string) => Promise<string>;
20
+ /** Get cumulative output tokens (for token budget). */
21
+ getOutputTokens?(): number;
22
+ private recordResponse;
23
+ getUsage(): import("../llm/types.js").LLMUsageTracker;
24
+ }
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Model call facade — wraps LLM client with transcript integration.
3
+ */
4
+ import { logger, getCurrentSid } from "../logging/logger.js";
5
+ import { recordLLMError, recordLLMRequest, recordLLMResponse, } from "../logging/session-recorder.js";
6
+ import { sanitizeMessages } from "../logging/sanitize-messages.js";
7
+ import { addAPIDuration, addToModelUsage, addInputTokens, addOutputTokens } from "../state.js";
8
+ let _reqSeq = 0;
9
+ function nextReqId() {
10
+ _reqSeq += 1;
11
+ return `r${_reqSeq.toString(36)}`;
12
+ }
13
+ export class ModelFacade {
14
+ client;
15
+ transcript;
16
+ constructor(client, transcript) {
17
+ this.client = client;
18
+ this.transcript = transcript;
19
+ }
20
+ async call(systemPrompt, messages, tools, onStream, signal) {
21
+ const startMs = Date.now();
22
+ const msgCount = messages.length;
23
+ const sid = getCurrentSid();
24
+ const reqId = nextReqId();
25
+ recordLLMRequest(sid, {
26
+ provider: this.client.provider ?? "?",
27
+ model: this.client.model ?? "?",
28
+ stream: true,
29
+ // Image base64 payloads stay out of recorded prompts — see
30
+ // logging/sanitize-messages.ts. Transcripts keep the full bytes
31
+ // (needed for replay); logs do not.
32
+ messages: sanitizeMessages(messages),
33
+ tools,
34
+ systemPrompt,
35
+ }, reqId);
36
+ let response;
37
+ try {
38
+ response = await this.client.createMessage({
39
+ systemPrompt,
40
+ messages,
41
+ tools,
42
+ stream: true,
43
+ onChunk: (chunk) => {
44
+ if (!onStream)
45
+ return;
46
+ if (chunk.type === "text" && chunk.text) {
47
+ onStream({ type: "text_delta", text: chunk.text, tokens: chunk.tokens });
48
+ }
49
+ else if (chunk.type === "tool_use_start" && chunk.toolCall) {
50
+ // Forward tool_use_start immediately so the UI can show progress
51
+ // while JSON args are still streaming
52
+ onStream({
53
+ type: "tool_use_start",
54
+ toolCall: {
55
+ id: chunk.toolCall.id ?? "",
56
+ toolName: chunk.toolCall.toolName ?? "",
57
+ args: chunk.toolCall.args ?? {},
58
+ },
59
+ });
60
+ }
61
+ else if (chunk.type === "tool_use_delta" && chunk.toolCall?.id) {
62
+ onStream({
63
+ type: "tool_use_args_delta",
64
+ toolCallId: chunk.toolCall.id,
65
+ args: chunk.toolCall.args ?? {},
66
+ });
67
+ }
68
+ },
69
+ signal,
70
+ });
71
+ }
72
+ catch (err) {
73
+ recordLLMError(sid, reqId, err, Date.now() - startMs);
74
+ throw err;
75
+ }
76
+ const latencyMs = Date.now() - startMs;
77
+ logger.info("llm.request", {
78
+ stream: true,
79
+ latencyMs,
80
+ msgCount,
81
+ stopReason: response.stopReason,
82
+ toolCalls: response.toolCalls.length,
83
+ textLen: response.text?.length ?? 0,
84
+ usage: response.usage,
85
+ });
86
+ recordLLMResponse(sid, {
87
+ text: response.text,
88
+ toolCalls: response.toolCalls,
89
+ stopReason: response.stopReason,
90
+ usage: response.usage,
91
+ durationMs: latencyMs,
92
+ }, reqId);
93
+ this.recordUsage(response, latencyMs);
94
+ this.recordResponse(response);
95
+ return response;
96
+ }
97
+ /**
98
+ * Call without streaming — used as fallback when streaming fails.
99
+ */
100
+ async callWithoutStreaming(systemPrompt, messages, tools, signal) {
101
+ const startMs = Date.now();
102
+ const msgCount = messages.length;
103
+ const sid = getCurrentSid();
104
+ const reqId = nextReqId();
105
+ recordLLMRequest(sid, {
106
+ provider: this.client.provider ?? "?",
107
+ model: this.client.model ?? "?",
108
+ stream: false,
109
+ // Image base64 payloads stay out of recorded prompts — same rule
110
+ // as the streaming path above.
111
+ messages: sanitizeMessages(messages),
112
+ tools,
113
+ systemPrompt,
114
+ }, reqId);
115
+ let response;
116
+ try {
117
+ response = await this.client.createMessage({
118
+ systemPrompt,
119
+ messages,
120
+ tools,
121
+ stream: false,
122
+ signal,
123
+ });
124
+ }
125
+ catch (err) {
126
+ recordLLMError(sid, reqId, err, Date.now() - startMs);
127
+ throw err;
128
+ }
129
+ const latencyMs = Date.now() - startMs;
130
+ logger.info("llm.request", {
131
+ stream: false,
132
+ latencyMs,
133
+ msgCount,
134
+ stopReason: response.stopReason,
135
+ toolCalls: response.toolCalls.length,
136
+ textLen: response.text?.length ?? 0,
137
+ usage: response.usage,
138
+ });
139
+ recordLLMResponse(sid, {
140
+ text: response.text,
141
+ toolCalls: response.toolCalls,
142
+ stopReason: response.stopReason,
143
+ usage: response.usage,
144
+ durationMs: latencyMs,
145
+ }, reqId);
146
+ this.recordUsage(response, latencyMs);
147
+ this.recordResponse(response);
148
+ return response;
149
+ }
150
+ /** Record API timing and token usage to bootstrap state. */
151
+ recordUsage(response, latencyMs) {
152
+ addAPIDuration(latencyMs);
153
+ const u = response.usage;
154
+ if (u) {
155
+ addInputTokens(u.promptTokens ?? 0);
156
+ addOutputTokens(u.completionTokens ?? 0);
157
+ addToModelUsage(this.client.model ?? "unknown", u.promptTokens ?? 0, u.completionTokens ?? 0, u.cacheReadTokens ?? 0, u.cacheCreationTokens ?? 0);
158
+ }
159
+ }
160
+ /** Optional summarize function for tool use summaries. */
161
+ summarize;
162
+ recordResponse(response) {
163
+ if (response.text || response.toolCalls.length > 0 || response.reasoningContent) {
164
+ const contentBlocks = [];
165
+ // DeepSeek V4 thinking mode emits reasoning_content alongside the
166
+ // reply; we echo it back on the next turn so the model can resume
167
+ // its chain of thought. Persist as a dedicated block so transcript
168
+ // -> message round-tripping preserves it without mixing into
169
+ // displayable text. Goes first so it sits adjacent to the
170
+ // assistant turn it belongs to even after compaction.
171
+ if (response.reasoningContent) {
172
+ contentBlocks.push({
173
+ type: "reasoning",
174
+ reasoningContent: response.reasoningContent,
175
+ });
176
+ }
177
+ if (response.text) {
178
+ contentBlocks.push({ type: "text", text: response.text });
179
+ }
180
+ for (const tc of response.toolCalls) {
181
+ contentBlocks.push({
182
+ type: "tool_use",
183
+ id: tc.id,
184
+ name: tc.toolName,
185
+ input: tc.args,
186
+ });
187
+ }
188
+ this.transcript.appendMessage("assistant", contentBlocks);
189
+ }
190
+ }
191
+ getUsage() {
192
+ return this.client.getUsage();
193
+ }
194
+ }
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Parse a single-string `task` for inline image attachments.
3
+ *
4
+ * Desktop's composer encodes images as `<codeshell-image>` blocks before
5
+ * sending — see `packages/desktop/src/renderer/chat/attachments.ts` —
6
+ * because the agent-server-stdio RPC schema only carries a `task: string`.
7
+ * The engine recovers the structured form here before handing the message
8
+ * to the LLM client.
9
+ *
10
+ * Wire format (one block per image):
11
+ *
12
+ * <codeshell-image mime="image/png" name="screenshot.png">
13
+ * data:image/png;base64,iVBORw0KGgo…
14
+ * </codeshell-image>
15
+ *
16
+ * Multiple blocks may appear interleaved with regular text — preserved
17
+ * order matters because some prompts reference "the second image".
18
+ *
19
+ * Pure / no I/O. Pure-text tasks (no `<codeshell-image>` substring) hit
20
+ * a single non-matching indexOf check and return immediately, so CLI / TUI
21
+ * callers pay essentially nothing.
22
+ */
23
+ export interface ParsedImage {
24
+ /** MIME type as declared in the block opening tag. */
25
+ mime: string;
26
+ /** Original file name (may be empty). HTML-attr-escaped on the wire; unescaped here. */
27
+ name: string;
28
+ /** Full `data:<mime>;base64,<…>` URL — handy for OpenAI-compat clients. */
29
+ dataUrl: string;
30
+ /** Just the base64 payload, with the data-URL prefix stripped. */
31
+ base64: string;
32
+ }
33
+ export interface ParsedTask {
34
+ /** Remaining plain-text portion (image blocks removed, surrounding whitespace trimmed). */
35
+ text: string;
36
+ /** Images in the order they appeared in the source. */
37
+ images: ParsedImage[];
38
+ /** Convenience flag — true iff `images.length > 0`. */
39
+ hasImages: boolean;
40
+ }
41
+ export declare class ImageParseError extends Error {
42
+ constructor(message: string);
43
+ }
44
+ /**
45
+ * Parse `<codeshell-image>` blocks out of `task`.
46
+ *
47
+ * Behavior:
48
+ * - No marker substring → fast return, no allocations beyond the
49
+ * `ParsedTask` shell.
50
+ * - One or more well-formed blocks → blocks removed from `text`,
51
+ * surrounding whitespace collapsed, blocks accumulated in `images`
52
+ * in source order.
53
+ * - Malformed block (e.g. unclosed tag, missing data URL) → throws
54
+ * {@link ImageParseError}. Callers decide whether to drop or fail
55
+ * the run, but **silent fallback is intentionally not provided** —
56
+ * dropping image bytes on the floor was the failure mode this whole
57
+ * pipeline exists to prevent.
58
+ */
59
+ export declare function parseTaskWithImages(task: string): ParsedTask;
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Parse a single-string `task` for inline image attachments.
3
+ *
4
+ * Desktop's composer encodes images as `<codeshell-image>` blocks before
5
+ * sending — see `packages/desktop/src/renderer/chat/attachments.ts` —
6
+ * because the agent-server-stdio RPC schema only carries a `task: string`.
7
+ * The engine recovers the structured form here before handing the message
8
+ * to the LLM client.
9
+ *
10
+ * Wire format (one block per image):
11
+ *
12
+ * <codeshell-image mime="image/png" name="screenshot.png">
13
+ * data:image/png;base64,iVBORw0KGgo…
14
+ * </codeshell-image>
15
+ *
16
+ * Multiple blocks may appear interleaved with regular text — preserved
17
+ * order matters because some prompts reference "the second image".
18
+ *
19
+ * Pure / no I/O. Pure-text tasks (no `<codeshell-image>` substring) hit
20
+ * a single non-matching indexOf check and return immediately, so CLI / TUI
21
+ * callers pay essentially nothing.
22
+ */
23
+ export class ImageParseError extends Error {
24
+ constructor(message) {
25
+ super(message);
26
+ this.name = "ImageParseError";
27
+ }
28
+ }
29
+ const IMAGE_BLOCK_MARKER = "<codeshell-image";
30
+ /**
31
+ * Pulled out so the regex compiles once. Captures:
32
+ * 1 = raw attribute string (everything between `<codeshell-image` and the
33
+ * closing `>` of the opening tag)
34
+ * 2 = body (everything between the opening tag and `</codeshell-image>`)
35
+ *
36
+ * Anchored loosely — we tolerate whitespace inside the opening tag and
37
+ * around the body, which is what the desktop encoder produces.
38
+ */
39
+ const IMAGE_BLOCK_RE = /<codeshell-image\b([^>]*)>([\s\S]*?)<\/codeshell-image>/g;
40
+ const ATTR_RE = /(\w+)\s*=\s*"([^"]*)"/g;
41
+ /**
42
+ * Reverse of the desktop encoder's `escapeAttr` so file names with `&`
43
+ * or quotes round-trip cleanly.
44
+ */
45
+ function unescapeAttr(s) {
46
+ return s
47
+ .replace(/&quot;/g, '"')
48
+ .replace(/&lt;/g, "<")
49
+ .replace(/&gt;/g, ">")
50
+ .replace(/&amp;/g, "&");
51
+ }
52
+ function parseAttrs(raw) {
53
+ const out = {};
54
+ ATTR_RE.lastIndex = 0;
55
+ let m;
56
+ while ((m = ATTR_RE.exec(raw)) !== null) {
57
+ out[m[1].toLowerCase()] = unescapeAttr(m[2]);
58
+ }
59
+ return out;
60
+ }
61
+ const DATA_URL_RE = /^data:([^;,]+);base64,([A-Za-z0-9+/=\s]+)$/;
62
+ function parseDataUrl(body) {
63
+ const trimmed = body.trim();
64
+ const m = DATA_URL_RE.exec(trimmed);
65
+ if (!m) {
66
+ throw new ImageParseError("image block body is not a data URL of the form `data:<mime>;base64,<…>`");
67
+ }
68
+ const mime = m[1].trim();
69
+ // Strip ALL whitespace from the base64 portion — wire format may contain
70
+ // newlines inserted for readability. The base64 grammar tolerates none.
71
+ const base64 = m[2].replace(/\s+/g, "");
72
+ if (base64.length === 0) {
73
+ throw new ImageParseError("image block body has an empty base64 payload");
74
+ }
75
+ return { mime, base64 };
76
+ }
77
+ /**
78
+ * Parse `<codeshell-image>` blocks out of `task`.
79
+ *
80
+ * Behavior:
81
+ * - No marker substring → fast return, no allocations beyond the
82
+ * `ParsedTask` shell.
83
+ * - One or more well-formed blocks → blocks removed from `text`,
84
+ * surrounding whitespace collapsed, blocks accumulated in `images`
85
+ * in source order.
86
+ * - Malformed block (e.g. unclosed tag, missing data URL) → throws
87
+ * {@link ImageParseError}. Callers decide whether to drop or fail
88
+ * the run, but **silent fallback is intentionally not provided** —
89
+ * dropping image bytes on the floor was the failure mode this whole
90
+ * pipeline exists to prevent.
91
+ */
92
+ export function parseTaskWithImages(task) {
93
+ if (typeof task !== "string" || task.indexOf(IMAGE_BLOCK_MARKER) === -1) {
94
+ return { text: task ?? "", images: [], hasImages: false };
95
+ }
96
+ // Defensively reject the orphaned-opening-tag case before delegating to
97
+ // the matcher: a `<codeshell-image …>` with no matching `</codeshell-image>`
98
+ // is exactly the "browser hung up mid-paste" failure mode this parser
99
+ // exists to surface, not swallow.
100
+ const openingMatches = task.match(/<codeshell-image\b/g) ?? [];
101
+ const closingMatches = task.match(/<\/codeshell-image>/g) ?? [];
102
+ if (openingMatches.length !== closingMatches.length) {
103
+ throw new ImageParseError(`unbalanced <codeshell-image> tags: ${openingMatches.length} opening vs ${closingMatches.length} closing`);
104
+ }
105
+ const images = [];
106
+ IMAGE_BLOCK_RE.lastIndex = 0;
107
+ const textWithoutImages = task.replace(IMAGE_BLOCK_RE, (_match, attrsRaw, body) => {
108
+ const attrs = parseAttrs(attrsRaw);
109
+ const { mime, base64 } = parseDataUrl(body);
110
+ const declaredMime = attrs.mime?.trim();
111
+ // Prefer the opening-tag attribute when it disagrees with the data URL's
112
+ // self-declared type — the attribute is what the desktop validator gated
113
+ // on, so it's the "source of truth" the rest of the pipeline expects.
114
+ const finalMime = declaredMime && declaredMime.length > 0 ? declaredMime : mime;
115
+ images.push({
116
+ mime: finalMime,
117
+ name: attrs.name ?? "",
118
+ dataUrl: `data:${finalMime};base64,${base64}`,
119
+ base64,
120
+ });
121
+ return "";
122
+ });
123
+ // Collapse the whitespace the removed blocks leave behind. Two passes:
124
+ // 1. Multiple blank lines (3+ newlines) → exactly two newlines, so the
125
+ // remaining prose retains paragraph breaks but doesn't look like a
126
+ // page of empty whitespace.
127
+ // 2. Trim leading/trailing whitespace introduced by a block at either
128
+ // end of the message.
129
+ const cleanedText = textWithoutImages.replace(/\n{3,}/g, "\n\n").trim();
130
+ return {
131
+ text: cleanedText,
132
+ images,
133
+ hasImages: images.length > 0,
134
+ };
135
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * patchOrphanedToolUses — repair message sequences where an assistant
3
+ * `tool_use` block has no corresponding `tool_result`.
4
+ *
5
+ * Why this matters: OpenAI strictly enforces that every `tool_calls`
6
+ * entry on an assistant message is followed by a matching `role:"tool"`
7
+ * message (one per `tool_call_id`). An incomplete sequence triggers
8
+ * `400 An assistant message with 'tool_calls' must be followed by tool
9
+ * messages responding to each 'tool_call_id'`.
10
+ *
11
+ * The sequence can become incomplete in two ways:
12
+ * 1. The model called tools, the API call between turns failed before
13
+ * the executor wrote the results. TurnLoop already patches this
14
+ * mid-run (see turn-loop.ts), so the broken state only lives in
15
+ * memory.
16
+ * 2. The process crashed / was Ctrl+C'd after the assistant message
17
+ * was persisted to transcript.jsonl but before tool_result events
18
+ * were appended. On `/resume`, the loaded message array carries
19
+ * this gap into the next API call.
20
+ *
21
+ * This module is the resume-side counterpart: scan the entire loaded
22
+ * history (not just the tail), find every assistant→missing-result gap,
23
+ * inject a synthetic tool_result for each orphan in the correct
24
+ * position so the resulting sequence is valid for both Anthropic and
25
+ * OpenAI message shapes.
26
+ *
27
+ * Insertion strategy: we append the synthetic results as a NEW `user`
28
+ * message with `tool_result` blocks placed immediately after the
29
+ * assistant message that produced the orphan. This matches what the
30
+ * runtime would have written if execution had completed normally, and
31
+ * the OpenAI converter (providers/openai.ts) lifts each `tool_result`
32
+ * out to a separate `role:"tool"` message keyed by `tool_use_id` —
33
+ * exactly the shape the API requires.
34
+ */
35
+ import type { Message } from "../types.js";
36
+ export interface PatchOrphanedSummary {
37
+ /** How many gaps were found across the whole history. */
38
+ gapsPatched: number;
39
+ /** Total synthetic tool_result blocks injected. */
40
+ toolResultsInjected: number;
41
+ }
42
+ /**
43
+ * Walk `messages` and, for every assistant message whose `tool_use`
44
+ * blocks lack corresponding `tool_result`s anywhere later in the array,
45
+ * splice a synthetic user→tool_result message right after it. Mutates
46
+ * `messages` in place and returns a summary so callers can log how
47
+ * much repair was needed.
48
+ *
49
+ * Idempotent: a second call on the same array is a no-op because the
50
+ * first pass already filled every gap.
51
+ */
52
+ export declare function patchOrphanedToolUses(messages: Message[]): PatchOrphanedSummary;
@@ -0,0 +1,95 @@
1
+ /**
2
+ * patchOrphanedToolUses — repair message sequences where an assistant
3
+ * `tool_use` block has no corresponding `tool_result`.
4
+ *
5
+ * Why this matters: OpenAI strictly enforces that every `tool_calls`
6
+ * entry on an assistant message is followed by a matching `role:"tool"`
7
+ * message (one per `tool_call_id`). An incomplete sequence triggers
8
+ * `400 An assistant message with 'tool_calls' must be followed by tool
9
+ * messages responding to each 'tool_call_id'`.
10
+ *
11
+ * The sequence can become incomplete in two ways:
12
+ * 1. The model called tools, the API call between turns failed before
13
+ * the executor wrote the results. TurnLoop already patches this
14
+ * mid-run (see turn-loop.ts), so the broken state only lives in
15
+ * memory.
16
+ * 2. The process crashed / was Ctrl+C'd after the assistant message
17
+ * was persisted to transcript.jsonl but before tool_result events
18
+ * were appended. On `/resume`, the loaded message array carries
19
+ * this gap into the next API call.
20
+ *
21
+ * This module is the resume-side counterpart: scan the entire loaded
22
+ * history (not just the tail), find every assistant→missing-result gap,
23
+ * inject a synthetic tool_result for each orphan in the correct
24
+ * position so the resulting sequence is valid for both Anthropic and
25
+ * OpenAI message shapes.
26
+ *
27
+ * Insertion strategy: we append the synthetic results as a NEW `user`
28
+ * message with `tool_result` blocks placed immediately after the
29
+ * assistant message that produced the orphan. This matches what the
30
+ * runtime would have written if execution had completed normally, and
31
+ * the OpenAI converter (providers/openai.ts) lifts each `tool_result`
32
+ * out to a separate `role:"tool"` message keyed by `tool_use_id` —
33
+ * exactly the shape the API requires.
34
+ */
35
+ const SYNTHETIC_ERROR_TEXT = "Error: Tool execution did not complete (process interrupted or earlier API failure). " +
36
+ "This result was injected during session resume to keep the message sequence valid.";
37
+ /**
38
+ * Walk `messages` and, for every assistant message whose `tool_use`
39
+ * blocks lack corresponding `tool_result`s anywhere later in the array,
40
+ * splice a synthetic user→tool_result message right after it. Mutates
41
+ * `messages` in place and returns a summary so callers can log how
42
+ * much repair was needed.
43
+ *
44
+ * Idempotent: a second call on the same array is a no-op because the
45
+ * first pass already filled every gap.
46
+ */
47
+ export function patchOrphanedToolUses(messages) {
48
+ const summary = { gapsPatched: 0, toolResultsInjected: 0 };
49
+ // Pre-compute the set of tool_result ids already answered anywhere in
50
+ // the history, then scan forward. Doing this in one pass avoids the
51
+ // O(n²) "for each assistant, scan tail" pattern in TurnLoop's
52
+ // single-shot version — resume sessions can be long.
53
+ const answeredIds = new Set();
54
+ for (const msg of messages) {
55
+ if (!Array.isArray(msg.content))
56
+ continue;
57
+ for (const block of msg.content) {
58
+ if (block.type === "tool_result" && block.tool_use_id) {
59
+ answeredIds.add(block.tool_use_id);
60
+ }
61
+ }
62
+ }
63
+ // Walk left-to-right, splicing inserts immediately after the offending
64
+ // assistant message. We iterate by index and bump past the inserted
65
+ // message so we don't re-process it.
66
+ for (let i = 0; i < messages.length; i++) {
67
+ const msg = messages[i];
68
+ if (msg.role !== "assistant" || !Array.isArray(msg.content))
69
+ continue;
70
+ const orphanedIds = [];
71
+ for (const block of msg.content) {
72
+ if (block.type === "tool_use" && block.id && !answeredIds.has(block.id)) {
73
+ orphanedIds.push(block.id);
74
+ }
75
+ }
76
+ if (orphanedIds.length === 0)
77
+ continue;
78
+ const errorBlocks = orphanedIds.map((id) => ({
79
+ type: "tool_result",
80
+ tool_use_id: id,
81
+ content: SYNTHETIC_ERROR_TEXT,
82
+ }));
83
+ messages.splice(i + 1, 0, { role: "user", content: errorBlocks });
84
+ // Mark these ids answered so a later assistant message referencing
85
+ // the same id (shouldn't happen with real id generation, but guards
86
+ // against bad transcripts) doesn't double-patch.
87
+ for (const id of orphanedIds)
88
+ answeredIds.add(id);
89
+ summary.gapsPatched += 1;
90
+ summary.toolResultsInjected += orphanedIds.length;
91
+ // Skip the synthetic message we just spliced in.
92
+ i += 1;
93
+ }
94
+ return summary;
95
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * High-level query API — async generator wrapping TurnLoop.
3
+ *
4
+ * Callers consume events via `for await (const event of query(params))`.
5
+ * This is the public entry point for running agentic queries; TurnLoop
6
+ * is the internal state machine.
7
+ *
8
+ * Adapted from restored-src/src/query.ts, simplified for Code Shell.
9
+ */
10
+ import type { Message, StreamEvent, ToolDefinition, TerminalReason } from "../types.js";
11
+ import { type TurnLoopDeps } from "./turn-loop.js";
12
+ export interface QueryParams {
13
+ /** Initial message history (including the new user message). */
14
+ messages: Message[];
15
+ /** System prompt text. */
16
+ systemPrompt: string;
17
+ /** Available tool definitions. */
18
+ tools: ToolDefinition[];
19
+ /** Max turns before forced stop. */
20
+ maxTurns?: number;
21
+ /** Max tool calls per turn (default 20). */
22
+ maxToolCallsPerTurn?: number;
23
+ /** Abort signal for cancellation. */
24
+ signal?: AbortSignal;
25
+ /** Dependencies injected by the caller (engine). */
26
+ deps: QueryDeps;
27
+ }
28
+ export interface QueryDeps {
29
+ model: TurnLoopDeps["model"];
30
+ toolExecutor: TurnLoopDeps["toolExecutor"];
31
+ contextManager: TurnLoopDeps["contextManager"];
32
+ hooks: TurnLoopDeps["hooks"];
33
+ transcript: TurnLoopDeps["transcript"];
34
+ }
35
+ export interface QueryResult {
36
+ text: string;
37
+ reason: TerminalReason;
38
+ turnCount: number;
39
+ }
40
+ /**
41
+ * Run an agentic query and yield stream events as they occur.
42
+ *
43
+ * Usage:
44
+ * const events: StreamEvent[] = [];
45
+ * for await (const event of query(params)) {
46
+ * events.push(event);
47
+ * }
48
+ * // last event contains the final result
49
+ */
50
+ export declare function query(params: QueryParams): AsyncGenerator<StreamEvent, QueryResult, undefined>;