@machina.ai/cell-cli-core 1.10.0-rc1 → 1.13.0-rc1

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 (549) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.js +4 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +13 -5
  5. package/dist/src/agents/codebase-investigator.js +2 -5
  6. package/dist/src/agents/codebase-investigator.js.map +1 -1
  7. package/dist/src/agents/executor.d.ts +19 -0
  8. package/dist/src/agents/executor.js +234 -46
  9. package/dist/src/agents/executor.js.map +1 -1
  10. package/dist/src/agents/executor.test.js +371 -40
  11. package/dist/src/agents/executor.test.js.map +1 -1
  12. package/dist/src/agents/registry.js +4 -3
  13. package/dist/src/agents/registry.js.map +1 -1
  14. package/dist/src/agents/subagent-tool-wrapper.test.js +2 -4
  15. package/dist/src/agents/subagent-tool-wrapper.test.js.map +1 -1
  16. package/dist/src/agents/types.d.ts +2 -1
  17. package/dist/src/agents/types.js +1 -0
  18. package/dist/src/agents/types.js.map +1 -1
  19. package/dist/src/code_assist/converter.d.ts +1 -0
  20. package/dist/src/code_assist/converter.js +1 -0
  21. package/dist/src/code_assist/converter.js.map +1 -1
  22. package/dist/src/code_assist/converter.test.js +19 -0
  23. package/dist/src/code_assist/converter.test.js.map +1 -1
  24. package/dist/src/code_assist/experiments/client_metadata.d.ts +12 -0
  25. package/dist/src/code_assist/experiments/client_metadata.js +49 -0
  26. package/dist/src/code_assist/experiments/client_metadata.js.map +1 -0
  27. package/dist/src/code_assist/experiments/experiments.d.ts +17 -0
  28. package/dist/src/code_assist/experiments/experiments.js +36 -0
  29. package/dist/src/code_assist/experiments/experiments.js.map +1 -0
  30. package/dist/src/code_assist/experiments/types.d.ts +35 -0
  31. package/dist/src/code_assist/experiments/types.js +7 -0
  32. package/dist/src/code_assist/experiments/types.js.map +1 -0
  33. package/dist/src/code_assist/oauth-credential-storage.js +5 -4
  34. package/dist/src/code_assist/oauth-credential-storage.js.map +1 -1
  35. package/dist/src/code_assist/oauth-credential-storage.test.js +15 -3
  36. package/dist/src/code_assist/oauth-credential-storage.test.js.map +1 -1
  37. package/dist/src/code_assist/oauth2.d.ts +2 -2
  38. package/dist/src/code_assist/oauth2.js +64 -51
  39. package/dist/src/code_assist/oauth2.js.map +1 -1
  40. package/dist/src/code_assist/oauth2.test.js +65 -33
  41. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  42. package/dist/src/code_assist/server.d.ts +6 -4
  43. package/dist/src/code_assist/server.js +11 -0
  44. package/dist/src/code_assist/server.js.map +1 -1
  45. package/dist/src/code_assist/server.test.js +17 -0
  46. package/dist/src/code_assist/server.test.js.map +1 -1
  47. package/dist/src/code_assist/setup.d.ts +2 -2
  48. package/dist/src/code_assist/setup.js.map +1 -1
  49. package/dist/src/code_assist/types.d.ts +1 -1
  50. package/dist/src/code_assist/types.js.map +1 -1
  51. package/dist/src/commands/extensions.d.ts +7 -0
  52. package/dist/src/commands/extensions.js +9 -0
  53. package/dist/src/commands/extensions.js.map +1 -0
  54. package/dist/src/commands/extensions.test.js +19 -0
  55. package/dist/src/commands/extensions.test.js.map +1 -0
  56. package/dist/src/config/config.d.ts +81 -32
  57. package/dist/src/config/config.js +193 -66
  58. package/dist/src/config/config.js.map +1 -1
  59. package/dist/src/config/config.test.js +115 -36
  60. package/dist/src/config/config.test.js.map +1 -1
  61. package/dist/src/config/models.d.ts +1 -1
  62. package/dist/src/config/models.js +2 -2
  63. package/dist/src/config/models.js.map +1 -1
  64. package/dist/src/config/storage.d.ts +3 -0
  65. package/dist/src/config/storage.js +20 -0
  66. package/dist/src/config/storage.js.map +1 -1
  67. package/dist/src/confirmation-bus/message-bus.d.ts +2 -1
  68. package/dist/src/confirmation-bus/message-bus.js +7 -1
  69. package/dist/src/confirmation-bus/message-bus.js.map +1 -1
  70. package/dist/src/confirmation-bus/types.d.ts +12 -2
  71. package/dist/src/confirmation-bus/types.js +1 -0
  72. package/dist/src/confirmation-bus/types.js.map +1 -1
  73. package/dist/src/core/apiKeyCredentialStorage.d.ts +17 -0
  74. package/dist/src/core/apiKeyCredentialStorage.js +64 -0
  75. package/dist/src/core/apiKeyCredentialStorage.js.map +1 -0
  76. package/dist/src/core/apiKeyCredentialStorage.test.d.ts +6 -0
  77. package/dist/src/core/apiKeyCredentialStorage.test.js +71 -0
  78. package/dist/src/core/apiKeyCredentialStorage.test.js.map +1 -0
  79. package/dist/src/core/client.d.ts +2 -11
  80. package/dist/src/core/client.js +31 -170
  81. package/dist/src/core/client.js.map +1 -1
  82. package/dist/src/core/client.test.js +107 -429
  83. package/dist/src/core/client.test.js.map +1 -1
  84. package/dist/src/core/contentGenerator.js +64 -59
  85. package/dist/src/core/contentGenerator.js.map +1 -1
  86. package/dist/src/core/contentGenerator.test.js +38 -4
  87. package/dist/src/core/contentGenerator.test.js.map +1 -1
  88. package/dist/src/core/coreToolScheduler.d.ts +8 -2
  89. package/dist/src/core/coreToolScheduler.js +337 -172
  90. package/dist/src/core/coreToolScheduler.js.map +1 -1
  91. package/dist/src/core/coreToolScheduler.test.js +363 -12
  92. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  93. package/dist/src/core/fakeContentGenerator.d.ts +33 -0
  94. package/dist/src/core/fakeContentGenerator.js +58 -0
  95. package/dist/src/core/fakeContentGenerator.js.map +1 -0
  96. package/dist/src/core/fakeContentGenerator.test.d.ts +6 -0
  97. package/dist/src/core/fakeContentGenerator.test.js +127 -0
  98. package/dist/src/core/fakeContentGenerator.test.js.map +1 -0
  99. package/dist/src/core/geminiChat.d.ts +2 -0
  100. package/dist/src/core/geminiChat.js +7 -2
  101. package/dist/src/core/geminiChat.js.map +1 -1
  102. package/dist/src/core/geminiChat.test.js +15 -3
  103. package/dist/src/core/geminiChat.test.js.map +1 -1
  104. package/dist/src/core/logger.js +21 -19
  105. package/dist/src/core/logger.js.map +1 -1
  106. package/dist/src/core/loggingContentGenerator.d.ts +1 -0
  107. package/dist/src/core/loggingContentGenerator.js +113 -33
  108. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  109. package/dist/src/core/nonInteractiveToolExecutor.js +5 -4
  110. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  111. package/dist/src/core/nonInteractiveToolExecutor.test.js +3 -0
  112. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  113. package/dist/src/core/prompts.js +115 -72
  114. package/dist/src/core/prompts.js.map +1 -1
  115. package/dist/src/core/prompts.test.js +30 -108
  116. package/dist/src/core/prompts.test.js.map +1 -1
  117. package/dist/src/core/recordingContentGenerator.d.ts +18 -0
  118. package/dist/src/core/recordingContentGenerator.js +77 -0
  119. package/dist/src/core/recordingContentGenerator.js.map +1 -0
  120. package/dist/src/core/recordingContentGenerator.test.d.ts +6 -0
  121. package/dist/src/core/recordingContentGenerator.test.js +101 -0
  122. package/dist/src/core/recordingContentGenerator.test.js.map +1 -0
  123. package/dist/src/core/turn.d.ts +2 -0
  124. package/dist/src/core/turn.js +3 -1
  125. package/dist/src/core/turn.js.map +1 -1
  126. package/dist/src/core/turn.test.js +48 -0
  127. package/dist/src/core/turn.test.js.map +1 -1
  128. package/dist/src/fallback/handler.js +2 -0
  129. package/dist/src/fallback/handler.js.map +1 -1
  130. package/dist/src/generated/git-commit.d.ts +2 -2
  131. package/dist/src/generated/git-commit.js +2 -2
  132. package/dist/src/hooks/hookPlanner.d.ts +46 -0
  133. package/dist/src/hooks/hookPlanner.js +108 -0
  134. package/dist/src/hooks/hookPlanner.js.map +1 -0
  135. package/dist/src/hooks/hookPlanner.test.d.ts +6 -0
  136. package/dist/src/hooks/hookPlanner.test.js +255 -0
  137. package/dist/src/hooks/hookPlanner.test.js.map +1 -0
  138. package/dist/src/hooks/hookRegistry.d.ts +87 -0
  139. package/dist/src/hooks/hookRegistry.js +198 -0
  140. package/dist/src/hooks/hookRegistry.js.map +1 -0
  141. package/dist/src/hooks/hookRegistry.test.d.ts +6 -0
  142. package/dist/src/hooks/hookRegistry.test.js +341 -0
  143. package/dist/src/hooks/hookRegistry.test.js.map +1 -0
  144. package/dist/src/hooks/hookTranslator.d.ts +113 -0
  145. package/dist/src/hooks/hookTranslator.js +232 -0
  146. package/dist/src/hooks/hookTranslator.js.map +1 -0
  147. package/dist/src/hooks/hookTranslator.test.d.ts +6 -0
  148. package/dist/src/hooks/hookTranslator.test.js +192 -0
  149. package/dist/src/hooks/hookTranslator.test.js.map +1 -0
  150. package/dist/src/hooks/types.d.ts +384 -0
  151. package/dist/src/hooks/types.js +284 -0
  152. package/dist/src/hooks/types.js.map +1 -0
  153. package/dist/src/hooks/types.test.d.ts +6 -0
  154. package/dist/src/hooks/types.test.js +35 -0
  155. package/dist/src/hooks/types.test.js.map +1 -0
  156. package/dist/src/ide/ide-client.js +2 -1
  157. package/dist/src/ide/ide-client.js.map +1 -1
  158. package/dist/src/index.d.ts +15 -0
  159. package/dist/src/index.js +18 -0
  160. package/dist/src/index.js.map +1 -1
  161. package/dist/src/mcp/google-auth-provider.d.ts +2 -0
  162. package/dist/src/mcp/google-auth-provider.js +21 -3
  163. package/dist/src/mcp/google-auth-provider.js.map +1 -1
  164. package/dist/src/mcp/google-auth-provider.test.js +42 -9
  165. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  166. package/dist/src/mcp/mcpLauncher.d.ts +26 -0
  167. package/dist/src/mcp/mcpLauncher.js +238 -0
  168. package/dist/src/mcp/mcpLauncher.js.map +1 -0
  169. package/dist/src/mcp/oauth-provider.d.ts +8 -5
  170. package/dist/src/mcp/oauth-provider.js +140 -55
  171. package/dist/src/mcp/oauth-provider.js.map +1 -1
  172. package/dist/src/mcp/oauth-provider.test.js +191 -2
  173. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  174. package/dist/src/mcp/oauth-token-storage.js +5 -4
  175. package/dist/src/mcp/oauth-token-storage.js.map +1 -1
  176. package/dist/src/mcp/oauth-token-storage.test.js +17 -11
  177. package/dist/src/mcp/oauth-token-storage.test.js.map +1 -1
  178. package/dist/src/mcp/oauth-utils.d.ts +7 -0
  179. package/dist/src/mcp/oauth-utils.js +28 -8
  180. package/dist/src/mcp/oauth-utils.js.map +1 -1
  181. package/dist/src/mcp/oauth-utils.test.js +45 -2
  182. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  183. package/dist/src/mcp/sa-impersonation-provider.d.ts +0 -6
  184. package/dist/src/mcp/sa-impersonation-provider.js +6 -23
  185. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -1
  186. package/dist/src/mcp/token-storage/base-token-storage.test.js +75 -84
  187. package/dist/src/mcp/token-storage/base-token-storage.test.js.map +1 -1
  188. package/dist/src/mcp/token-storage/file-token-storage.js +1 -1
  189. package/dist/src/mcp/token-storage/file-token-storage.js.map +1 -1
  190. package/dist/src/mcp/token-storage/file-token-storage.test.js +7 -5
  191. package/dist/src/mcp/token-storage/file-token-storage.test.js.map +1 -1
  192. package/dist/src/mcp/token-storage/hybrid-token-storage.js +1 -1
  193. package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -1
  194. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js +2 -2
  195. package/dist/src/mcp/token-storage/hybrid-token-storage.test.js.map +1 -1
  196. package/dist/src/mcp/token-storage/keychain-token-storage.d.ts +6 -2
  197. package/dist/src/mcp/token-storage/keychain-token-storage.js +63 -7
  198. package/dist/src/mcp/token-storage/keychain-token-storage.js.map +1 -1
  199. package/dist/src/mcp/token-storage/keychain-token-storage.test.js +54 -3
  200. package/dist/src/mcp/token-storage/keychain-token-storage.test.js.map +1 -1
  201. package/dist/src/mcp/token-storage/types.d.ts +6 -0
  202. package/dist/src/mcp/token-storage/types.js.map +1 -1
  203. package/dist/src/output/stream-json-formatter.d.ts +32 -0
  204. package/dist/src/output/stream-json-formatter.js +52 -0
  205. package/dist/src/output/stream-json-formatter.js.map +1 -0
  206. package/dist/src/output/stream-json-formatter.test.d.ts +6 -0
  207. package/dist/src/output/stream-json-formatter.test.js +479 -0
  208. package/dist/src/output/stream-json-formatter.test.js.map +1 -0
  209. package/dist/src/output/types.d.ts +63 -1
  210. package/dist/src/output/types.js +11 -0
  211. package/dist/src/output/types.js.map +1 -1
  212. package/dist/src/policy/config.d.ts +31 -0
  213. package/dist/src/policy/config.js +197 -0
  214. package/dist/src/policy/config.js.map +1 -0
  215. package/dist/src/policy/config.test.d.ts +6 -0
  216. package/dist/src/policy/config.test.js +404 -0
  217. package/dist/src/policy/config.test.js.map +1 -0
  218. package/dist/src/policy/index.d.ts +2 -0
  219. package/dist/src/policy/index.js +2 -0
  220. package/dist/src/policy/index.js.map +1 -1
  221. package/dist/src/policy/policies/read-only.toml +56 -0
  222. package/dist/src/policy/policies/write.toml +63 -0
  223. package/dist/src/policy/policies/yolo.toml +31 -0
  224. package/dist/src/policy/policy-engine.js +4 -0
  225. package/dist/src/policy/policy-engine.js.map +1 -1
  226. package/dist/src/policy/toml-loader.d.ts +46 -0
  227. package/dist/src/policy/toml-loader.js +314 -0
  228. package/dist/src/policy/toml-loader.js.map +1 -0
  229. package/dist/src/policy/toml-loader.test.d.ts +6 -0
  230. package/dist/src/policy/toml-loader.test.js +522 -0
  231. package/dist/src/policy/toml-loader.test.js.map +1 -0
  232. package/dist/src/policy/types.d.ts +18 -0
  233. package/dist/src/policy/types.js +6 -0
  234. package/dist/src/policy/types.js.map +1 -1
  235. package/dist/src/prompts/prompt-registry.js +2 -1
  236. package/dist/src/prompts/prompt-registry.js.map +1 -1
  237. package/dist/src/routing/strategies/classifierStrategy.js +3 -2
  238. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
  239. package/dist/src/services/chatCompressionService.d.ts +32 -0
  240. package/dist/src/services/chatCompressionService.js +162 -0
  241. package/dist/src/services/chatCompressionService.js.map +1 -0
  242. package/dist/src/services/chatCompressionService.test.d.ts +6 -0
  243. package/dist/src/services/chatCompressionService.test.js +209 -0
  244. package/dist/src/services/chatCompressionService.test.js.map +1 -0
  245. package/dist/src/services/chatRecordingService.js +9 -8
  246. package/dist/src/services/chatRecordingService.js.map +1 -1
  247. package/dist/src/services/fileDiscoveryService.d.ts +2 -14
  248. package/dist/src/services/fileDiscoveryService.js +19 -55
  249. package/dist/src/services/fileDiscoveryService.js.map +1 -1
  250. package/dist/src/services/fileDiscoveryService.test.js +91 -11
  251. package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
  252. package/dist/src/services/loopDetectionService.d.ts +1 -1
  253. package/dist/src/services/loopDetectionService.js +27 -13
  254. package/dist/src/services/loopDetectionService.js.map +1 -1
  255. package/dist/src/services/loopDetectionService.test.js +119 -11
  256. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  257. package/dist/src/services/shellExecutionService.js +50 -23
  258. package/dist/src/services/shellExecutionService.js.map +1 -1
  259. package/dist/src/services/shellExecutionService.test.js +82 -15
  260. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  261. package/dist/src/telemetry/activity-monitor.d.ts +116 -0
  262. package/dist/src/telemetry/activity-monitor.js +209 -0
  263. package/dist/src/telemetry/activity-monitor.js.map +1 -0
  264. package/dist/src/telemetry/activity-monitor.test.d.ts +6 -0
  265. package/dist/src/telemetry/activity-monitor.test.js +248 -0
  266. package/dist/src/telemetry/activity-monitor.test.js.map +1 -0
  267. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +5 -1
  268. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +135 -57
  269. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  270. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +43 -75
  271. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  272. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +7 -1
  273. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +13 -1
  274. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  275. package/dist/src/telemetry/gcp-exporters.js +0 -1
  276. package/dist/src/telemetry/gcp-exporters.js.map +1 -1
  277. package/dist/src/telemetry/gcp-exporters.test.js +1 -1
  278. package/dist/src/telemetry/gcp-exporters.test.js.map +1 -1
  279. package/dist/src/telemetry/index.d.ts +4 -2
  280. package/dist/src/telemetry/index.js +5 -3
  281. package/dist/src/telemetry/index.js.map +1 -1
  282. package/dist/src/telemetry/loggers.d.ts +2 -1
  283. package/dist/src/telemetry/loggers.js +37 -26
  284. package/dist/src/telemetry/loggers.js.map +1 -1
  285. package/dist/src/telemetry/loggers.test.js +215 -56
  286. package/dist/src/telemetry/loggers.test.js.map +1 -1
  287. package/dist/src/telemetry/metrics.d.ts +55 -6
  288. package/dist/src/telemetry/metrics.js +89 -1
  289. package/dist/src/telemetry/metrics.js.map +1 -1
  290. package/dist/src/telemetry/metrics.test.js +172 -213
  291. package/dist/src/telemetry/metrics.test.js.map +1 -1
  292. package/dist/src/telemetry/sdk.js +3 -2
  293. package/dist/src/telemetry/sdk.js.map +1 -1
  294. package/dist/src/telemetry/semantic.d.ts +82 -0
  295. package/dist/src/telemetry/semantic.js +269 -0
  296. package/dist/src/telemetry/semantic.js.map +1 -0
  297. package/dist/src/telemetry/semantic.test.d.ts +6 -0
  298. package/dist/src/telemetry/semantic.test.js +387 -0
  299. package/dist/src/telemetry/semantic.test.js.map +1 -0
  300. package/dist/src/telemetry/telemetry-utils.test.js +29 -28
  301. package/dist/src/telemetry/telemetry-utils.test.js.map +1 -1
  302. package/dist/src/telemetry/trace.d.ts +46 -0
  303. package/dist/src/telemetry/trace.js +121 -0
  304. package/dist/src/telemetry/trace.js.map +1 -0
  305. package/dist/src/telemetry/types.d.ts +79 -34
  306. package/dist/src/telemetry/types.js +191 -61
  307. package/dist/src/telemetry/types.js.map +1 -1
  308. package/dist/src/telemetry/uiTelemetry.js +6 -6
  309. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  310. package/dist/src/telemetry/uiTelemetry.test.js +88 -66
  311. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  312. package/dist/src/tools/edit.d.ts +3 -2
  313. package/dist/src/tools/edit.js +24 -19
  314. package/dist/src/tools/edit.js.map +1 -1
  315. package/dist/src/tools/edit.test.js +78 -2
  316. package/dist/src/tools/edit.test.js.map +1 -1
  317. package/dist/src/tools/glob.d.ts +3 -2
  318. package/dist/src/tools/glob.js +15 -19
  319. package/dist/src/tools/glob.js.map +1 -1
  320. package/dist/src/tools/glob.test.js +203 -199
  321. package/dist/src/tools/glob.test.js.map +1 -1
  322. package/dist/src/tools/grep.d.ts +3 -2
  323. package/dist/src/tools/grep.js +22 -16
  324. package/dist/src/tools/grep.js.map +1 -1
  325. package/dist/src/tools/ls.d.ts +3 -2
  326. package/dist/src/tools/ls.js +15 -20
  327. package/dist/src/tools/ls.js.map +1 -1
  328. package/dist/src/tools/ls.test.js +2 -9
  329. package/dist/src/tools/ls.test.js.map +1 -1
  330. package/dist/src/tools/mcp-client-manager.d.ts +49 -11
  331. package/dist/src/tools/mcp-client-manager.js +209 -31
  332. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  333. package/dist/src/tools/mcp-client-manager.test.js +132 -25
  334. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  335. package/dist/src/tools/mcp-client.d.ts +5 -1
  336. package/dist/src/tools/mcp-client.js +85 -104
  337. package/dist/src/tools/mcp-client.js.map +1 -1
  338. package/dist/src/tools/mcp-client.test.js +65 -6
  339. package/dist/src/tools/mcp-client.test.js.map +1 -1
  340. package/dist/src/tools/mcp-tool.d.ts +5 -2
  341. package/dist/src/tools/mcp-tool.js +16 -8
  342. package/dist/src/tools/mcp-tool.js.map +1 -1
  343. package/dist/src/tools/memoryTool.d.ts +6 -4
  344. package/dist/src/tools/memoryTool.js +13 -10
  345. package/dist/src/tools/memoryTool.js.map +1 -1
  346. package/dist/src/tools/message-bus-integration.test.js +14 -1
  347. package/dist/src/tools/message-bus-integration.test.js.map +1 -1
  348. package/dist/src/tools/modifiable-tool.js +3 -2
  349. package/dist/src/tools/modifiable-tool.js.map +1 -1
  350. package/dist/src/tools/read-file.d.ts +4 -3
  351. package/dist/src/tools/read-file.js +16 -11
  352. package/dist/src/tools/read-file.js.map +1 -1
  353. package/dist/src/tools/read-file.test.js +25 -2
  354. package/dist/src/tools/read-file.test.js.map +1 -1
  355. package/dist/src/tools/read-many-files.d.ts +4 -3
  356. package/dist/src/tools/read-many-files.js +19 -37
  357. package/dist/src/tools/read-many-files.js.map +1 -1
  358. package/dist/src/tools/read-many-files.test.js +0 -1
  359. package/dist/src/tools/read-many-files.test.js.map +1 -1
  360. package/dist/src/tools/ripGrep.d.ts +3 -2
  361. package/dist/src/tools/ripGrep.js +47 -17
  362. package/dist/src/tools/ripGrep.js.map +1 -1
  363. package/dist/src/tools/ripGrep.test.js +106 -60
  364. package/dist/src/tools/ripGrep.test.js.map +1 -1
  365. package/dist/src/tools/shell.d.ts +7 -5
  366. package/dist/src/tools/shell.js +39 -68
  367. package/dist/src/tools/shell.js.map +1 -1
  368. package/dist/src/tools/shell.test.js +69 -9
  369. package/dist/src/tools/shell.test.js.map +1 -1
  370. package/dist/src/tools/smart-edit.d.ts +3 -2
  371. package/dist/src/tools/smart-edit.js +30 -18
  372. package/dist/src/tools/smart-edit.js.map +1 -1
  373. package/dist/src/tools/smart-edit.test.js +62 -2
  374. package/dist/src/tools/smart-edit.test.js.map +1 -1
  375. package/dist/src/tools/tool-names.d.ts +8 -0
  376. package/dist/src/tools/tool-names.js +8 -5
  377. package/dist/src/tools/tool-names.js.map +1 -1
  378. package/dist/src/tools/tool-registry.d.ts +6 -19
  379. package/dist/src/tools/tool-registry.js +14 -49
  380. package/dist/src/tools/tool-registry.js.map +1 -1
  381. package/dist/src/tools/tool-registry.test.js +2 -24
  382. package/dist/src/tools/tool-registry.test.js.map +1 -1
  383. package/dist/src/tools/tools.d.ts +22 -8
  384. package/dist/src/tools/tools.js +65 -36
  385. package/dist/src/tools/tools.js.map +1 -1
  386. package/dist/src/tools/web-fetch.d.ts +4 -3
  387. package/dist/src/tools/web-fetch.js +37 -25
  388. package/dist/src/tools/web-fetch.js.map +1 -1
  389. package/dist/src/tools/web-fetch.test.js +262 -1
  390. package/dist/src/tools/web-fetch.test.js.map +1 -1
  391. package/dist/src/tools/web-search.d.ts +4 -3
  392. package/dist/src/tools/web-search.js +8 -6
  393. package/dist/src/tools/web-search.js.map +1 -1
  394. package/dist/src/tools/write-file.d.ts +3 -2
  395. package/dist/src/tools/write-file.js +8 -8
  396. package/dist/src/tools/write-file.js.map +1 -1
  397. package/dist/src/tools/write-file.test.js +1 -2
  398. package/dist/src/tools/write-file.test.js.map +1 -1
  399. package/dist/src/tools/write-todos.d.ts +4 -8
  400. package/dist/src/tools/write-todos.js +15 -6
  401. package/dist/src/tools/write-todos.js.map +1 -1
  402. package/dist/src/tools/write-todos.test.js +2 -2
  403. package/dist/src/tools/write-todos.test.js.map +1 -1
  404. package/dist/src/utils/bfsFileSearch.js +3 -2
  405. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  406. package/dist/src/utils/channel.d.ts +19 -0
  407. package/dist/src/utils/channel.js +49 -0
  408. package/dist/src/utils/channel.js.map +1 -0
  409. package/dist/src/utils/channel.test.d.ts +6 -0
  410. package/dist/src/utils/channel.test.js +170 -0
  411. package/dist/src/utils/channel.test.js.map +1 -0
  412. package/dist/src/utils/debugLogger.d.ts +25 -0
  413. package/dist/src/utils/debugLogger.js +33 -0
  414. package/dist/src/utils/debugLogger.js.map +1 -0
  415. package/dist/src/utils/debugLogger.test.d.ts +6 -0
  416. package/dist/src/utils/debugLogger.test.js +67 -0
  417. package/dist/src/utils/debugLogger.test.js.map +1 -0
  418. package/dist/src/utils/delay.d.ts +16 -0
  419. package/dist/src/utils/delay.js +43 -0
  420. package/dist/src/utils/delay.js.map +1 -0
  421. package/dist/src/utils/delay.test.d.ts +6 -0
  422. package/dist/src/utils/delay.test.js +88 -0
  423. package/dist/src/utils/delay.test.js.map +1 -0
  424. package/dist/src/utils/editCorrector.js +5 -9
  425. package/dist/src/utils/editCorrector.js.map +1 -1
  426. package/dist/src/utils/editCorrector.test.js +3 -5
  427. package/dist/src/utils/editCorrector.test.js.map +1 -1
  428. package/dist/src/utils/editor.js +33 -38
  429. package/dist/src/utils/editor.js.map +1 -1
  430. package/dist/src/utils/environmentContext.d.ts +2 -1
  431. package/dist/src/utils/environmentContext.js +18 -33
  432. package/dist/src/utils/environmentContext.js.map +1 -1
  433. package/dist/src/utils/environmentContext.test.js +0 -34
  434. package/dist/src/utils/environmentContext.test.js.map +1 -1
  435. package/dist/src/utils/errorParsing.d.ts +1 -1
  436. package/dist/src/utils/errorParsing.js +5 -33
  437. package/dist/src/utils/errorParsing.js.map +1 -1
  438. package/dist/src/utils/errorParsing.test.js +0 -88
  439. package/dist/src/utils/errorParsing.test.js.map +1 -1
  440. package/dist/src/utils/errors.d.ts +3 -0
  441. package/dist/src/utils/errors.js +6 -0
  442. package/dist/src/utils/errors.js.map +1 -1
  443. package/dist/src/utils/events.d.ts +88 -0
  444. package/dist/src/utils/events.js +77 -0
  445. package/dist/src/utils/events.js.map +1 -0
  446. package/dist/src/utils/events.test.d.ts +6 -0
  447. package/dist/src/utils/events.test.js +131 -0
  448. package/dist/src/utils/events.test.js.map +1 -0
  449. package/dist/src/utils/extensionLoader.d.ts +78 -0
  450. package/dist/src/utils/extensionLoader.js +162 -0
  451. package/dist/src/utils/extensionLoader.js.map +1 -0
  452. package/dist/src/utils/extensionLoader.test.d.ts +6 -0
  453. package/dist/src/utils/extensionLoader.test.js +90 -0
  454. package/dist/src/utils/extensionLoader.test.js.map +1 -0
  455. package/dist/src/utils/fetch.d.ts +1 -0
  456. package/dist/src/utils/fetch.js +4 -0
  457. package/dist/src/utils/fetch.js.map +1 -1
  458. package/dist/src/utils/fileUtils.d.ts +4 -0
  459. package/dist/src/utils/fileUtils.js +34 -2
  460. package/dist/src/utils/fileUtils.js.map +1 -1
  461. package/dist/src/utils/fileUtils.test.js +12 -1
  462. package/dist/src/utils/fileUtils.test.js.map +1 -1
  463. package/dist/src/utils/flashFallback.test.js +26 -45
  464. package/dist/src/utils/flashFallback.test.js.map +1 -1
  465. package/dist/src/utils/getFolderStructure.js +9 -17
  466. package/dist/src/utils/getFolderStructure.js.map +1 -1
  467. package/dist/src/utils/gitIgnoreParser.d.ts +4 -1
  468. package/dist/src/utils/gitIgnoreParser.js +28 -10
  469. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  470. package/dist/src/utils/gitIgnoreParser.test.js +58 -0
  471. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  472. package/dist/src/utils/googleErrors.d.ts +104 -0
  473. package/dist/src/utils/googleErrors.js +152 -0
  474. package/dist/src/utils/googleErrors.js.map +1 -0
  475. package/dist/src/utils/googleErrors.test.d.ts +6 -0
  476. package/dist/src/utils/googleErrors.test.js +301 -0
  477. package/dist/src/utils/googleErrors.test.js.map +1 -0
  478. package/dist/src/utils/googleQuotaErrors.d.ts +36 -0
  479. package/dist/src/utils/googleQuotaErrors.js +149 -0
  480. package/dist/src/utils/googleQuotaErrors.js.map +1 -0
  481. package/dist/src/utils/googleQuotaErrors.test.d.ts +6 -0
  482. package/dist/src/utils/googleQuotaErrors.test.js +311 -0
  483. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -0
  484. package/dist/src/utils/ignorePatterns.test.js +26 -30
  485. package/dist/src/utils/ignorePatterns.test.js.map +1 -1
  486. package/dist/src/utils/installationManager.js +2 -1
  487. package/dist/src/utils/installationManager.js.map +1 -1
  488. package/dist/src/utils/installationManager.test.js +3 -3
  489. package/dist/src/utils/installationManager.test.js.map +1 -1
  490. package/dist/src/utils/llm-edit-fixer.d.ts +1 -1
  491. package/dist/src/utils/llm-edit-fixer.js +29 -4
  492. package/dist/src/utils/llm-edit-fixer.js.map +1 -1
  493. package/dist/src/utils/llm-edit-fixer.test.js +21 -0
  494. package/dist/src/utils/llm-edit-fixer.test.js.map +1 -1
  495. package/dist/src/utils/memoryDiscovery.d.ts +11 -1
  496. package/dist/src/utils/memoryDiscovery.js +150 -11
  497. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  498. package/dist/src/utils/memoryDiscovery.test.js +157 -19
  499. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  500. package/dist/src/utils/memoryImportProcessor.js +3 -2
  501. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  502. package/dist/src/utils/nextSpeakerChecker.js +2 -1
  503. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  504. package/dist/src/utils/package.d.ts +12 -0
  505. package/dist/src/utils/package.js +15 -0
  506. package/dist/src/utils/package.js.map +1 -0
  507. package/dist/src/utils/paths.js +126 -26
  508. package/dist/src/utils/paths.js.map +1 -1
  509. package/dist/src/utils/paths.test.js +200 -68
  510. package/dist/src/utils/paths.test.js.map +1 -1
  511. package/dist/src/utils/quotaErrorDetection.d.ts +0 -2
  512. package/dist/src/utils/quotaErrorDetection.js +0 -46
  513. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  514. package/dist/src/utils/retry.d.ts +1 -0
  515. package/dist/src/utils/retry.js +57 -158
  516. package/dist/src/utils/retry.js.map +1 -1
  517. package/dist/src/utils/retry.test.js +48 -109
  518. package/dist/src/utils/retry.test.js.map +1 -1
  519. package/dist/src/utils/safeJsonStringify.d.ts +4 -4
  520. package/dist/src/utils/safeJsonStringify.js +31 -7
  521. package/dist/src/utils/safeJsonStringify.js.map +1 -1
  522. package/dist/src/utils/shell-utils.d.ts +14 -2
  523. package/dist/src/utils/shell-utils.js +381 -136
  524. package/dist/src/utils/shell-utils.js.map +1 -1
  525. package/dist/src/utils/shell-utils.test.js +242 -60
  526. package/dist/src/utils/shell-utils.test.js.map +1 -1
  527. package/dist/src/utils/summarizer.js +2 -1
  528. package/dist/src/utils/summarizer.js.map +1 -1
  529. package/dist/src/utils/summarizer.test.js +0 -1
  530. package/dist/src/utils/summarizer.test.js.map +1 -1
  531. package/dist/src/utils/systemEncoding.js +5 -4
  532. package/dist/src/utils/systemEncoding.js.map +1 -1
  533. package/dist/src/utils/tool-utils.d.ts +2 -2
  534. package/dist/src/utils/tool-utils.js +14 -5
  535. package/dist/src/utils/tool-utils.js.map +1 -1
  536. package/dist/src/utils/userAccountManager.js +5 -4
  537. package/dist/src/utils/userAccountManager.js.map +1 -1
  538. package/dist/src/utils/workspaceContext.js +3 -2
  539. package/dist/src/utils/workspaceContext.js.map +1 -1
  540. package/dist/src/utils/workspaceContext.test.js +2 -2
  541. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  542. package/dist/tsconfig.tsbuildinfo +1 -1
  543. package/package.json +13 -5
  544. package/dist/src/core/subagent.d.ts +0 -236
  545. package/dist/src/core/subagent.js +0 -482
  546. package/dist/src/core/subagent.js.map +0 -1
  547. package/dist/src/core/subagent.test.js +0 -556
  548. package/dist/src/core/subagent.test.js.map +0 -1
  549. /package/dist/src/{core/subagent.test.d.ts → commands/extensions.test.d.ts} +0 -0
@@ -3,15 +3,18 @@
3
3
  * Copyright 2025 Google LLC
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
- import { ToolConfirmationOutcome, ApprovalMode, logToolCall, ReadFileTool, ToolErrorType, ToolCallEvent, ShellTool, logToolOutputTruncated, ToolOutputTruncatedEvent, } from '../index.js';
6
+ import { ToolConfirmationOutcome, ApprovalMode, logToolCall, ToolErrorType, ToolCallEvent, logToolOutputTruncated, ToolOutputTruncatedEvent, runInDevTraceSpan, } from '../index.js';
7
+ import { READ_FILE_TOOL_NAME, SHELL_TOOL_NAME } from '../tools/tool-names.js';
7
8
  import { getResponseTextFromParts } from '../utils/generateContentResponseUtilities.js';
8
9
  import { isModifiableDeclarativeTool, modifyWithEditor, } from '../tools/modifiable-tool.js';
9
10
  import * as Diff from 'diff';
10
11
  import * as fs from 'node:fs/promises';
11
12
  import * as path from 'node:path';
13
+ import { isShellInvocationAllowlisted, SHELL_TOOL_NAMES, } from '../utils/shell-utils.js';
12
14
  import { doesToolInvocationMatch } from '../utils/tool-utils.js';
13
15
  import levenshtein from 'fast-levenshtein';
14
16
  import { ShellToolInvocation } from '../tools/shell.js';
17
+ import { MessageBusType } from '../confirmation-bus/types.js';
15
18
  /**
16
19
  * Formats tool output for a Gemini FunctionResponse.
17
20
  */
@@ -124,10 +127,10 @@ export async function truncateAndSaveToFile(content, callId, projectTempDir, thr
124
127
  return {
125
128
  content: `Tool output was too large and has been truncated.
126
129
  The full output has been saved to: ${outputFile}
127
- To read the complete output, use the ${ReadFileTool.Name} tool with the absolute file path above. For large files, you can use the offset and limit parameters to read specific sections:
128
- - ${ReadFileTool.Name} tool with offset=0, limit=100 to see the first 100 lines
129
- - ${ReadFileTool.Name} tool with offset=N to skip N lines from the beginning
130
- - ${ReadFileTool.Name} tool with limit=M to read only M lines at a time
130
+ To read the complete output, use the ${READ_FILE_TOOL_NAME} tool with the absolute file path above. For large files, you can use the offset and limit parameters to read specific sections:
131
+ - ${READ_FILE_TOOL_NAME} tool with offset=0, limit=100 to see the first 100 lines
132
+ - ${READ_FILE_TOOL_NAME} tool with offset=N to skip N lines from the beginning
133
+ - ${READ_FILE_TOOL_NAME} tool with limit=M to read only M lines at a time
131
134
  The truncated output below shows the beginning and end of the content. The marker '... [CONTENT TRUNCATED] ...' indicates where content was removed.
132
135
  This allows you to efficiently examine different parts of the output without loading the entire file.
133
136
  Truncated part of the output:
@@ -142,7 +145,9 @@ ${truncatedContent}`,
142
145
  }
143
146
  }
144
147
  export class CoreToolScheduler {
145
- toolRegistry;
148
+ // Static WeakMap to track which MessageBus instances already have a handler subscribed
149
+ // This prevents duplicate subscriptions when multiple CoreToolScheduler instances are created
150
+ static subscribedMessageBuses = new WeakMap();
146
151
  toolCalls = [];
147
152
  outputUpdateHandler;
148
153
  onAllToolCallsComplete;
@@ -152,17 +157,43 @@ export class CoreToolScheduler {
152
157
  onEditorClose;
153
158
  isFinalizingToolCalls = false;
154
159
  isScheduling = false;
160
+ isCancelling = false;
155
161
  requestQueue = [];
162
+ toolCallQueue = [];
163
+ completedToolCallsForBatch = [];
156
164
  constructor(options) {
157
165
  this.config = options.config;
158
- this.toolRegistry = options.config.getToolRegistry();
159
166
  this.outputUpdateHandler = options.outputUpdateHandler;
160
167
  this.onAllToolCallsComplete = options.onAllToolCallsComplete;
161
168
  this.onToolCallsUpdate = options.onToolCallsUpdate;
162
169
  this.getPreferredEditor = options.getPreferredEditor;
163
170
  this.onEditorClose = options.onEditorClose;
171
+ // Subscribe to message bus for ASK_USER policy decisions
172
+ // Use a static WeakMap to ensure we only subscribe ONCE per MessageBus instance
173
+ // This prevents memory leaks when multiple CoreToolScheduler instances are created
174
+ // (e.g., on every React render, or for each non-interactive tool call)
175
+ if (this.config.getEnableMessageBusIntegration()) {
176
+ const messageBus = this.config.getMessageBus();
177
+ // Check if we've already subscribed a handler to this message bus
178
+ if (!CoreToolScheduler.subscribedMessageBuses.has(messageBus)) {
179
+ // Create a shared handler that will be used for this message bus
180
+ const sharedHandler = (request) => {
181
+ // When ASK_USER policy decision is made, respond with requiresUserConfirmation=true
182
+ // to tell tools to use their legacy confirmation flow
183
+ messageBus.publish({
184
+ type: MessageBusType.TOOL_CONFIRMATION_RESPONSE,
185
+ correlationId: request.correlationId,
186
+ confirmed: false,
187
+ requiresUserConfirmation: true,
188
+ });
189
+ };
190
+ messageBus.subscribe(MessageBusType.TOOL_CONFIRMATION_REQUEST, sharedHandler);
191
+ // Store the handler in the WeakMap so we don't subscribe again
192
+ CoreToolScheduler.subscribedMessageBuses.set(messageBus, sharedHandler);
193
+ }
194
+ }
164
195
  }
165
- setStatusInternal(targetCallId, newStatus, auxiliaryData) {
196
+ setStatusInternal(targetCallId, newStatus, signal, auxiliaryData) {
166
197
  this.toolCalls = this.toolCalls.map((currentCall) => {
167
198
  if (currentCall.request.callId !== targetCallId ||
168
199
  currentCall.status === 'success' ||
@@ -292,7 +323,6 @@ export class CoreToolScheduler {
292
323
  }
293
324
  });
294
325
  this.notifyToolCallsUpdate();
295
- this.checkAndNotifyCompletion();
296
326
  }
297
327
  setArgsInternal(targetCallId, args) {
298
328
  this.toolCalls = this.toolCalls.map((call) => {
@@ -341,7 +371,7 @@ export class CoreToolScheduler {
341
371
  * @returns A suggestion string like " Did you mean 'tool'?" or " Did you mean one of: 'tool1', 'tool2'?", or an empty string if no suggestions are found.
342
372
  */
343
373
  getToolSuggestion(unknownToolName, topN = 3) {
344
- const allToolNames = this.toolRegistry.getAllToolNames();
374
+ const allToolNames = this.config.getToolRegistry().getAllToolNames();
345
375
  const matches = allToolNames.map((toolName) => ({
346
376
  name: toolName,
347
377
  distance: levenshtein.get(unknownToolName, toolName),
@@ -362,42 +392,70 @@ export class CoreToolScheduler {
362
392
  }
363
393
  }
364
394
  schedule(request, signal) {
365
- if (this.isRunning() || this.isScheduling) {
366
- return new Promise((resolve, reject) => {
367
- const abortHandler = () => {
368
- // Find and remove the request from the queue
369
- const index = this.requestQueue.findIndex((item) => item.request === request);
370
- if (index > -1) {
371
- this.requestQueue.splice(index, 1);
372
- reject(new Error('Tool call cancelled while in queue.'));
373
- }
374
- };
375
- signal.addEventListener('abort', abortHandler, { once: true });
376
- this.requestQueue.push({
377
- request,
378
- signal,
379
- resolve: () => {
380
- signal.removeEventListener('abort', abortHandler);
381
- resolve();
382
- },
383
- reject: (reason) => {
384
- signal.removeEventListener('abort', abortHandler);
385
- reject(reason);
386
- },
395
+ return runInDevTraceSpan({ name: 'schedule' }, async ({ metadata: spanMetadata }) => {
396
+ spanMetadata.input = request;
397
+ if (this.isRunning() || this.isScheduling) {
398
+ return new Promise((resolve, reject) => {
399
+ const abortHandler = () => {
400
+ // Find and remove the request from the queue
401
+ const index = this.requestQueue.findIndex((item) => item.request === request);
402
+ if (index > -1) {
403
+ this.requestQueue.splice(index, 1);
404
+ reject(new Error('Tool call cancelled while in queue.'));
405
+ }
406
+ };
407
+ signal.addEventListener('abort', abortHandler, { once: true });
408
+ this.requestQueue.push({
409
+ request,
410
+ signal,
411
+ resolve: () => {
412
+ signal.removeEventListener('abort', abortHandler);
413
+ resolve();
414
+ },
415
+ reject: (reason) => {
416
+ signal.removeEventListener('abort', abortHandler);
417
+ reject(reason);
418
+ },
419
+ });
387
420
  });
388
- });
421
+ }
422
+ return this._schedule(request, signal);
423
+ });
424
+ }
425
+ cancelAll(signal) {
426
+ if (this.isCancelling) {
427
+ return;
428
+ }
429
+ this.isCancelling = true;
430
+ // Cancel the currently active tool call, if there is one.
431
+ if (this.toolCalls.length > 0) {
432
+ const activeCall = this.toolCalls[0];
433
+ // Only cancel if it's in a cancellable state.
434
+ if (activeCall.status === 'awaiting_approval' ||
435
+ activeCall.status === 'executing' ||
436
+ activeCall.status === 'scheduled' ||
437
+ activeCall.status === 'validating') {
438
+ this.setStatusInternal(activeCall.request.callId, 'cancelled', signal, 'User cancelled the operation.');
439
+ }
389
440
  }
390
- return this._schedule(request, signal);
441
+ // Clear the queue and mark all queued items as cancelled for completion reporting.
442
+ this._cancelAllQueuedCalls();
443
+ // Finalize the batch immediately.
444
+ void this.checkAndNotifyCompletion(signal);
391
445
  }
392
446
  async _schedule(request, signal) {
393
447
  this.isScheduling = true;
448
+ this.isCancelling = false;
394
449
  try {
395
450
  if (this.isRunning()) {
396
451
  throw new Error('Cannot schedule new tool calls while other tool calls are actively running (executing or awaiting approval).');
397
452
  }
398
453
  const requestsToProcess = Array.isArray(request) ? request : [request];
454
+ this.completedToolCallsForBatch = [];
399
455
  const newToolCalls = requestsToProcess.map((reqInfo) => {
400
- const toolInstance = this.toolRegistry.getTool(reqInfo.name);
456
+ const toolInstance = this.config
457
+ .getToolRegistry()
458
+ .getTool(reqInfo.name);
401
459
  if (!toolInstance) {
402
460
  const suggestion = this.getToolSuggestion(reqInfo.name);
403
461
  const errorMessage = `Tool "${reqInfo.name}" not found in registry. Tools must use the exact names that are registered.${suggestion}`;
@@ -426,29 +484,55 @@ export class CoreToolScheduler {
426
484
  startTime: Date.now(),
427
485
  };
428
486
  });
429
- this.toolCalls = this.toolCalls.concat(newToolCalls);
430
- this.notifyToolCallsUpdate();
431
- for (const toolCall of newToolCalls) {
432
- if (toolCall.status !== 'validating') {
433
- continue;
487
+ this.toolCallQueue.push(...newToolCalls);
488
+ await this._processNextInQueue(signal);
489
+ }
490
+ finally {
491
+ this.isScheduling = false;
492
+ }
493
+ }
494
+ async _processNextInQueue(signal) {
495
+ // If there's already a tool being processed, or the queue is empty, stop.
496
+ if (this.toolCalls.length > 0 || this.toolCallQueue.length === 0) {
497
+ return;
498
+ }
499
+ // If cancellation happened between steps, handle it.
500
+ if (signal.aborted) {
501
+ this._cancelAllQueuedCalls();
502
+ // Finalize the batch.
503
+ await this.checkAndNotifyCompletion(signal);
504
+ return;
505
+ }
506
+ const toolCall = this.toolCallQueue.shift();
507
+ // This is now the single active tool call.
508
+ this.toolCalls = [toolCall];
509
+ this.notifyToolCallsUpdate();
510
+ // Handle tools that were already errored during creation.
511
+ if (toolCall.status === 'error') {
512
+ // An error during validation means this "active" tool is already complete.
513
+ // We need to check for batch completion to either finish or process the next in queue.
514
+ await this.checkAndNotifyCompletion(signal);
515
+ return;
516
+ }
517
+ // This logic is moved from the old `for` loop in `_schedule`.
518
+ if (toolCall.status === 'validating') {
519
+ const { request: reqInfo, invocation } = toolCall;
520
+ try {
521
+ if (signal.aborted) {
522
+ this.setStatusInternal(reqInfo.callId, 'cancelled', signal, 'Tool call cancelled by user.');
523
+ // The completion check will handle the cascade.
524
+ await this.checkAndNotifyCompletion(signal);
525
+ return;
434
526
  }
435
- const { request: reqInfo, invocation } = toolCall;
436
- try {
437
- if (signal.aborted) {
438
- this.setStatusInternal(reqInfo.callId, 'cancelled', 'Tool call cancelled by user.');
439
- continue;
440
- }
441
- const confirmationDetails = await invocation.shouldConfirmExecute(signal);
442
- if (!confirmationDetails) {
443
- this.setToolCallOutcome(reqInfo.callId, ToolConfirmationOutcome.ProceedAlways);
444
- this.setStatusInternal(reqInfo.callId, 'scheduled');
445
- continue;
446
- }
447
- const allowedTools = this.config.getAllowedTools() || [];
448
- if (this.config.getApprovalMode() === ApprovalMode.YOLO ||
449
- doesToolInvocationMatch(toolCall.tool, invocation, allowedTools)) {
527
+ const confirmationDetails = await invocation.shouldConfirmExecute(signal);
528
+ if (!confirmationDetails) {
529
+ this.setToolCallOutcome(reqInfo.callId, ToolConfirmationOutcome.ProceedAlways);
530
+ this.setStatusInternal(reqInfo.callId, 'scheduled', signal);
531
+ }
532
+ else {
533
+ if (this.isAutoApproved(toolCall)) {
450
534
  this.setToolCallOutcome(reqInfo.callId, ToolConfirmationOutcome.ProceedAlways);
451
- this.setStatusInternal(reqInfo.callId, 'scheduled');
535
+ this.setStatusInternal(reqInfo.callId, 'scheduled', signal);
452
536
  }
453
537
  else {
454
538
  // Allow IDE to resolve confirmation
@@ -468,35 +552,33 @@ export class CoreToolScheduler {
468
552
  ...confirmationDetails,
469
553
  onConfirm: (outcome, payload) => this.handleConfirmationResponse(reqInfo.callId, originalOnConfirm, outcome, signal, payload),
470
554
  };
471
- this.setStatusInternal(reqInfo.callId, 'awaiting_approval', wrappedConfirmationDetails);
555
+ this.setStatusInternal(reqInfo.callId, 'awaiting_approval', signal, wrappedConfirmationDetails);
472
556
  }
473
557
  }
474
- catch (error) {
475
- if (signal.aborted) {
476
- this.setStatusInternal(reqInfo.callId, 'cancelled', 'Tool call cancelled by user.');
477
- continue;
478
- }
479
- this.setStatusInternal(reqInfo.callId, 'error', createErrorResponse(reqInfo, error instanceof Error ? error : new Error(String(error)), ToolErrorType.UNHANDLED_EXCEPTION));
558
+ }
559
+ catch (error) {
560
+ if (signal.aborted) {
561
+ this.setStatusInternal(reqInfo.callId, 'cancelled', signal, 'Tool call cancelled by user.');
562
+ await this.checkAndNotifyCompletion(signal);
563
+ }
564
+ else {
565
+ this.setStatusInternal(reqInfo.callId, 'error', signal, createErrorResponse(reqInfo, error instanceof Error ? error : new Error(String(error)), ToolErrorType.UNHANDLED_EXCEPTION));
566
+ await this.checkAndNotifyCompletion(signal);
480
567
  }
481
568
  }
482
- await this.attemptExecutionOfScheduledCalls(signal);
483
- void this.checkAndNotifyCompletion();
484
- }
485
- finally {
486
- this.isScheduling = false;
487
569
  }
570
+ await this.attemptExecutionOfScheduledCalls(signal);
488
571
  }
489
572
  async handleConfirmationResponse(callId, originalOnConfirm, outcome, signal, payload) {
490
573
  const toolCall = this.toolCalls.find((c) => c.request.callId === callId && c.status === 'awaiting_approval');
491
574
  if (toolCall && toolCall.status === 'awaiting_approval') {
492
575
  await originalOnConfirm(outcome);
493
576
  }
494
- if (outcome === ToolConfirmationOutcome.ProceedAlways) {
495
- await this.autoApproveCompatiblePendingTools(signal, callId);
496
- }
497
577
  this.setToolCallOutcome(callId, outcome);
498
578
  if (outcome === ToolConfirmationOutcome.Cancel || signal.aborted) {
499
- this.setStatusInternal(callId, 'cancelled', 'User did not allow tool call');
579
+ // Instead of just cancelling one tool, trigger the full cancel cascade.
580
+ this.cancelAll(signal);
581
+ return; // `cancelAll` calls `checkAndNotifyCompletion`, so we can exit here.
500
582
  }
501
583
  else if (outcome === ToolConfirmationOutcome.ModifyWithEditor) {
502
584
  const waitingToolCall = toolCall;
@@ -506,13 +588,13 @@ export class CoreToolScheduler {
506
588
  if (!editorType) {
507
589
  return;
508
590
  }
509
- this.setStatusInternal(callId, 'awaiting_approval', {
591
+ this.setStatusInternal(callId, 'awaiting_approval', signal, {
510
592
  ...waitingToolCall.confirmationDetails,
511
593
  isModifying: true,
512
594
  });
513
595
  const { updatedParams, updatedDiff } = await modifyWithEditor(waitingToolCall.request.args, modifyContext, editorType, signal, this.onEditorClose);
514
596
  this.setArgsInternal(callId, updatedParams);
515
- this.setStatusInternal(callId, 'awaiting_approval', {
597
+ this.setStatusInternal(callId, 'awaiting_approval', signal, {
516
598
  ...waitingToolCall.confirmationDetails,
517
599
  fileDiff: updatedDiff,
518
600
  isModifying: false,
@@ -524,7 +606,7 @@ export class CoreToolScheduler {
524
606
  if (payload?.newContent && toolCall) {
525
607
  await this._applyInlineModify(toolCall, payload, signal);
526
608
  }
527
- this.setStatusInternal(callId, 'scheduled');
609
+ this.setStatusInternal(callId, 'scheduled', signal);
528
610
  }
529
611
  await this.attemptExecutionOfScheduledCalls(signal);
530
612
  }
@@ -544,7 +626,7 @@ export class CoreToolScheduler {
544
626
  const updatedParams = modifyContext.createUpdatedParams(currentContent, payload.newContent, toolCall.request.args);
545
627
  const updatedDiff = Diff.createPatch(modifyContext.getFilePath(toolCall.request.args), currentContent, payload.newContent, 'Current', 'Proposed');
546
628
  this.setArgsInternal(toolCall.request.callId, updatedParams);
547
- this.setStatusInternal(toolCall.request.callId, 'awaiting_approval', {
629
+ this.setStatusInternal(toolCall.request.callId, 'awaiting_approval', signal, {
548
630
  ...toolCall.confirmationDetails,
549
631
  fileDiff: updatedDiff,
550
632
  });
@@ -562,7 +644,7 @@ export class CoreToolScheduler {
562
644
  const scheduledCall = toolCall;
563
645
  const { callId, name: toolName } = scheduledCall.request;
564
646
  const invocation = scheduledCall.invocation;
565
- this.setStatusInternal(callId, 'executing');
647
+ this.setStatusInternal(callId, 'executing', signal);
566
648
  const liveOutputCallback = scheduledCall.tool.canUpdateOutput && this.outputUpdateHandler
567
649
  ? (outputChunk) => {
568
650
  if (this.outputUpdateHandler) {
@@ -575,103 +657,142 @@ export class CoreToolScheduler {
575
657
  }
576
658
  : undefined;
577
659
  const shellExecutionConfig = this.config.getShellExecutionConfig();
578
- // TODO: Refactor to remove special casing for ShellToolInvocation.
579
- // Introduce a generic callbacks object for the execute method to handle
580
- // things like `onPid` and `onLiveOutput`. This will make the scheduler
581
- // agnostic to the invocation type.
582
- let promise;
583
- if (invocation instanceof ShellToolInvocation) {
584
- const setPidCallback = (pid) => {
585
- this.toolCalls = this.toolCalls.map((tc) => tc.request.callId === callId && tc.status === 'executing'
586
- ? { ...tc, pid }
587
- : tc);
588
- this.notifyToolCallsUpdate();
660
+ await runInDevTraceSpan({
661
+ name: toolCall.tool.name,
662
+ attributes: { type: 'tool-call' },
663
+ }, async ({ metadata: spanMetadata }) => {
664
+ spanMetadata.input = {
665
+ request: toolCall.request,
589
666
  };
590
- promise = invocation.execute(signal, liveOutputCallback, shellExecutionConfig, setPidCallback);
591
- }
592
- else {
593
- promise = invocation.execute(signal, liveOutputCallback, shellExecutionConfig);
594
- }
595
- try {
596
- const toolResult = await promise;
597
- if (signal.aborted) {
598
- this.setStatusInternal(callId, 'cancelled', 'User cancelled tool execution.');
599
- continue;
600
- }
601
- if (toolResult.error === undefined) {
602
- let content = toolResult.llmContent;
603
- let outputFile = undefined;
604
- const contentLength = typeof content === 'string' ? content.length : undefined;
605
- if (typeof content === 'string' &&
606
- toolName === ShellTool.Name &&
607
- this.config.getEnableToolOutputTruncation() &&
608
- this.config.getTruncateToolOutputThreshold() > 0 &&
609
- this.config.getTruncateToolOutputLines() > 0) {
610
- const originalContentLength = content.length;
611
- const threshold = this.config.getTruncateToolOutputThreshold();
612
- const lines = this.config.getTruncateToolOutputLines();
613
- const truncatedResult = await truncateAndSaveToFile(content, callId, this.config.storage.getProjectTempDir(), threshold, lines);
614
- content = truncatedResult.content;
615
- outputFile = truncatedResult.outputFile;
616
- if (outputFile) {
617
- logToolOutputTruncated(this.config, new ToolOutputTruncatedEvent(scheduledCall.request.prompt_id, {
618
- toolName,
619
- originalContentLength,
620
- truncatedContentLength: content.length,
621
- threshold,
622
- lines,
623
- }));
624
- }
625
- }
626
- const response = convertToFunctionResponse(toolName, callId, content);
627
- const successResponse = {
628
- callId,
629
- responseParts: response,
630
- resultDisplay: toolResult.returnDisplay,
631
- error: undefined,
632
- errorType: undefined,
633
- outputFile,
634
- contentLength,
667
+ // TODO: Refactor to remove special casing for ShellToolInvocation.
668
+ // Introduce a generic callbacks object for the execute method to handle
669
+ // things like `onPid` and `onLiveOutput`. This will make the scheduler
670
+ // agnostic to the invocation type.
671
+ let promise;
672
+ if (invocation instanceof ShellToolInvocation) {
673
+ const setPidCallback = (pid) => {
674
+ this.toolCalls = this.toolCalls.map((tc) => tc.request.callId === callId && tc.status === 'executing'
675
+ ? { ...tc, pid }
676
+ : tc);
677
+ this.notifyToolCallsUpdate();
635
678
  };
636
- this.setStatusInternal(callId, 'success', successResponse);
679
+ promise = invocation.execute(signal, liveOutputCallback, shellExecutionConfig, setPidCallback);
637
680
  }
638
681
  else {
639
- // It is a failure
640
- const error = new Error(toolResult.error.message);
641
- const errorResponse = createErrorResponse(scheduledCall.request, error, toolResult.error.type);
642
- this.setStatusInternal(callId, 'error', errorResponse);
682
+ promise = invocation.execute(signal, liveOutputCallback, shellExecutionConfig);
643
683
  }
644
- }
645
- catch (executionError) {
646
- if (signal.aborted) {
647
- this.setStatusInternal(callId, 'cancelled', 'User cancelled tool execution.');
684
+ try {
685
+ const toolResult = await promise;
686
+ spanMetadata.output = toolResult;
687
+ if (signal.aborted) {
688
+ this.setStatusInternal(callId, 'cancelled', signal, 'User cancelled tool execution.');
689
+ }
690
+ else if (toolResult.error === undefined) {
691
+ let content = toolResult.llmContent;
692
+ let outputFile = undefined;
693
+ const contentLength = typeof content === 'string' ? content.length : undefined;
694
+ if (typeof content === 'string' &&
695
+ toolName === SHELL_TOOL_NAME &&
696
+ this.config.getEnableToolOutputTruncation() &&
697
+ this.config.getTruncateToolOutputThreshold() > 0 &&
698
+ this.config.getTruncateToolOutputLines() > 0) {
699
+ const originalContentLength = content.length;
700
+ const threshold = this.config.getTruncateToolOutputThreshold();
701
+ const lines = this.config.getTruncateToolOutputLines();
702
+ const truncatedResult = await truncateAndSaveToFile(content, callId, this.config.storage.getProjectTempDir(), threshold, lines);
703
+ content = truncatedResult.content;
704
+ outputFile = truncatedResult.outputFile;
705
+ if (outputFile) {
706
+ logToolOutputTruncated(this.config, new ToolOutputTruncatedEvent(scheduledCall.request.prompt_id, {
707
+ toolName,
708
+ originalContentLength,
709
+ truncatedContentLength: content.length,
710
+ threshold,
711
+ lines,
712
+ }));
713
+ }
714
+ }
715
+ const response = convertToFunctionResponse(toolName, callId, content);
716
+ const successResponse = {
717
+ callId,
718
+ responseParts: response,
719
+ resultDisplay: toolResult.returnDisplay,
720
+ error: undefined,
721
+ errorType: undefined,
722
+ outputFile,
723
+ contentLength,
724
+ };
725
+ this.setStatusInternal(callId, 'success', signal, successResponse);
726
+ }
727
+ else {
728
+ // It is a failure
729
+ const error = new Error(toolResult.error.message);
730
+ const errorResponse = createErrorResponse(scheduledCall.request, error, toolResult.error.type);
731
+ this.setStatusInternal(callId, 'error', signal, errorResponse);
732
+ }
648
733
  }
649
- else {
650
- this.setStatusInternal(callId, 'error', createErrorResponse(scheduledCall.request, executionError instanceof Error
651
- ? executionError
652
- : new Error(String(executionError)), ToolErrorType.UNHANDLED_EXCEPTION));
734
+ catch (executionError) {
735
+ spanMetadata.error = executionError;
736
+ if (signal.aborted) {
737
+ this.setStatusInternal(callId, 'cancelled', signal, 'User cancelled tool execution.');
738
+ }
739
+ else {
740
+ this.setStatusInternal(callId, 'error', signal, createErrorResponse(scheduledCall.request, executionError instanceof Error
741
+ ? executionError
742
+ : new Error(String(executionError)), ToolErrorType.UNHANDLED_EXCEPTION));
743
+ }
653
744
  }
654
- }
745
+ await this.checkAndNotifyCompletion(signal);
746
+ });
655
747
  }
656
748
  }
657
749
  }
658
- async checkAndNotifyCompletion() {
659
- const allCallsAreTerminal = this.toolCalls.every((call) => call.status === 'success' ||
660
- call.status === 'error' ||
661
- call.status === 'cancelled');
662
- if (this.toolCalls.length > 0 && allCallsAreTerminal) {
663
- const completedCalls = [...this.toolCalls];
750
+ async checkAndNotifyCompletion(signal) {
751
+ // This method is now only concerned with the single active tool call.
752
+ if (this.toolCalls.length === 0) {
753
+ // It's possible to be called when a batch is cancelled before any tool has started.
754
+ if (signal.aborted && this.toolCallQueue.length > 0) {
755
+ this._cancelAllQueuedCalls();
756
+ }
757
+ }
758
+ else {
759
+ const activeCall = this.toolCalls[0];
760
+ const isTerminal = activeCall.status === 'success' ||
761
+ activeCall.status === 'error' ||
762
+ activeCall.status === 'cancelled';
763
+ // If the active tool is not in a terminal state (e.g., it's 'executing' or 'awaiting_approval'),
764
+ // then the scheduler is still busy or paused. We should not proceed.
765
+ if (!isTerminal) {
766
+ return;
767
+ }
768
+ // The active tool is finished. Move it to the completed batch.
769
+ const completedCall = activeCall;
770
+ this.completedToolCallsForBatch.push(completedCall);
771
+ logToolCall(this.config, new ToolCallEvent(completedCall));
772
+ // Clear the active tool slot. This is crucial for the sequential processing.
664
773
  this.toolCalls = [];
665
- for (const call of completedCalls) {
666
- logToolCall(this.config, new ToolCallEvent(call));
774
+ }
775
+ // Now, check if the entire batch is complete.
776
+ // The batch is complete if the queue is empty or the operation was cancelled.
777
+ if (this.toolCallQueue.length === 0 || signal.aborted) {
778
+ if (signal.aborted) {
779
+ this._cancelAllQueuedCalls();
780
+ }
781
+ // If there's nothing to report and we weren't cancelled, we can stop.
782
+ // But if we were cancelled, we must proceed to potentially start the next queued request.
783
+ if (this.completedToolCallsForBatch.length === 0 && !signal.aborted) {
784
+ return;
667
785
  }
668
786
  if (this.onAllToolCallsComplete) {
669
787
  this.isFinalizingToolCalls = true;
670
- await this.onAllToolCallsComplete(completedCalls);
788
+ // Use the batch array, not the (now empty) active array.
789
+ await this.onAllToolCallsComplete(this.completedToolCallsForBatch);
790
+ this.completedToolCallsForBatch = []; // Clear after reporting.
671
791
  this.isFinalizingToolCalls = false;
672
792
  }
793
+ this.isCancelling = false;
673
794
  this.notifyToolCallsUpdate();
674
- // After completion, process the next item in the queue.
795
+ // After completion of the entire batch, process the next item in the main request queue.
675
796
  if (this.requestQueue.length > 0) {
676
797
  const next = this.requestQueue.shift();
677
798
  this._schedule(next.request, next.signal)
@@ -679,10 +800,58 @@ export class CoreToolScheduler {
679
800
  .catch(next.reject);
680
801
  }
681
802
  }
803
+ else {
804
+ // The batch is not yet complete, so continue processing the current batch sequence.
805
+ await this._processNextInQueue(signal);
806
+ }
807
+ }
808
+ _cancelAllQueuedCalls() {
809
+ while (this.toolCallQueue.length > 0) {
810
+ const queuedCall = this.toolCallQueue.shift();
811
+ // Don't cancel tools that already errored during validation.
812
+ if (queuedCall.status === 'error') {
813
+ this.completedToolCallsForBatch.push(queuedCall);
814
+ continue;
815
+ }
816
+ const durationMs = 'startTime' in queuedCall && queuedCall.startTime
817
+ ? Date.now() - queuedCall.startTime
818
+ : undefined;
819
+ const errorMessage = '[Operation Cancelled] User cancelled the operation.';
820
+ this.completedToolCallsForBatch.push({
821
+ request: queuedCall.request,
822
+ tool: queuedCall.tool,
823
+ invocation: queuedCall.invocation,
824
+ status: 'cancelled',
825
+ response: {
826
+ callId: queuedCall.request.callId,
827
+ responseParts: [
828
+ {
829
+ functionResponse: {
830
+ id: queuedCall.request.callId,
831
+ name: queuedCall.request.name,
832
+ response: {
833
+ error: errorMessage,
834
+ },
835
+ },
836
+ },
837
+ ],
838
+ resultDisplay: undefined,
839
+ error: undefined,
840
+ errorType: undefined,
841
+ contentLength: errorMessage.length,
842
+ },
843
+ durationMs,
844
+ outcome: ToolConfirmationOutcome.Cancel,
845
+ });
846
+ }
682
847
  }
683
848
  notifyToolCallsUpdate() {
684
849
  if (this.onToolCallsUpdate) {
685
- this.onToolCallsUpdate([...this.toolCalls]);
850
+ this.onToolCallsUpdate([
851
+ ...this.completedToolCallsForBatch,
852
+ ...this.toolCalls,
853
+ ...this.toolCallQueue,
854
+ ]);
686
855
  }
687
856
  }
688
857
  setToolCallOutcome(callId, outcome) {
@@ -695,21 +864,17 @@ export class CoreToolScheduler {
695
864
  };
696
865
  });
697
866
  }
698
- async autoApproveCompatiblePendingTools(signal, triggeringCallId) {
699
- const pendingTools = this.toolCalls.filter((call) => call.status === 'awaiting_approval' &&
700
- call.request.callId !== triggeringCallId);
701
- for (const pendingTool of pendingTools) {
702
- try {
703
- const stillNeedsConfirmation = await pendingTool.invocation.shouldConfirmExecute(signal);
704
- if (!stillNeedsConfirmation) {
705
- this.setToolCallOutcome(pendingTool.request.callId, ToolConfirmationOutcome.ProceedAlways);
706
- this.setStatusInternal(pendingTool.request.callId, 'scheduled');
707
- }
708
- }
709
- catch (error) {
710
- console.error(`Error checking confirmation for tool ${pendingTool.request.callId}:`, error);
711
- }
867
+ isAutoApproved(toolCall) {
868
+ if (this.config.getApprovalMode() === ApprovalMode.YOLO) {
869
+ return true;
870
+ }
871
+ const allowedTools = this.config.getAllowedTools() || [];
872
+ const { tool, invocation } = toolCall;
873
+ const toolName = typeof tool === 'string' ? tool : tool.name;
874
+ if (SHELL_TOOL_NAMES.includes(toolName)) {
875
+ return isShellInvocationAllowlisted(invocation, allowedTools);
712
876
  }
877
+ return doesToolInvocationMatch(tool, invocation, allowedTools);
713
878
  }
714
879
  }
715
880
  //# sourceMappingURL=coreToolScheduler.js.map