@evalops/maestro 0.10.18 → 0.10.20

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 (922) hide show
  1. package/README.md +56 -1
  2. package/dist/agent/action-approval.d.ts +12 -2
  3. package/dist/agent/action-approval.d.ts.map +1 -1
  4. package/dist/agent/action-approval.js +19 -32
  5. package/dist/agent/action-approval.js.map +1 -1
  6. package/dist/agent/agent.d.ts +1 -0
  7. package/dist/agent/agent.d.ts.map +1 -1
  8. package/dist/agent/agent.js +26 -0
  9. package/dist/agent/agent.js.map +1 -1
  10. package/dist/agent/compaction.d.ts +2 -0
  11. package/dist/agent/compaction.d.ts.map +1 -1
  12. package/dist/agent/compaction.js +4 -2
  13. package/dist/agent/compaction.js.map +1 -1
  14. package/dist/agent/index.d.ts +1 -1
  15. package/dist/agent/index.d.ts.map +1 -1
  16. package/dist/agent/index.js +1 -1
  17. package/dist/agent/index.js.map +1 -1
  18. package/dist/agent/modes.d.ts +56 -4
  19. package/dist/agent/modes.d.ts.map +1 -1
  20. package/dist/agent/modes.js +163 -2
  21. package/dist/agent/modes.js.map +1 -1
  22. package/dist/agent/prompt-recovery.d.ts.map +1 -1
  23. package/dist/agent/prompt-recovery.js +1 -3
  24. package/dist/agent/prompt-recovery.js.map +1 -1
  25. package/dist/agent/providers/anthropic.d.ts.map +1 -1
  26. package/dist/agent/providers/anthropic.js +9 -1
  27. package/dist/agent/providers/anthropic.js.map +1 -1
  28. package/dist/agent/providers/codex-app-server.d.ts +12 -0
  29. package/dist/agent/providers/codex-app-server.d.ts.map +1 -0
  30. package/dist/agent/providers/codex-app-server.js +788 -0
  31. package/dist/agent/providers/codex-app-server.js.map +1 -0
  32. package/dist/agent/providers/google-gemini-cli.js +14 -3
  33. package/dist/agent/providers/google.js +22 -3
  34. package/dist/agent/providers/scripted.d.ts +11 -0
  35. package/dist/agent/providers/scripted.d.ts.map +1 -0
  36. package/dist/agent/providers/scripted.js +399 -0
  37. package/dist/agent/providers/scripted.js.map +1 -0
  38. package/dist/agent/providers/vertex.js +14 -3
  39. package/dist/agent/scenario-source.d.ts +19 -0
  40. package/dist/agent/scenario-source.d.ts.map +1 -0
  41. package/dist/agent/scenario-source.js +112 -0
  42. package/dist/agent/scenario-source.js.map +1 -0
  43. package/dist/agent/subagent-specs.d.ts +1 -1
  44. package/dist/agent/subagent-specs.js +1 -1
  45. package/dist/agent/subagent-specs.js.map +1 -1
  46. package/dist/agent/swarm/executor.d.ts +25 -0
  47. package/dist/agent/swarm/executor.d.ts.map +1 -1
  48. package/dist/agent/swarm/executor.js +795 -20
  49. package/dist/agent/swarm/executor.js.map +1 -1
  50. package/dist/agent/swarm/runtime-events.d.ts +11 -0
  51. package/dist/agent/swarm/runtime-events.d.ts.map +1 -0
  52. package/dist/agent/swarm/runtime-events.js +26 -0
  53. package/dist/agent/swarm/runtime-events.js.map +1 -0
  54. package/dist/agent/swarm/types.d.ts +78 -0
  55. package/dist/agent/swarm/types.d.ts.map +1 -1
  56. package/dist/agent/swarm/types.js.map +1 -1
  57. package/dist/agent/tracing.d.ts +1 -1
  58. package/dist/agent/tracing.d.ts.map +1 -1
  59. package/dist/agent/tracing.js +17 -9
  60. package/dist/agent/tracing.js.map +1 -1
  61. package/dist/agent/transport/create-provider-stream.d.ts.map +1 -1
  62. package/dist/agent/transport/create-provider-stream.js +14 -0
  63. package/dist/agent/transport/create-provider-stream.js.map +1 -1
  64. package/dist/agent/transport/stable-stringify.d.ts +2 -0
  65. package/dist/agent/transport/stable-stringify.d.ts.map +1 -0
  66. package/dist/agent/transport/stable-stringify.js +14 -0
  67. package/dist/agent/transport/stable-stringify.js.map +1 -0
  68. package/dist/agent/transport/tool-execution-bridge.d.ts.map +1 -1
  69. package/dist/agent/transport/tool-execution-bridge.js +2 -15
  70. package/dist/agent/transport/tool-execution-bridge.js.map +1 -1
  71. package/dist/agent/transport/tool-safety-pipeline.d.ts +5 -1
  72. package/dist/agent/transport/tool-safety-pipeline.d.ts.map +1 -1
  73. package/dist/agent/transport/tool-safety-pipeline.js +184 -36
  74. package/dist/agent/transport/tool-safety-pipeline.js.map +1 -1
  75. package/dist/agent/transport.d.ts +8 -0
  76. package/dist/agent/transport.d.ts.map +1 -1
  77. package/dist/agent/transport.js +1613 -68
  78. package/dist/agent/transport.js.map +1 -1
  79. package/dist/agent/types.d.ts +170 -2
  80. package/dist/agent/types.d.ts.map +1 -1
  81. package/dist/agent/types.js.map +1 -1
  82. package/dist/api/enterprise-routes.d.ts.map +1 -1
  83. package/dist/api/enterprise-routes.js +34 -3
  84. package/dist/api/enterprise-routes.js.map +1 -1
  85. package/dist/app-server/in-process-client.d.ts +32 -0
  86. package/dist/app-server/in-process-client.d.ts.map +1 -0
  87. package/dist/app-server/in-process-client.js +73 -0
  88. package/dist/app-server/in-process-client.js.map +1 -0
  89. package/dist/app-server/session-api.d.ts +36 -0
  90. package/dist/app-server/session-api.d.ts.map +1 -0
  91. package/dist/app-server/session-api.js +713 -0
  92. package/dist/app-server/session-api.js.map +1 -0
  93. package/dist/approvals/platform-action-approval.d.ts +3 -1
  94. package/dist/approvals/platform-action-approval.d.ts.map +1 -1
  95. package/dist/approvals/platform-action-approval.js +16 -9
  96. package/dist/approvals/platform-action-approval.js.map +1 -1
  97. package/dist/approvals/service-client.d.ts.map +1 -1
  98. package/dist/approvals/service-client.js +7 -7
  99. package/dist/approvals/service-client.js.map +1 -1
  100. package/dist/audit/logger.d.ts +4 -4
  101. package/dist/bootstrap/agent-creation-setup.d.ts +4 -0
  102. package/dist/bootstrap/agent-creation-setup.d.ts.map +1 -1
  103. package/dist/bootstrap/agent-creation-setup.js +3 -1
  104. package/dist/bootstrap/agent-creation-setup.js.map +1 -1
  105. package/dist/bootstrap/auth-setup.js +1 -1
  106. package/dist/bootstrap/auth-setup.js.map +1 -1
  107. package/dist/bootstrap/event-subscriptions-setup.d.ts +6 -0
  108. package/dist/bootstrap/event-subscriptions-setup.d.ts.map +1 -1
  109. package/dist/bootstrap/event-subscriptions-setup.js +26 -2
  110. package/dist/bootstrap/event-subscriptions-setup.js.map +1 -1
  111. package/dist/bootstrap/model-resolution-setup.d.ts.map +1 -1
  112. package/dist/bootstrap/model-resolution-setup.js +4 -1
  113. package/dist/bootstrap/model-resolution-setup.js.map +1 -1
  114. package/dist/bootstrap/tools-setup.d.ts +2 -1
  115. package/dist/bootstrap/tools-setup.d.ts.map +1 -1
  116. package/dist/bootstrap/tools-setup.js +5 -1
  117. package/dist/bootstrap/tools-setup.js.map +1 -1
  118. package/dist/cli/args.d.ts +9 -1
  119. package/dist/cli/args.d.ts.map +1 -1
  120. package/dist/cli/args.js +130 -5
  121. package/dist/cli/args.js.map +1 -1
  122. package/dist/cli/commands/a2a.d.ts +9 -0
  123. package/dist/cli/commands/a2a.d.ts.map +1 -0
  124. package/dist/cli/commands/a2a.js +1714 -0
  125. package/dist/cli/commands/a2a.js.map +1 -0
  126. package/dist/cli/commands/agents.d.ts +16 -2
  127. package/dist/cli/commands/agents.d.ts.map +1 -1
  128. package/dist/cli/commands/agents.js +223 -35
  129. package/dist/cli/commands/agents.js.map +1 -1
  130. package/dist/cli/commands/codex.d.ts +1 -1
  131. package/dist/cli/commands/codex.d.ts.map +1 -1
  132. package/dist/cli/commands/codex.js +145 -39
  133. package/dist/cli/commands/codex.js.map +1 -1
  134. package/dist/cli/commands/context.d.ts +10 -0
  135. package/dist/cli/commands/context.d.ts.map +1 -0
  136. package/dist/cli/commands/context.js +176 -0
  137. package/dist/cli/commands/context.js.map +1 -0
  138. package/dist/cli/commands/hosted-runner.d.ts +1 -0
  139. package/dist/cli/commands/hosted-runner.d.ts.map +1 -1
  140. package/dist/cli/commands/hosted-runner.js +9 -1
  141. package/dist/cli/commands/hosted-runner.js.map +1 -1
  142. package/dist/cli/commands/modes.d.ts +8 -0
  143. package/dist/cli/commands/modes.d.ts.map +1 -0
  144. package/dist/cli/commands/modes.js +151 -0
  145. package/dist/cli/commands/modes.js.map +1 -0
  146. package/dist/cli/commands/operating-plane.d.ts +14 -0
  147. package/dist/cli/commands/operating-plane.d.ts.map +1 -0
  148. package/dist/cli/commands/operating-plane.js +160 -0
  149. package/dist/cli/commands/operating-plane.js.map +1 -0
  150. package/dist/cli/commands/run.d.ts +87 -0
  151. package/dist/cli/commands/run.d.ts.map +1 -0
  152. package/dist/cli/commands/run.js +356 -0
  153. package/dist/cli/commands/run.js.map +1 -0
  154. package/dist/cli/commands/scenario.d.ts +7 -0
  155. package/dist/cli/commands/scenario.d.ts.map +1 -0
  156. package/dist/cli/commands/scenario.js +195 -0
  157. package/dist/cli/commands/scenario.js.map +1 -0
  158. package/dist/cli/commands/skill.d.ts +7 -0
  159. package/dist/cli/commands/skill.d.ts.map +1 -0
  160. package/dist/cli/commands/skill.js +286 -0
  161. package/dist/cli/commands/skill.js.map +1 -0
  162. package/dist/cli/headless-protocol.d.ts +55 -1
  163. package/dist/cli/headless-protocol.d.ts.map +1 -1
  164. package/dist/cli/headless-protocol.js +446 -7
  165. package/dist/cli/headless-protocol.js.map +1 -1
  166. package/dist/cli/headless-runtime-selection.d.ts +38 -0
  167. package/dist/cli/headless-runtime-selection.d.ts.map +1 -0
  168. package/dist/cli/headless-runtime-selection.js +48 -0
  169. package/dist/cli/headless-runtime-selection.js.map +1 -0
  170. package/dist/cli/headless.d.ts +5 -1
  171. package/dist/cli/headless.d.ts.map +1 -1
  172. package/dist/cli/headless.js +11 -1
  173. package/dist/cli/headless.js.map +1 -1
  174. package/dist/cli/help.d.ts +3 -1
  175. package/dist/cli/help.d.ts.map +1 -1
  176. package/dist/cli/help.js +135 -30
  177. package/dist/cli/help.js.map +1 -1
  178. package/dist/cli/system-prompt.d.ts +22 -4
  179. package/dist/cli/system-prompt.d.ts.map +1 -1
  180. package/dist/cli/system-prompt.js +224 -127
  181. package/dist/cli/system-prompt.js.map +1 -1
  182. package/dist/cli-tui/commands/a2a-handlers.d.ts +7 -0
  183. package/dist/cli-tui/commands/a2a-handlers.d.ts.map +1 -0
  184. package/dist/cli-tui/commands/a2a-handlers.js +160 -0
  185. package/dist/cli-tui/commands/a2a-handlers.js.map +1 -0
  186. package/dist/cli-tui/commands/command-catalog.d.ts.map +1 -1
  187. package/dist/cli-tui/commands/command-catalog.js +15 -0
  188. package/dist/cli-tui/commands/command-catalog.js.map +1 -1
  189. package/dist/cli-tui/commands/command-registry-adapter.js +10 -1
  190. package/dist/cli-tui/commands/command-registry-adapter.js.map +1 -1
  191. package/dist/cli-tui/commands/handlers/mode-handler.d.ts.map +1 -1
  192. package/dist/cli-tui/commands/handlers/mode-handler.js +22 -10
  193. package/dist/cli-tui/commands/handlers/mode-handler.js.map +1 -1
  194. package/dist/cli-tui/commands/mcp-handlers.d.ts.map +1 -1
  195. package/dist/cli-tui/commands/mcp-handlers.js +6 -5
  196. package/dist/cli-tui/commands/mcp-handlers.js.map +1 -1
  197. package/dist/cli-tui/commands/types.d.ts +1 -0
  198. package/dist/cli-tui/commands/types.d.ts.map +1 -1
  199. package/dist/cli-tui/commands/types.js.map +1 -1
  200. package/dist/cli-tui/commands/utility-handlers.d.ts +4 -0
  201. package/dist/cli-tui/commands/utility-handlers.d.ts.map +1 -1
  202. package/dist/cli-tui/commands/utility-handlers.js +45 -6
  203. package/dist/cli-tui/commands/utility-handlers.js.map +1 -1
  204. package/dist/cli-tui/run/run-shell-command.d.ts.map +1 -1
  205. package/dist/cli-tui/run/run-shell-command.js +14 -5
  206. package/dist/cli-tui/run/run-shell-command.js.map +1 -1
  207. package/dist/cli-tui/run/streaming-shell-command.d.ts.map +1 -1
  208. package/dist/cli-tui/run/streaming-shell-command.js +14 -5
  209. package/dist/cli-tui/run/streaming-shell-command.js.map +1 -1
  210. package/dist/cli-tui/selectors/model-selector.d.ts +1 -0
  211. package/dist/cli-tui/selectors/model-selector.d.ts.map +1 -1
  212. package/dist/cli-tui/selectors/model-selector.js +6 -2
  213. package/dist/cli-tui/selectors/model-selector.js.map +1 -1
  214. package/dist/cli-tui/tui-renderer/command-registry-options.d.ts.map +1 -1
  215. package/dist/cli-tui/tui-renderer/command-registry-options.js +5 -0
  216. package/dist/cli-tui/tui-renderer/command-registry-options.js.map +1 -1
  217. package/dist/cli-tui/utils/commands/review-prompt.d.ts +1 -1
  218. package/dist/cli-tui/utils/commands/review-prompt.d.ts.map +1 -1
  219. package/dist/cli-tui/utils/commands/review-prompt.js +8 -3
  220. package/dist/cli-tui/utils/commands/review-prompt.js.map +1 -1
  221. package/dist/cli-tui/utils/runtime-badges.d.ts +1 -0
  222. package/dist/cli-tui/utils/runtime-badges.d.ts.map +1 -1
  223. package/dist/cli-tui/utils/runtime-badges.js +7 -0
  224. package/dist/cli-tui/utils/runtime-badges.js.map +1 -1
  225. package/dist/cli-tui/utils/text-formatting.d.ts +1 -0
  226. package/dist/cli-tui/utils/text-formatting.d.ts.map +1 -1
  227. package/dist/cli-tui/utils/text-formatting.js +5 -0
  228. package/dist/cli-tui/utils/text-formatting.js.map +1 -1
  229. package/dist/cli.js +49158 -26161
  230. package/dist/cli.js.map +1 -1
  231. package/dist/codex/app-server-client.d.ts +139 -0
  232. package/dist/codex/app-server-client.d.ts.map +1 -0
  233. package/dist/codex/app-server-client.js +352 -0
  234. package/dist/codex/app-server-client.js.map +1 -0
  235. package/dist/codex/compatibility.d.ts +48 -0
  236. package/dist/codex/compatibility.d.ts.map +1 -0
  237. package/dist/codex/compatibility.js +344 -0
  238. package/dist/codex/compatibility.js.map +1 -0
  239. package/dist/codex/subagent-dispatch-table.d.ts +66 -0
  240. package/dist/codex/subagent-dispatch-table.d.ts.map +1 -0
  241. package/dist/codex/subagent-dispatch-table.js +127 -0
  242. package/dist/codex/subagent-dispatch-table.js.map +1 -0
  243. package/dist/codex/subagent-workgraph.d.ts +56 -0
  244. package/dist/codex/subagent-workgraph.d.ts.map +1 -0
  245. package/dist/codex/subagent-workgraph.js +89 -0
  246. package/dist/codex/subagent-workgraph.js.map +1 -0
  247. package/dist/config/constants.d.ts +3 -1
  248. package/dist/config/constants.d.ts.map +1 -1
  249. package/dist/config/constants.js +9 -0
  250. package/dist/config/constants.js.map +1 -1
  251. package/dist/config/feature-flags.d.ts +10 -1
  252. package/dist/config/feature-flags.d.ts.map +1 -1
  253. package/dist/config/feature-flags.js +17 -6
  254. package/dist/config/feature-flags.js.map +1 -1
  255. package/dist/config/index.d.ts +1 -1
  256. package/dist/config/index.d.ts.map +1 -1
  257. package/dist/config/index.js +1 -1
  258. package/dist/config/index.js.map +1 -1
  259. package/dist/config/toml-config.d.ts +32 -0
  260. package/dist/config/toml-config.d.ts.map +1 -1
  261. package/dist/config/toml-config.js +152 -43
  262. package/dist/config/toml-config.js.map +1 -1
  263. package/dist/connectors/service-client.d.ts.map +1 -1
  264. package/dist/connectors/service-client.js +4 -7
  265. package/dist/connectors/service-client.js.map +1 -1
  266. package/dist/context/manifest-types.d.ts +59 -0
  267. package/dist/context/manifest-types.d.ts.map +1 -0
  268. package/dist/context/manifest-types.js +2 -0
  269. package/dist/context/manifest-types.js.map +1 -0
  270. package/dist/context/manifest.d.ts +16 -0
  271. package/dist/context/manifest.d.ts.map +1 -0
  272. package/dist/context/manifest.js +503 -0
  273. package/dist/context/manifest.js.map +1 -0
  274. package/dist/db/schema.d.ts +10 -1
  275. package/dist/db/schema.d.ts.map +1 -1
  276. package/dist/db/schema.js.map +1 -1
  277. package/dist/evalops/env-aliases.d.ts +13 -0
  278. package/dist/evalops/env-aliases.d.ts.map +1 -0
  279. package/dist/evalops/env-aliases.js +60 -0
  280. package/dist/evalops/env-aliases.js.map +1 -0
  281. package/dist/evalops/managed-context.d.ts.map +1 -1
  282. package/dist/evalops/managed-context.js +28 -62
  283. package/dist/evalops/managed-context.js.map +1 -1
  284. package/dist/guardian/config.d.ts.map +1 -1
  285. package/dist/guardian/config.js +1 -0
  286. package/dist/guardian/config.js.map +1 -1
  287. package/dist/guardian/runner.d.ts +2 -0
  288. package/dist/guardian/runner.d.ts.map +1 -1
  289. package/dist/guardian/runner.js +105 -2
  290. package/dist/guardian/runner.js.map +1 -1
  291. package/dist/guardian/types.d.ts +1 -0
  292. package/dist/guardian/types.d.ts.map +1 -1
  293. package/dist/guardian/types.js.map +1 -1
  294. package/dist/index.d.ts +5 -1
  295. package/dist/index.d.ts.map +1 -1
  296. package/dist/index.js +5 -1
  297. package/dist/index.js.map +1 -1
  298. package/dist/main.d.ts.map +1 -1
  299. package/dist/main.js +267 -55
  300. package/dist/main.js.map +1 -1
  301. package/dist/mcp/config.d.ts.map +1 -1
  302. package/dist/mcp/config.js +89 -7
  303. package/dist/mcp/config.js.map +1 -1
  304. package/dist/mcp/manager.d.ts +5 -1
  305. package/dist/mcp/manager.d.ts.map +1 -1
  306. package/dist/mcp/manager.js +159 -4
  307. package/dist/mcp/manager.js.map +1 -1
  308. package/dist/mcp/platform-plugin.d.ts.map +1 -1
  309. package/dist/mcp/platform-plugin.js +9 -26
  310. package/dist/mcp/platform-plugin.js.map +1 -1
  311. package/dist/mcp/schema.d.ts +15 -0
  312. package/dist/mcp/schema.d.ts.map +1 -1
  313. package/dist/mcp/schema.js +24 -0
  314. package/dist/mcp/schema.js.map +1 -1
  315. package/dist/mcp/tool-bridge.d.ts +39 -10
  316. package/dist/mcp/tool-bridge.d.ts.map +1 -1
  317. package/dist/mcp/tool-bridge.js +101 -24
  318. package/dist/mcp/tool-bridge.js.map +1 -1
  319. package/dist/mcp/types.d.ts +27 -0
  320. package/dist/mcp/types.d.ts.map +1 -1
  321. package/dist/mcp/types.js.map +1 -1
  322. package/dist/mcp/workspace-trust.d.ts +10 -0
  323. package/dist/mcp/workspace-trust.d.ts.map +1 -0
  324. package/dist/mcp/workspace-trust.js +295 -0
  325. package/dist/mcp/workspace-trust.js.map +1 -0
  326. package/dist/memory/service-client.d.ts +1 -0
  327. package/dist/memory/service-client.d.ts.map +1 -1
  328. package/dist/memory/service-client.js +194 -9
  329. package/dist/memory/service-client.js.map +1 -1
  330. package/dist/models/builtin.d.ts.map +1 -1
  331. package/dist/models/builtin.js +66 -25
  332. package/dist/models/builtin.js.map +1 -1
  333. package/dist/models/config-loader.d.ts +10 -10
  334. package/dist/models/config-loader.d.ts.map +1 -1
  335. package/dist/models/config-loader.js +2 -0
  336. package/dist/models/config-loader.js.map +1 -1
  337. package/dist/models/registry.d.ts +1 -0
  338. package/dist/models/registry.d.ts.map +1 -1
  339. package/dist/models/registry.js +1 -0
  340. package/dist/models/registry.js.map +1 -1
  341. package/dist/oauth/device-identity.d.ts.map +1 -1
  342. package/dist/oauth/device-identity.js +1 -3
  343. package/dist/oauth/device-identity.js.map +1 -1
  344. package/dist/oauth/evalops.d.ts.map +1 -1
  345. package/dist/oauth/evalops.js +2 -5
  346. package/dist/oauth/evalops.js.map +1 -1
  347. package/dist/opentelemetry.d.ts.map +1 -1
  348. package/dist/opentelemetry.js +12 -12
  349. package/dist/opentelemetry.js.map +1 -1
  350. package/dist/package-version.d.ts +2 -0
  351. package/dist/package-version.d.ts.map +1 -0
  352. package/dist/package-version.js +11 -0
  353. package/dist/package-version.js.map +1 -0
  354. package/dist/packages/constants.d.ts +3 -0
  355. package/dist/packages/constants.d.ts.map +1 -0
  356. package/dist/packages/constants.js +3 -0
  357. package/dist/packages/constants.js.map +1 -0
  358. package/dist/packages/inspection.d.ts.map +1 -1
  359. package/dist/packages/inspection.js +2 -1
  360. package/dist/packages/inspection.js.map +1 -1
  361. package/dist/packages/search.d.ts.map +1 -1
  362. package/dist/packages/search.js +1 -1
  363. package/dist/packages/search.js.map +1 -1
  364. package/dist/platform/a2a-capability-market.d.ts +21 -0
  365. package/dist/platform/a2a-capability-market.d.ts.map +1 -0
  366. package/dist/platform/a2a-capability-market.js +176 -0
  367. package/dist/platform/a2a-capability-market.js.map +1 -0
  368. package/dist/platform/a2a-client.d.ts +119 -0
  369. package/dist/platform/a2a-client.d.ts.map +1 -1
  370. package/dist/platform/a2a-client.js +413 -24
  371. package/dist/platform/a2a-client.js.map +1 -1
  372. package/dist/platform/a2a-fleet.d.ts +41 -0
  373. package/dist/platform/a2a-fleet.d.ts.map +1 -0
  374. package/dist/platform/a2a-fleet.js +109 -0
  375. package/dist/platform/a2a-fleet.js.map +1 -0
  376. package/dist/platform/a2a-maestro-peer.d.ts +20 -0
  377. package/dist/platform/a2a-maestro-peer.d.ts.map +1 -0
  378. package/dist/platform/a2a-maestro-peer.js +176 -0
  379. package/dist/platform/a2a-maestro-peer.js.map +1 -0
  380. package/dist/platform/a2a-peer-pairing.d.ts +107 -0
  381. package/dist/platform/a2a-peer-pairing.d.ts.map +1 -0
  382. package/dist/platform/a2a-peer-pairing.js +489 -0
  383. package/dist/platform/a2a-peer-pairing.js.map +1 -0
  384. package/dist/platform/a2a-peer-registry.d.ts +68 -0
  385. package/dist/platform/a2a-peer-registry.d.ts.map +1 -0
  386. package/dist/platform/a2a-peer-registry.js +320 -0
  387. package/dist/platform/a2a-peer-registry.js.map +1 -0
  388. package/dist/platform/a2a-task-ledger.d.ts +86 -0
  389. package/dist/platform/a2a-task-ledger.d.ts.map +1 -0
  390. package/dist/platform/a2a-task-ledger.js +546 -0
  391. package/dist/platform/a2a-task-ledger.js.map +1 -0
  392. package/dist/platform/a2a-work-graph.d.ts +43 -0
  393. package/dist/platform/a2a-work-graph.d.ts.map +1 -0
  394. package/dist/platform/a2a-work-graph.js +267 -0
  395. package/dist/platform/a2a-work-graph.js.map +1 -0
  396. package/dist/platform/agent-registry-client.d.ts +327 -0
  397. package/dist/platform/agent-registry-client.d.ts.map +1 -0
  398. package/dist/platform/agent-registry-client.js +803 -0
  399. package/dist/platform/agent-registry-client.js.map +1 -0
  400. package/dist/platform/agent-runtime-client.d.ts +135 -1
  401. package/dist/platform/agent-runtime-client.d.ts.map +1 -1
  402. package/dist/platform/agent-runtime-client.js +467 -10
  403. package/dist/platform/agent-runtime-client.js.map +1 -1
  404. package/dist/platform/cerebro-facts-client.d.ts.map +1 -1
  405. package/dist/platform/cerebro-facts-client.js +4 -7
  406. package/dist/platform/cerebro-facts-client.js.map +1 -1
  407. package/dist/platform/client.d.ts.map +1 -1
  408. package/dist/platform/client.js +3 -12
  409. package/dist/platform/client.js.map +1 -1
  410. package/dist/platform/core-services.d.ts +68 -0
  411. package/dist/platform/core-services.d.ts.map +1 -1
  412. package/dist/platform/core-services.js +68 -0
  413. package/dist/platform/core-services.js.map +1 -1
  414. package/dist/platform/fermata-eval-client.d.ts +195 -0
  415. package/dist/platform/fermata-eval-client.d.ts.map +1 -0
  416. package/dist/platform/fermata-eval-client.js +146 -0
  417. package/dist/platform/fermata-eval-client.js.map +1 -0
  418. package/dist/platform/fermata-scenario-suite.d.ts +99 -0
  419. package/dist/platform/fermata-scenario-suite.d.ts.map +1 -0
  420. package/dist/platform/fermata-scenario-suite.js +459 -0
  421. package/dist/platform/fermata-scenario-suite.js.map +1 -0
  422. package/dist/platform/maestro-timeline-client.d.ts.map +1 -1
  423. package/dist/platform/maestro-timeline-client.js +5 -11
  424. package/dist/platform/maestro-timeline-client.js.map +1 -1
  425. package/dist/platform/operating-plane-client.d.ts +156 -0
  426. package/dist/platform/operating-plane-client.d.ts.map +1 -0
  427. package/dist/platform/operating-plane-client.js +131 -0
  428. package/dist/platform/operating-plane-client.js.map +1 -0
  429. package/dist/platform/operating-plane-summary.d.ts +47 -0
  430. package/dist/platform/operating-plane-summary.d.ts.map +1 -0
  431. package/dist/platform/operating-plane-summary.js +209 -0
  432. package/dist/platform/operating-plane-summary.js.map +1 -0
  433. package/dist/platform/tool-execution-client.d.ts.map +1 -1
  434. package/dist/platform/tool-execution-client.js +4 -11
  435. package/dist/platform/tool-execution-client.js.map +1 -1
  436. package/dist/prompts/service-client.d.ts.map +1 -1
  437. package/dist/prompts/service-client.js +3 -5
  438. package/dist/prompts/service-client.js.map +1 -1
  439. package/dist/prompts/system-prompt.d.ts +3 -0
  440. package/dist/prompts/system-prompt.d.ts.map +1 -1
  441. package/dist/prompts/system-prompt.js +13 -3
  442. package/dist/prompts/system-prompt.js.map +1 -1
  443. package/dist/prompts/types.d.ts +2 -0
  444. package/dist/prompts/types.d.ts.map +1 -1
  445. package/dist/prompts/types.js.map +1 -1
  446. package/dist/providers/api-keys.d.ts +1 -1
  447. package/dist/providers/api-keys.d.ts.map +1 -1
  448. package/dist/providers/api-keys.js +2 -1
  449. package/dist/providers/api-keys.js.map +1 -1
  450. package/dist/providers/auth.d.ts.map +1 -1
  451. package/dist/providers/auth.js +48 -25
  452. package/dist/providers/auth.js.map +1 -1
  453. package/dist/remote-runner/attach-client.d.ts.map +1 -1
  454. package/dist/remote-runner/attach-client.js +1 -0
  455. package/dist/remote-runner/attach-client.js.map +1 -1
  456. package/dist/remote-runner/client.d.ts.map +1 -1
  457. package/dist/remote-runner/client.js +4 -7
  458. package/dist/remote-runner/client.js.map +1 -1
  459. package/dist/rpc/rpc-types.d.ts.map +1 -1
  460. package/dist/rpc/rpc-types.js +1 -0
  461. package/dist/rpc/rpc-types.js.map +1 -1
  462. package/dist/safety/action-firewall.d.ts.map +1 -1
  463. package/dist/safety/action-firewall.js +69 -6
  464. package/dist/safety/action-firewall.js.map +1 -1
  465. package/dist/safety/attack-patterns.d.ts.map +1 -1
  466. package/dist/safety/attack-patterns.js +31 -14
  467. package/dist/safety/attack-patterns.js.map +1 -1
  468. package/dist/safety/bash-parser.d.ts.map +1 -1
  469. package/dist/safety/bash-parser.js +4 -3
  470. package/dist/safety/bash-parser.js.map +1 -1
  471. package/dist/safety/execpolicy.d.ts +15 -3
  472. package/dist/safety/execpolicy.d.ts.map +1 -1
  473. package/dist/safety/execpolicy.js +248 -37
  474. package/dist/safety/execpolicy.js.map +1 -1
  475. package/dist/safety/governance-service-client.d.ts.map +1 -1
  476. package/dist/safety/governance-service-client.js +4 -7
  477. package/dist/safety/governance-service-client.js.map +1 -1
  478. package/dist/safety/guarded-files.d.ts +34 -0
  479. package/dist/safety/guarded-files.d.ts.map +1 -0
  480. package/dist/safety/guarded-files.js +372 -0
  481. package/dist/safety/guarded-files.js.map +1 -0
  482. package/dist/safety/loop-detector.d.ts.map +1 -1
  483. package/dist/safety/loop-detector.js +6 -1
  484. package/dist/safety/loop-detector.js.map +1 -1
  485. package/dist/safety/permission-profile.d.ts +47 -0
  486. package/dist/safety/permission-profile.d.ts.map +1 -0
  487. package/dist/safety/permission-profile.js +349 -0
  488. package/dist/safety/permission-profile.js.map +1 -0
  489. package/dist/safety/safety-middleware.d.ts +5 -1
  490. package/dist/safety/safety-middleware.d.ts.map +1 -1
  491. package/dist/safety/safety-middleware.js +3 -2
  492. package/dist/safety/safety-middleware.js.map +1 -1
  493. package/dist/safety/suspicious-patterns.d.ts.map +1 -1
  494. package/dist/safety/suspicious-patterns.js +12 -7
  495. package/dist/safety/suspicious-patterns.js.map +1 -1
  496. package/dist/safety/tool-categorization.js +1 -1
  497. package/dist/safety/tool-categorization.js.map +1 -1
  498. package/dist/safety/validators/path-policy-validator.d.ts.map +1 -1
  499. package/dist/safety/validators/path-policy-validator.js +7 -0
  500. package/dist/safety/validators/path-policy-validator.js.map +1 -1
  501. package/dist/sandbox/index.d.ts +6 -1
  502. package/dist/sandbox/index.d.ts.map +1 -1
  503. package/dist/sandbox/index.js +30 -4
  504. package/dist/sandbox/index.js.map +1 -1
  505. package/dist/sandbox/native-sandbox.d.ts +3 -0
  506. package/dist/sandbox/native-sandbox.d.ts.map +1 -1
  507. package/dist/sandbox/native-sandbox.js +139 -18
  508. package/dist/sandbox/native-sandbox.js.map +1 -1
  509. package/dist/sentry.d.ts +17 -0
  510. package/dist/sentry.d.ts.map +1 -0
  511. package/dist/sentry.js +91 -0
  512. package/dist/sentry.js.map +1 -0
  513. package/dist/server/agent-runtime-ledger.d.ts +141 -0
  514. package/dist/server/agent-runtime-ledger.d.ts.map +1 -0
  515. package/dist/server/agent-runtime-ledger.js +334 -0
  516. package/dist/server/agent-runtime-ledger.js.map +1 -0
  517. package/dist/server/agent-trajectory-inspection.d.ts +104 -0
  518. package/dist/server/agent-trajectory-inspection.d.ts.map +1 -0
  519. package/dist/server/agent-trajectory-inspection.js +168 -0
  520. package/dist/server/agent-trajectory-inspection.js.map +1 -0
  521. package/dist/server/agent-trajectory-replay.d.ts +56 -0
  522. package/dist/server/agent-trajectory-replay.d.ts.map +1 -0
  523. package/dist/server/agent-trajectory-replay.js +214 -0
  524. package/dist/server/agent-trajectory-replay.js.map +1 -0
  525. package/dist/server/agent-trajectory-scenarios.d.ts +109 -0
  526. package/dist/server/agent-trajectory-scenarios.d.ts.map +1 -0
  527. package/dist/server/agent-trajectory-scenarios.js +822 -0
  528. package/dist/server/agent-trajectory-scenarios.js.map +1 -0
  529. package/dist/server/agent-trajectory-scorers.d.ts +61 -0
  530. package/dist/server/agent-trajectory-scorers.d.ts.map +1 -0
  531. package/dist/server/agent-trajectory-scorers.js +162 -0
  532. package/dist/server/agent-trajectory-scorers.js.map +1 -0
  533. package/dist/server/agent-trajectory-validation.d.ts +7 -0
  534. package/dist/server/agent-trajectory-validation.d.ts.map +1 -0
  535. package/dist/server/agent-trajectory-validation.js +101 -0
  536. package/dist/server/agent-trajectory-validation.js.map +1 -0
  537. package/dist/server/agent-trajectory.d.ts +50 -0
  538. package/dist/server/agent-trajectory.d.ts.map +1 -0
  539. package/dist/server/agent-trajectory.js +159 -0
  540. package/dist/server/agent-trajectory.js.map +1 -0
  541. package/dist/server/app-context.d.ts +18 -0
  542. package/dist/server/app-context.d.ts.map +1 -1
  543. package/dist/server/app-context.js.map +1 -1
  544. package/dist/server/handlers/headless-sessions.d.ts.map +1 -1
  545. package/dist/server/handlers/headless-sessions.js +64 -27
  546. package/dist/server/handlers/headless-sessions.js.map +1 -1
  547. package/dist/server/handlers/health.d.ts +6 -0
  548. package/dist/server/handlers/health.d.ts.map +1 -1
  549. package/dist/server/handlers/health.js +6 -0
  550. package/dist/server/handlers/health.js.map +1 -1
  551. package/dist/server/handlers/hosted-runner-drain.d.ts +69 -1
  552. package/dist/server/handlers/hosted-runner-drain.d.ts.map +1 -1
  553. package/dist/server/handlers/hosted-runner-drain.js +309 -18
  554. package/dist/server/handlers/hosted-runner-drain.js.map +1 -1
  555. package/dist/server/handlers/hosted-runner-identity.d.ts +16 -0
  556. package/dist/server/handlers/hosted-runner-identity.d.ts.map +1 -1
  557. package/dist/server/handlers/hosted-runner-identity.js +43 -0
  558. package/dist/server/handlers/hosted-runner-identity.js.map +1 -1
  559. package/dist/server/handlers/mode.d.ts.map +1 -1
  560. package/dist/server/handlers/mode.js +3 -1
  561. package/dist/server/handlers/mode.js.map +1 -1
  562. package/dist/server/handlers/pending-requests.d.ts.map +1 -1
  563. package/dist/server/handlers/pending-requests.js +336 -51
  564. package/dist/server/handlers/pending-requests.js.map +1 -1
  565. package/dist/server/handlers/platform-a2a-push.d.ts +6 -0
  566. package/dist/server/handlers/platform-a2a-push.d.ts.map +1 -0
  567. package/dist/server/handlers/platform-a2a-push.js +136 -0
  568. package/dist/server/handlers/platform-a2a-push.js.map +1 -0
  569. package/dist/server/handlers/sessions.d.ts.map +1 -1
  570. package/dist/server/handlers/sessions.js +21 -1
  571. package/dist/server/handlers/sessions.js.map +1 -1
  572. package/dist/server/headless-runtime-service.d.ts +9 -2
  573. package/dist/server/headless-runtime-service.d.ts.map +1 -1
  574. package/dist/server/headless-runtime-service.js +39 -0
  575. package/dist/server/headless-runtime-service.js.map +1 -1
  576. package/dist/server/hosted-agent-runtime-progress.d.ts +144 -0
  577. package/dist/server/hosted-agent-runtime-progress.d.ts.map +1 -0
  578. package/dist/server/hosted-agent-runtime-progress.js +1650 -0
  579. package/dist/server/hosted-agent-runtime-progress.js.map +1 -0
  580. package/dist/server/hosted-runner-lease.d.ts +41 -0
  581. package/dist/server/hosted-runner-lease.d.ts.map +1 -0
  582. package/dist/server/hosted-runner-lease.js +140 -0
  583. package/dist/server/hosted-runner-lease.js.map +1 -0
  584. package/dist/server/hosted-session-manager.d.ts +16 -8
  585. package/dist/server/hosted-session-manager.d.ts.map +1 -1
  586. package/dist/server/hosted-session-manager.js +98 -76
  587. package/dist/server/hosted-session-manager.js.map +1 -1
  588. package/dist/server/junit-xml.d.ts +2 -0
  589. package/dist/server/junit-xml.d.ts.map +1 -0
  590. package/dist/server/junit-xml.js +9 -0
  591. package/dist/server/junit-xml.js.map +1 -0
  592. package/dist/server/routes.d.ts.map +1 -1
  593. package/dist/server/routes.js +6 -0
  594. package/dist/server/routes.js.map +1 -1
  595. package/dist/server/scenario-recorder.d.ts +56 -0
  596. package/dist/server/scenario-recorder.d.ts.map +1 -0
  597. package/dist/server/scenario-recorder.js +109 -0
  598. package/dist/server/scenario-recorder.js.map +1 -0
  599. package/dist/server/scripted-scenario-runner.d.ts +46 -0
  600. package/dist/server/scripted-scenario-runner.d.ts.map +1 -0
  601. package/dist/server/scripted-scenario-runner.js +190 -0
  602. package/dist/server/scripted-scenario-runner.js.map +1 -0
  603. package/dist/server/server-middlewares.d.ts +6 -2
  604. package/dist/server/server-middlewares.d.ts.map +1 -1
  605. package/dist/server/server-middlewares.js +8 -2
  606. package/dist/server/server-middlewares.js.map +1 -1
  607. package/dist/server/server-request-manager.d.ts +9 -1
  608. package/dist/server/server-request-manager.d.ts.map +1 -1
  609. package/dist/server/server-request-manager.js +49 -4
  610. package/dist/server/server-request-manager.js.map +1 -1
  611. package/dist/services/intelligent-router/service.d.ts +2 -0
  612. package/dist/services/intelligent-router/service.d.ts.map +1 -1
  613. package/dist/services/intelligent-router/service.js +4 -0
  614. package/dist/services/intelligent-router/service.js.map +1 -1
  615. package/dist/services/service-authority.d.ts +25 -0
  616. package/dist/services/service-authority.d.ts.map +1 -0
  617. package/dist/services/service-authority.js +143 -0
  618. package/dist/services/service-authority.js.map +1 -0
  619. package/dist/services/workspace-config/service.d.ts +2 -0
  620. package/dist/services/workspace-config/service.d.ts.map +1 -1
  621. package/dist/services/workspace-config/service.js +4 -0
  622. package/dist/services/workspace-config/service.js.map +1 -1
  623. package/dist/session/manager.d.ts +8 -2
  624. package/dist/session/manager.d.ts.map +1 -1
  625. package/dist/session/manager.js +19 -4
  626. package/dist/session/manager.js.map +1 -1
  627. package/dist/session/session-branch.d.ts.map +1 -1
  628. package/dist/session/session-branch.js +5 -1
  629. package/dist/session/session-branch.js.map +1 -1
  630. package/dist/session/session-catalog.d.ts +7 -2
  631. package/dist/session/session-catalog.d.ts.map +1 -1
  632. package/dist/session/session-catalog.js +13 -2
  633. package/dist/session/session-catalog.js.map +1 -1
  634. package/dist/session/session-context.d.ts +6 -2
  635. package/dist/session/session-context.d.ts.map +1 -1
  636. package/dist/session/session-context.js +44 -4
  637. package/dist/session/session-context.js.map +1 -1
  638. package/dist/session/session-graph-projection.d.ts +32 -0
  639. package/dist/session/session-graph-projection.d.ts.map +1 -0
  640. package/dist/session/session-graph-projection.js +133 -0
  641. package/dist/session/session-graph-projection.js.map +1 -0
  642. package/dist/session/types.d.ts +18 -0
  643. package/dist/session/types.d.ts.map +1 -1
  644. package/dist/session/types.js +8 -0
  645. package/dist/session/types.js.map +1 -1
  646. package/dist/session/wire-format.generated.d.ts +3 -0
  647. package/dist/session/wire-format.generated.d.ts.map +1 -1
  648. package/dist/session/wire-format.generated.js +20 -0
  649. package/dist/session/wire-format.generated.js.map +1 -1
  650. package/dist/skills/eval-harness.d.ts +38 -0
  651. package/dist/skills/eval-harness.d.ts.map +1 -0
  652. package/dist/skills/eval-harness.js +112 -0
  653. package/dist/skills/eval-harness.js.map +1 -0
  654. package/dist/skills/index.d.ts +5 -1
  655. package/dist/skills/index.d.ts.map +1 -1
  656. package/dist/skills/index.js +5 -1
  657. package/dist/skills/index.js.map +1 -1
  658. package/dist/skills/linter.d.ts +36 -0
  659. package/dist/skills/linter.d.ts.map +1 -0
  660. package/dist/skills/linter.js +398 -0
  661. package/dist/skills/linter.js.map +1 -0
  662. package/dist/skills/loader.d.ts +36 -6
  663. package/dist/skills/loader.d.ts.map +1 -1
  664. package/dist/skills/loader.js +169 -86
  665. package/dist/skills/loader.js.map +1 -1
  666. package/dist/skills/package-contract.d.ts +45 -0
  667. package/dist/skills/package-contract.d.ts.map +1 -0
  668. package/dist/skills/package-contract.js +153 -0
  669. package/dist/skills/package-contract.js.map +1 -0
  670. package/dist/skills/runtime-activation.d.ts +68 -0
  671. package/dist/skills/runtime-activation.d.ts.map +1 -0
  672. package/dist/skills/runtime-activation.js +228 -0
  673. package/dist/skills/runtime-activation.js.map +1 -0
  674. package/dist/skills/service-client.d.ts.map +1 -1
  675. package/dist/skills/service-client.js +3 -4
  676. package/dist/skills/service-client.js.map +1 -1
  677. package/dist/skills/tool.d.ts.map +1 -1
  678. package/dist/skills/tool.js +2 -0
  679. package/dist/skills/tool.js.map +1 -1
  680. package/dist/skills/types.d.ts +14 -0
  681. package/dist/skills/types.d.ts.map +1 -1
  682. package/dist/skills/types.js.map +1 -1
  683. package/dist/telemetry/agent-operating-plane-context.d.ts +24 -0
  684. package/dist/telemetry/agent-operating-plane-context.d.ts.map +1 -0
  685. package/dist/telemetry/agent-operating-plane-context.js +54 -0
  686. package/dist/telemetry/agent-operating-plane-context.js.map +1 -0
  687. package/dist/telemetry/beacon.d.ts +24 -0
  688. package/dist/telemetry/beacon.d.ts.map +1 -0
  689. package/dist/telemetry/beacon.js +115 -0
  690. package/dist/telemetry/beacon.js.map +1 -0
  691. package/dist/telemetry/cli-command-aggregator.d.ts +36 -0
  692. package/dist/telemetry/cli-command-aggregator.d.ts.map +1 -0
  693. package/dist/telemetry/cli-command-aggregator.js +251 -0
  694. package/dist/telemetry/cli-command-aggregator.js.map +1 -0
  695. package/dist/telemetry/cli-startup.d.ts +21 -0
  696. package/dist/telemetry/cli-startup.d.ts.map +1 -0
  697. package/dist/telemetry/cli-startup.js +83 -0
  698. package/dist/telemetry/cli-startup.js.map +1 -0
  699. package/dist/telemetry/disablement.d.ts +13 -0
  700. package/dist/telemetry/disablement.d.ts.map +1 -0
  701. package/dist/telemetry/disablement.js +19 -0
  702. package/dist/telemetry/disablement.js.map +1 -0
  703. package/dist/telemetry/index.d.ts +6 -2
  704. package/dist/telemetry/index.d.ts.map +1 -1
  705. package/dist/telemetry/index.js +6 -2
  706. package/dist/telemetry/index.js.map +1 -1
  707. package/dist/telemetry/maestro-event-bus.d.ts +52 -0
  708. package/dist/telemetry/maestro-event-bus.d.ts.map +1 -1
  709. package/dist/telemetry/maestro-event-bus.js +179 -3
  710. package/dist/telemetry/maestro-event-bus.js.map +1 -1
  711. package/dist/telemetry/maestro-event-catalog.d.ts +3 -1
  712. package/dist/telemetry/maestro-event-catalog.d.ts.map +1 -1
  713. package/dist/telemetry/maestro-event-catalog.js +2 -0
  714. package/dist/telemetry/maestro-event-catalog.js.map +1 -1
  715. package/dist/telemetry/maestro-platform-replay-fixture.d.ts.map +1 -1
  716. package/dist/telemetry/maestro-platform-replay-fixture.js +74 -9
  717. package/dist/telemetry/maestro-platform-replay-fixture.js.map +1 -1
  718. package/dist/telemetry/maestro-publisher-conformance-fixture.d.ts +1 -1
  719. package/dist/telemetry/maestro-publisher-conformance-fixture.d.ts.map +1 -1
  720. package/dist/telemetry/maestro-publisher-conformance-fixture.js +46 -11
  721. package/dist/telemetry/maestro-publisher-conformance-fixture.js.map +1 -1
  722. package/dist/telemetry/mcp-beacon.d.ts +20 -0
  723. package/dist/telemetry/mcp-beacon.d.ts.map +1 -0
  724. package/dist/telemetry/mcp-beacon.js +54 -0
  725. package/dist/telemetry/mcp-beacon.js.map +1 -0
  726. package/dist/telemetry/metadata-normalization.d.ts +7 -0
  727. package/dist/telemetry/metadata-normalization.d.ts.map +1 -0
  728. package/dist/telemetry/metadata-normalization.js +189 -0
  729. package/dist/telemetry/metadata-normalization.js.map +1 -0
  730. package/dist/telemetry/meter-service-client.d.ts.map +1 -1
  731. package/dist/telemetry/meter-service-client.js +5 -10
  732. package/dist/telemetry/meter-service-client.js.map +1 -1
  733. package/dist/telemetry/metrics.d.ts +123 -0
  734. package/dist/telemetry/metrics.d.ts.map +1 -0
  735. package/dist/telemetry/metrics.js +184 -0
  736. package/dist/telemetry/metrics.js.map +1 -0
  737. package/dist/telemetry/turn-tracker.d.ts +1 -0
  738. package/dist/telemetry/turn-tracker.d.ts.map +1 -1
  739. package/dist/telemetry/turn-tracker.js +22 -1
  740. package/dist/telemetry/turn-tracker.js.map +1 -1
  741. package/dist/telemetry/wide-events.d.ts +31 -1
  742. package/dist/telemetry/wide-events.d.ts.map +1 -1
  743. package/dist/telemetry/wide-events.js +229 -1
  744. package/dist/telemetry/wide-events.js.map +1 -1
  745. package/dist/telemetry.d.ts +39 -3
  746. package/dist/telemetry.d.ts.map +1 -1
  747. package/dist/telemetry.js +160 -3
  748. package/dist/telemetry.js.map +1 -1
  749. package/dist/testing/test-verification-hook.d.ts.map +1 -1
  750. package/dist/testing/test-verification-hook.js +34 -21
  751. package/dist/testing/test-verification-hook.js.map +1 -1
  752. package/dist/tools/apply-patch-parser.d.ts +26 -0
  753. package/dist/tools/apply-patch-parser.d.ts.map +1 -0
  754. package/dist/tools/apply-patch-parser.js +146 -0
  755. package/dist/tools/apply-patch-parser.js.map +1 -0
  756. package/dist/tools/apply-patch.d.ts +42 -0
  757. package/dist/tools/apply-patch.d.ts.map +1 -0
  758. package/dist/tools/apply-patch.js +648 -0
  759. package/dist/tools/apply-patch.js.map +1 -0
  760. package/dist/tools/ask-user.d.ts +1 -0
  761. package/dist/tools/ask-user.d.ts.map +1 -1
  762. package/dist/tools/background/tool-handler.d.ts +1 -0
  763. package/dist/tools/background/tool-handler.d.ts.map +1 -1
  764. package/dist/tools/bash.d.ts +1 -0
  765. package/dist/tools/bash.d.ts.map +1 -1
  766. package/dist/tools/codesearch.d.ts +1 -0
  767. package/dist/tools/codesearch.d.ts.map +1 -1
  768. package/dist/tools/conductor-client.d.ts +1 -0
  769. package/dist/tools/conductor-client.d.ts.map +1 -1
  770. package/dist/tools/conductor-client.js +63 -0
  771. package/dist/tools/conductor-client.js.map +1 -1
  772. package/dist/tools/diff.d.ts +1 -0
  773. package/dist/tools/diff.d.ts.map +1 -1
  774. package/dist/tools/edit.d.ts +1 -0
  775. package/dist/tools/edit.d.ts.map +1 -1
  776. package/dist/tools/extract-document.d.ts +1 -0
  777. package/dist/tools/extract-document.d.ts.map +1 -1
  778. package/dist/tools/find.d.ts +10 -0
  779. package/dist/tools/find.d.ts.map +1 -1
  780. package/dist/tools/find.js +236 -27
  781. package/dist/tools/find.js.map +1 -1
  782. package/dist/tools/gh.d.ts +3 -0
  783. package/dist/tools/gh.d.ts.map +1 -1
  784. package/dist/tools/index.d.ts +50 -0
  785. package/dist/tools/index.d.ts.map +1 -1
  786. package/dist/tools/index.js +4 -0
  787. package/dist/tools/index.js.map +1 -1
  788. package/dist/tools/list.d.ts +1 -0
  789. package/dist/tools/list.d.ts.map +1 -1
  790. package/dist/tools/notebook.d.ts +1 -0
  791. package/dist/tools/notebook.d.ts.map +1 -1
  792. package/dist/tools/oracle.d.ts +1 -0
  793. package/dist/tools/oracle.d.ts.map +1 -1
  794. package/dist/tools/oracle.js +17 -32
  795. package/dist/tools/oracle.js.map +1 -1
  796. package/dist/tools/parallel-execution.d.ts +13 -2
  797. package/dist/tools/parallel-execution.d.ts.map +1 -1
  798. package/dist/tools/parallel-execution.js +178 -7
  799. package/dist/tools/parallel-execution.js.map +1 -1
  800. package/dist/tools/parallel-ripgrep.d.ts +1 -0
  801. package/dist/tools/parallel-ripgrep.d.ts.map +1 -1
  802. package/dist/tools/pipeline.d.ts +4 -0
  803. package/dist/tools/pipeline.d.ts.map +1 -1
  804. package/dist/tools/read.d.ts +1 -0
  805. package/dist/tools/read.d.ts.map +1 -1
  806. package/dist/tools/search.d.ts +1 -0
  807. package/dist/tools/search.d.ts.map +1 -1
  808. package/dist/tools/status.d.ts +1 -0
  809. package/dist/tools/status.d.ts.map +1 -1
  810. package/dist/tools/todo.d.ts +1 -0
  811. package/dist/tools/todo.d.ts.map +1 -1
  812. package/dist/tools/tool-dsl.d.ts +5 -1
  813. package/dist/tools/tool-dsl.d.ts.map +1 -1
  814. package/dist/tools/tool-dsl.js +1 -0
  815. package/dist/tools/tool-dsl.js.map +1 -1
  816. package/dist/tools/tool-result-cache.d.ts.map +1 -1
  817. package/dist/tools/tool-result-cache.js +1 -0
  818. package/dist/tools/tool-result-cache.js.map +1 -1
  819. package/dist/tools/typebox-tool.d.ts.map +1 -1
  820. package/dist/tools/typebox-tool.js +3 -0
  821. package/dist/tools/typebox-tool.js.map +1 -1
  822. package/dist/tools/webfetch.d.ts +1 -0
  823. package/dist/tools/webfetch.d.ts.map +1 -1
  824. package/dist/tools/websearch.d.ts +1 -0
  825. package/dist/tools/websearch.d.ts.map +1 -1
  826. package/dist/tools/write.d.ts +1 -0
  827. package/dist/tools/write.d.ts.map +1 -1
  828. package/dist/utils/abort-error.d.ts +2 -0
  829. package/dist/utils/abort-error.d.ts.map +1 -0
  830. package/dist/utils/abort-error.js +7 -0
  831. package/dist/utils/abort-error.js.map +1 -0
  832. package/dist/utils/downstream.d.ts.map +1 -1
  833. package/dist/utils/downstream.js +4 -0
  834. package/dist/utils/downstream.js.map +1 -1
  835. package/dist/utils/logger.d.ts +3 -0
  836. package/dist/utils/logger.d.ts.map +1 -1
  837. package/dist/utils/logger.js +14 -3
  838. package/dist/utils/logger.js.map +1 -1
  839. package/dist/utils/path-containment.d.ts +2 -0
  840. package/dist/utils/path-containment.d.ts.map +1 -0
  841. package/dist/utils/path-containment.js +14 -0
  842. package/dist/utils/path-containment.js.map +1 -0
  843. package/dist/utils/prompt-safe-text.d.ts +7 -0
  844. package/dist/utils/prompt-safe-text.d.ts.map +1 -0
  845. package/dist/utils/prompt-safe-text.js +44 -0
  846. package/dist/utils/prompt-safe-text.js.map +1 -0
  847. package/dist/version.json +2 -2
  848. package/dist/web-server.d.ts.map +1 -1
  849. package/dist/web-server.js +32 -7
  850. package/dist/web-server.js.map +1 -1
  851. package/dist/workspace/root-resolver.d.ts +4 -1
  852. package/dist/workspace/root-resolver.d.ts.map +1 -1
  853. package/dist/workspace/root-resolver.js +16 -6
  854. package/dist/workspace/root-resolver.js.map +1 -1
  855. package/node_modules/@evalops/contracts/dist/advisor-effort.d.ts +8 -0
  856. package/node_modules/@evalops/contracts/dist/advisor-effort.d.ts.map +1 -0
  857. package/node_modules/@evalops/contracts/dist/advisor-effort.js +35 -0
  858. package/node_modules/@evalops/contracts/dist/advisor-effort.js.map +1 -0
  859. package/node_modules/@evalops/contracts/dist/delegation-prompt.d.ts +10 -0
  860. package/node_modules/@evalops/contracts/dist/delegation-prompt.d.ts.map +1 -0
  861. package/node_modules/@evalops/contracts/dist/delegation-prompt.js +48 -0
  862. package/node_modules/@evalops/contracts/dist/delegation-prompt.js.map +1 -0
  863. package/node_modules/@evalops/contracts/dist/guarded-files-settings.d.ts +20 -0
  864. package/node_modules/@evalops/contracts/dist/guarded-files-settings.d.ts.map +1 -0
  865. package/node_modules/@evalops/contracts/dist/guarded-files-settings.js +147 -0
  866. package/node_modules/@evalops/contracts/dist/guarded-files-settings.js.map +1 -0
  867. package/node_modules/@evalops/contracts/dist/headless-protocol-generated.d.ts +2 -0
  868. package/node_modules/@evalops/contracts/dist/headless-protocol-generated.d.ts.map +1 -1
  869. package/node_modules/@evalops/contracts/dist/headless-protocol-generated.js +1 -0
  870. package/node_modules/@evalops/contracts/dist/headless-protocol-generated.js.map +1 -1
  871. package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts +280 -5
  872. package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts.map +1 -1
  873. package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.js +36 -1
  874. package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.js.map +1 -1
  875. package/node_modules/@evalops/contracts/dist/index.d.ts +15 -1
  876. package/node_modules/@evalops/contracts/dist/index.d.ts.map +1 -1
  877. package/node_modules/@evalops/contracts/dist/index.js +6 -0
  878. package/node_modules/@evalops/contracts/dist/index.js.map +1 -1
  879. package/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts +593 -0
  880. package/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts.map +1 -0
  881. package/node_modules/@evalops/contracts/dist/maestro-app-server.js +218 -0
  882. package/node_modules/@evalops/contracts/dist/maestro-app-server.js.map +1 -0
  883. package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.d.ts +91 -0
  884. package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.d.ts.map +1 -1
  885. package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.js +92 -61
  886. package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.js.map +1 -1
  887. package/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts +3 -0
  888. package/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts.map +1 -1
  889. package/node_modules/@evalops/contracts/dist/runtime-constraints.d.ts +28 -0
  890. package/node_modules/@evalops/contracts/dist/runtime-constraints.d.ts.map +1 -0
  891. package/node_modules/@evalops/contracts/dist/runtime-constraints.js +71 -0
  892. package/node_modules/@evalops/contracts/dist/runtime-constraints.js.map +1 -0
  893. package/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts +7 -0
  894. package/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts.map +1 -1
  895. package/node_modules/@evalops/contracts/dist/runtime-server-request.js +2 -0
  896. package/node_modules/@evalops/contracts/dist/runtime-server-request.js.map +1 -1
  897. package/node_modules/@evalops/contracts/dist/scenario.d.ts +191 -0
  898. package/node_modules/@evalops/contracts/dist/scenario.d.ts.map +1 -0
  899. package/node_modules/@evalops/contracts/dist/scenario.js +4 -0
  900. package/node_modules/@evalops/contracts/dist/scenario.js.map +1 -0
  901. package/node_modules/@evalops/contracts/dist/schemas.d.ts +17 -3
  902. package/node_modules/@evalops/contracts/dist/schemas.d.ts.map +1 -1
  903. package/node_modules/@evalops/contracts/dist/schemas.js +16 -0
  904. package/node_modules/@evalops/contracts/dist/schemas.js.map +1 -1
  905. package/node_modules/@evalops/contracts/package.json +1 -1
  906. package/node_modules/@evalops/tui/package.json +1 -1
  907. package/package.json +41 -7
  908. package/skills/incident-triage/SKILL.md +40 -0
  909. package/skills/incident-triage/mcp.json +14 -0
  910. package/skills/incident-triage/reference/triage.md +20 -0
  911. package/skills/incident-triage/toolbox/incident-timeline +22 -0
  912. package/skills/incident-triage/toolbox/incident-timeline.cmd +16 -0
  913. package/skills/pr-review/SKILL.md +40 -0
  914. package/skills/pr-review/mcp.json +14 -0
  915. package/skills/pr-review/reference/rubric.md +20 -0
  916. package/skills/pr-review/toolbox/review-summary +20 -0
  917. package/skills/pr-review/toolbox/review-summary.cmd +14 -0
  918. package/skills/release-verification/SKILL.md +40 -0
  919. package/skills/release-verification/mcp.json +15 -0
  920. package/skills/release-verification/reference/checklist.md +21 -0
  921. package/skills/release-verification/toolbox/release-readiness +18 -0
  922. package/skills/release-verification/toolbox/release-readiness.cmd +12 -0
@@ -44,6 +44,10 @@
44
44
  *
45
45
  * @module agent/transport
46
46
  */
47
+ import { execFileSync } from "node:child_process";
48
+ import { createHash } from "node:crypto";
49
+ import { readFileSync } from "node:fs";
50
+ import { resolve as resolvePath } from "node:path";
47
51
  import { isContextFirewallBlockingEnabled } from "../config/env-vars.js";
48
52
  import { createToolHookService } from "../hooks/index.js";
49
53
  import { getProviderNetworkConfig } from "../providers/network-config.js";
@@ -58,16 +62,471 @@ import { createSafetyMiddleware, } from "../safety/safety-middleware.js";
58
62
  import { SemanticJudge } from "../safety/semantic-judge.js";
59
63
  import { WorkflowStateError, WorkflowStateTracker, applyWorkflowStateHooks, isWorkflowTrackedTool, } from "../safety/workflow-state.js";
60
64
  import { getSkillArtifactMetadataFromDetails, } from "../skills/artifact-metadata.js";
61
- import { getOptimalConcurrency } from "../tools/parallel-execution.js";
65
+ import { getPathScopedMutation, isParallelSafeTool, isReadOnlyTool, pathScopesOverlap, } from "../tools/parallel-execution.js";
62
66
  import { trackUsage } from "../tracking/cost-tracker.js";
63
67
  import { getTrainingHeaders } from "../training.js";
64
68
  import { getStoredCredentials } from "./keys.js";
65
69
  import { createProviderStream } from "./transport/create-provider-stream.js";
66
- import { getDefaultPlatformToolExecutionBridge, } from "./transport/tool-execution-bridge.js";
70
+ import { stableStringify } from "./transport/stable-stringify.js";
71
+ import { buildObservedResultMetadata, getDefaultPlatformToolExecutionBridge, } from "./transport/tool-execution-bridge.js";
67
72
  import { createToolExecutionPromise } from "./transport/tool-execution.js";
68
73
  import { evaluateToolSafety, } from "./transport/tool-safety-pipeline.js";
69
74
  import { createToolUpdateQueue, waitForNextExecutionOrUpdate, } from "./transport/tool-update-queue.js";
70
75
  import { calculateCost, resolveEnvCredential, } from "./transport/transport-utils.js";
76
+ function hashReusableToolResultSnapshot(value) {
77
+ return createHash("sha256").update(value).digest("hex");
78
+ }
79
+ function readGitSnapshotBuffer(cwd, args) {
80
+ return execFileSync("git", args, {
81
+ cwd,
82
+ stdio: ["ignore", "pipe", "ignore"],
83
+ timeout: 1_000,
84
+ });
85
+ }
86
+ function readGitSnapshotPart(cwd, args) {
87
+ return readGitSnapshotBuffer(cwd, args).toString("utf8").trim();
88
+ }
89
+ function hashGitSnapshotPart(cwd, args) {
90
+ return hashReusableToolResultSnapshot(readGitSnapshotBuffer(cwd, args));
91
+ }
92
+ function hashUntrackedGitFiles(root) {
93
+ const files = readGitSnapshotBuffer(root, [
94
+ "ls-files",
95
+ "--others",
96
+ "--exclude-standard",
97
+ "-z",
98
+ ])
99
+ .toString("utf8")
100
+ .split("\0")
101
+ .filter(Boolean)
102
+ .sort();
103
+ const hash = createHash("sha256");
104
+ for (const file of files) {
105
+ hash.update(file);
106
+ hash.update("\0");
107
+ hash.update(readFileSync(resolvePath(root, file)));
108
+ hash.update("\0");
109
+ }
110
+ return hash.digest("hex");
111
+ }
112
+ function hasDirtyGitSubmodules(root) {
113
+ try {
114
+ return (readGitSnapshotPart(root, [
115
+ "submodule",
116
+ "foreach",
117
+ "--recursive",
118
+ "--quiet",
119
+ "git status --porcelain=v1 --untracked-files=all",
120
+ ]).length > 0);
121
+ }
122
+ catch {
123
+ return true;
124
+ }
125
+ }
126
+ function computeReusableToolResultSnapshot(cwd) {
127
+ try {
128
+ const root = readGitSnapshotPart(cwd, ["rev-parse", "--show-toplevel"]);
129
+ const head = readGitSnapshotPart(cwd, ["rev-parse", "--verify", "HEAD"]);
130
+ const status = readGitSnapshotPart(root, [
131
+ "status",
132
+ "--porcelain=v1",
133
+ "--untracked-files=all",
134
+ ]);
135
+ if (hasDirtyGitSubmodules(root)) {
136
+ return undefined;
137
+ }
138
+ const unstagedDiff = hashGitSnapshotPart(root, [
139
+ "diff",
140
+ "--no-ext-diff",
141
+ "--binary",
142
+ ]);
143
+ const stagedDiff = hashGitSnapshotPart(root, [
144
+ "diff",
145
+ "--cached",
146
+ "--no-ext-diff",
147
+ "--binary",
148
+ ]);
149
+ const untracked = hashUntrackedGitFiles(root);
150
+ return `git:${hashReusableToolResultSnapshot(`${root}\n${head}\n${status}\n${unstagedDiff}\n${stagedDiff}\n${untracked}`)}`;
151
+ }
152
+ catch {
153
+ return undefined;
154
+ }
155
+ }
156
+ const GIT_SNAPSHOT_REUSABLE_TOOL_NAMES = new Set([
157
+ "read",
158
+ "ls",
159
+ "list",
160
+ "glob",
161
+ "find",
162
+ "grep",
163
+ "search",
164
+ "parallel_ripgrep",
165
+ "diff",
166
+ "status",
167
+ ]);
168
+ const REPO_PATH_ARGUMENTS_BY_TOOL = new Map([
169
+ ["read", ["path", "file_path"]],
170
+ ["ls", ["path", "dir", "directory"]],
171
+ ["list", ["path", "dir", "directory"]],
172
+ ["glob", ["path", "cwd", "root", "glob"]],
173
+ ["find", ["path", "cwd", "root", "glob"]],
174
+ ["grep", ["path", "paths", "glob"]],
175
+ ["search", ["path", "paths", "glob"]],
176
+ ["parallel_ripgrep", ["path", "paths", "glob"]],
177
+ ["diff", ["path", "paths", "cwd"]],
178
+ ["status", ["path", "paths", "cwd"]],
179
+ ]);
180
+ const GIT_SCOPED_REUSABLE_TOOL_RESULT_KEY_PREFIX = "git:";
181
+ const RUN_SCOPED_REUSABLE_TOOL_RESULT_KEY_PREFIX = "run:";
182
+ const REQUIRED_REPO_PATH_ARGUMENT_TOOLS = new Set(["read", "ls", "list"]);
183
+ function collectStringValues(value) {
184
+ if (typeof value === "string") {
185
+ return [value];
186
+ }
187
+ if (Array.isArray(value)) {
188
+ return value.flatMap((item) => collectStringValues(item));
189
+ }
190
+ return [];
191
+ }
192
+ function isRepoRelativePathArgument(value) {
193
+ const trimmed = value.trim();
194
+ if (trimmed.length === 0) {
195
+ return false;
196
+ }
197
+ if (trimmed.startsWith("/") ||
198
+ trimmed.startsWith("~") ||
199
+ trimmed.startsWith("\\\\") ||
200
+ /^[A-Za-z]:[\\/]/.test(trimmed)) {
201
+ return false;
202
+ }
203
+ return !trimmed.split(/[\\/]+/).includes("..");
204
+ }
205
+ function isGitIgnoredRepoPath(cwd, repoPath) {
206
+ try {
207
+ readGitSnapshotPart(cwd, ["check-ignore", "--quiet", "--", repoPath]);
208
+ return true;
209
+ }
210
+ catch (error) {
211
+ if (typeof error === "object" &&
212
+ error !== null &&
213
+ "status" in error &&
214
+ error.status === 1) {
215
+ return false;
216
+ }
217
+ return true;
218
+ }
219
+ }
220
+ function isToolCallIncludingIgnoredPaths(toolCall) {
221
+ const toolName = toolCall.name.toLowerCase();
222
+ const args = toolCall.arguments;
223
+ if (!args || typeof args !== "object" || Array.isArray(args)) {
224
+ return false;
225
+ }
226
+ const record = args;
227
+ if (toolName === "status") {
228
+ return record.includeIgnored === true || record.include_ignored === true;
229
+ }
230
+ if (toolName === "search" || toolName === "parallel_ripgrep") {
231
+ return record.useGitIgnore === false || record.use_git_ignore === false;
232
+ }
233
+ return false;
234
+ }
235
+ function hasRepoScopedReusableArguments(toolCall, cwd) {
236
+ const toolName = toolCall.name.toLowerCase();
237
+ if (isToolCallIncludingIgnoredPaths(toolCall)) {
238
+ return false;
239
+ }
240
+ const argumentNames = REPO_PATH_ARGUMENTS_BY_TOOL.get(toolName) ?? [];
241
+ if (argumentNames.length === 0) {
242
+ return true;
243
+ }
244
+ const args = toolCall.arguments;
245
+ if (!args || typeof args !== "object" || Array.isArray(args)) {
246
+ return !REQUIRED_REPO_PATH_ARGUMENT_TOOLS.has(toolName);
247
+ }
248
+ const pathValues = argumentNames.flatMap((name) => collectStringValues(args[name]));
249
+ if (pathValues.length === 0 &&
250
+ REQUIRED_REPO_PATH_ARGUMENT_TOOLS.has(toolName)) {
251
+ return false;
252
+ }
253
+ return pathValues.every((pathValue) => isRepoRelativePathArgument(pathValue) &&
254
+ !isGitIgnoredRepoPath(cwd, pathValue));
255
+ }
256
+ function isGitSnapshotReusableToolCall(tool, toolCall, cwd) {
257
+ if (tool.source !== undefined ||
258
+ tool.annotations?.openWorldHint === true ||
259
+ tool.executionLocation === "client") {
260
+ return false;
261
+ }
262
+ if (!GIT_SNAPSHOT_REUSABLE_TOOL_NAMES.has(tool.name.toLowerCase())) {
263
+ return false;
264
+ }
265
+ if (!isReadOnlyTool(tool.name, tool.annotations, tool.source)) {
266
+ return false;
267
+ }
268
+ return hasRepoScopedReusableArguments(toolCall, cwd);
269
+ }
270
+ const reusableToolDefinitionIdentities = new WeakMap();
271
+ let reusableToolDefinitionIdentityCounter = 0;
272
+ function getReusableToolDefinitionIdentity(value) {
273
+ const existing = reusableToolDefinitionIdentities.get(value);
274
+ if (existing !== undefined) {
275
+ return existing;
276
+ }
277
+ reusableToolDefinitionIdentityCounter += 1;
278
+ reusableToolDefinitionIdentities.set(value, reusableToolDefinitionIdentityCounter);
279
+ return reusableToolDefinitionIdentityCounter;
280
+ }
281
+ function getReusableToolFunctionIdentity(value) {
282
+ return typeof value === "function"
283
+ ? getReusableToolDefinitionIdentity(value)
284
+ : undefined;
285
+ }
286
+ function getReusableToolRegistrySignature(tools) {
287
+ return stableStringify(tools.map((tool) => ({
288
+ allowedCallers: tool.allowedCallers,
289
+ annotations: tool.annotations,
290
+ deferApiDefinition: tool.deferApiDefinition,
291
+ description: tool.description,
292
+ executeIdentity: getReusableToolFunctionIdentity(tool.execute),
293
+ executionLocation: tool.executionLocation,
294
+ getActivityDescriptionIdentity: getReusableToolFunctionIdentity(tool.getActivityDescription),
295
+ getDisplayNameIdentity: getReusableToolFunctionIdentity(tool.getDisplayName),
296
+ getToolUseSummaryIdentity: getReusableToolFunctionIdentity(tool.getToolUseSummary),
297
+ inputExamples: tool.inputExamples,
298
+ label: tool.label,
299
+ maxRetries: tool.maxRetries,
300
+ name: tool.name,
301
+ parameters: tool.parameters,
302
+ retryDelayMs: tool.retryDelayMs,
303
+ shouldRetryIdentity: getReusableToolFunctionIdentity(tool.shouldRetry),
304
+ source: tool.source,
305
+ toolIdentity: getReusableToolDefinitionIdentity(tool),
306
+ toolType: tool.toolType,
307
+ })));
308
+ }
309
+ function createToolMetadataCache(tools, reusableToolResultCwd = process.cwd()) {
310
+ const definitions = new Map(tools.map((tool) => [tool.name, tool]));
311
+ return {
312
+ definitions,
313
+ reusableToolResultCwd,
314
+ lookupCount: 0,
315
+ get(toolName) {
316
+ this.lookupCount += 1;
317
+ return definitions.get(toolName);
318
+ },
319
+ };
320
+ }
321
+ function getToolDefinition(lookup, toolName) {
322
+ if ("get" in lookup && !Array.isArray(lookup)) {
323
+ return lookup.get(toolName);
324
+ }
325
+ return lookup.find((candidate) => candidate.name === toolName);
326
+ }
327
+ function getReusableToolResultCacheKey(toolCall, tools) {
328
+ const tool = getToolDefinition(tools, toolCall.name);
329
+ const cwd = "reusableToolResultCwd" in tools
330
+ ? tools.reusableToolResultCwd
331
+ : process.cwd();
332
+ if (!tool || tool.annotations?.destructiveHint === true) {
333
+ return undefined;
334
+ }
335
+ if (!isReadOnlyTool(tool.name, tool.annotations, tool.source)) {
336
+ return undefined;
337
+ }
338
+ const toolName = tool.name.toLowerCase();
339
+ const cacheKey = `${toolCall.name}:${stableStringify(toolCall.arguments)}`;
340
+ if (isGitSnapshotReusableToolCall(tool, toolCall, cwd)) {
341
+ return `${GIT_SCOPED_REUSABLE_TOOL_RESULT_KEY_PREFIX}${cacheKey}`;
342
+ }
343
+ if (tool.source !== undefined ||
344
+ GIT_SNAPSHOT_REUSABLE_TOOL_NAMES.has(toolName) ||
345
+ tool.annotations?.openWorldHint === true ||
346
+ tool.executionLocation === "client") {
347
+ return undefined;
348
+ }
349
+ return `${RUN_SCOPED_REUSABLE_TOOL_RESULT_KEY_PREFIX}${cacheKey}`;
350
+ }
351
+ function isReadOnlyToolCallForCacheInvalidation(toolCall, tools) {
352
+ const tool = getToolDefinition(tools, toolCall.name);
353
+ return tool
354
+ ? isReadOnlyTool(tool.name, tool.annotations, tool.source)
355
+ : false;
356
+ }
357
+ function cloneToolResultForCache(message) {
358
+ return {
359
+ ...message,
360
+ content: message.content.map((item) => ({ ...item })),
361
+ };
362
+ }
363
+ function cloneToolOutcomeForCall(outcome, toolCall, timestamp) {
364
+ return {
365
+ message: {
366
+ ...outcome.message,
367
+ toolCallId: toolCall.id,
368
+ toolName: toolCall.name,
369
+ content: outcome.message.content.map((item) => ({ ...item })),
370
+ timestamp,
371
+ },
372
+ isError: outcome.isError,
373
+ };
374
+ }
375
+ function resolvePlatformToolExecutionBridge(option) {
376
+ if (option === false) {
377
+ return undefined;
378
+ }
379
+ return option ?? getDefaultPlatformToolExecutionBridge();
380
+ }
381
+ async function recordReusableToolExecutionBridgeOutput({ bridge, plan, outcome, durationMs, signal, }) {
382
+ if (!bridge || !plan) {
383
+ return outcome;
384
+ }
385
+ const observed = plan.kind === "observe"
386
+ ? await bridge.recordObservation(plan, outcome.message, signal)
387
+ : undefined;
388
+ const governedOutput = plan.kind === "governed"
389
+ ? await bridge.recordGovernedOutput(plan, outcome.message, durationMs, signal)
390
+ : undefined;
391
+ return {
392
+ ...outcome,
393
+ ...buildObservedResultMetadata(plan, observed ?? governedOutput),
394
+ };
395
+ }
396
+ function hasReusableToolResultState(cacheKey, cache, pending, policyCheckedKeys, pendingSafetyChecks) {
397
+ return (cache.has(cacheKey) ||
398
+ pending.has(cacheKey) ||
399
+ policyCheckedKeys.has(cacheKey) ||
400
+ (pendingSafetyChecks.get(cacheKey) ?? 0) > 0);
401
+ }
402
+ function incrementPendingReusableToolSafetyCheck(cacheKey, pendingSafetyChecks) {
403
+ if (!cacheKey) {
404
+ return;
405
+ }
406
+ pendingSafetyChecks.set(cacheKey, (pendingSafetyChecks.get(cacheKey) ?? 0) + 1);
407
+ }
408
+ function decrementPendingReusableToolSafetyCheck(cacheKey, pendingSafetyChecks) {
409
+ if (!cacheKey) {
410
+ return;
411
+ }
412
+ const nextCount = (pendingSafetyChecks.get(cacheKey) ?? 0) - 1;
413
+ if (nextCount <= 0) {
414
+ pendingSafetyChecks.delete(cacheKey);
415
+ return;
416
+ }
417
+ pendingSafetyChecks.set(cacheKey, nextCount);
418
+ }
419
+ function clearReusableToolResultState(cache, pending, policyCheckedKeys, pendingSafetyChecks, cacheGeneration) {
420
+ cache.clear();
421
+ pending.clear();
422
+ policyCheckedKeys.clear();
423
+ pendingSafetyChecks.clear();
424
+ cacheGeneration.value += 1;
425
+ }
426
+ function clearRunScopedReusableToolResultState(cache, pending, policyCheckedKeys, pendingSafetyChecks, cacheGeneration) {
427
+ let cleared = false;
428
+ for (const key of cache.keys()) {
429
+ if (key.startsWith(RUN_SCOPED_REUSABLE_TOOL_RESULT_KEY_PREFIX)) {
430
+ cache.delete(key);
431
+ cleared = true;
432
+ }
433
+ }
434
+ for (const key of pending.keys()) {
435
+ if (key.startsWith(RUN_SCOPED_REUSABLE_TOOL_RESULT_KEY_PREFIX)) {
436
+ pending.delete(key);
437
+ cleared = true;
438
+ }
439
+ }
440
+ for (const key of policyCheckedKeys) {
441
+ if (key.startsWith(RUN_SCOPED_REUSABLE_TOOL_RESULT_KEY_PREFIX)) {
442
+ policyCheckedKeys.delete(key);
443
+ cleared = true;
444
+ }
445
+ }
446
+ for (const key of pendingSafetyChecks.keys()) {
447
+ if (key.startsWith(RUN_SCOPED_REUSABLE_TOOL_RESULT_KEY_PREFIX)) {
448
+ pendingSafetyChecks.delete(key);
449
+ cleared = true;
450
+ }
451
+ }
452
+ if (cleared) {
453
+ cacheGeneration.value += 1;
454
+ }
455
+ }
456
+ function invalidateReusableToolResultsAfterMutation(toolCall, tools, cache, pending, policyCheckedKeys, pendingSafetyChecks, cacheGeneration) {
457
+ if (isReadOnlyToolCallForCacheInvalidation(toolCall, tools)) {
458
+ return;
459
+ }
460
+ clearReusableToolResultState(cache, pending, policyCheckedKeys, pendingSafetyChecks, cacheGeneration);
461
+ }
462
+ function hasPendingMutatingToolExecution(pendingExecutions, tools) {
463
+ return pendingExecutions.some((execution) => !isReadOnlyToolCallForCacheInvalidation(execution.toolCall, tools));
464
+ }
465
+ function trackReusableToolResult(cacheKey, executionPromise, cache, pending, policyCheckedKeys, cacheGeneration) {
466
+ const trackedGeneration = cacheGeneration?.value;
467
+ const trackedPromise = executionPromise
468
+ .then((outcome) => {
469
+ if (!outcome.isError &&
470
+ outcome.message.isError !== true &&
471
+ (cacheGeneration === undefined ||
472
+ cacheGeneration.value === trackedGeneration)) {
473
+ cache.set(cacheKey, {
474
+ message: cloneToolResultForCache(outcome.message),
475
+ });
476
+ }
477
+ else {
478
+ policyCheckedKeys?.delete(cacheKey);
479
+ }
480
+ return outcome;
481
+ })
482
+ .catch((error) => {
483
+ policyCheckedKeys?.delete(cacheKey);
484
+ throw error;
485
+ })
486
+ .finally(() => {
487
+ if (pending.get(cacheKey) === trackedPromise) {
488
+ pending.delete(cacheKey);
489
+ }
490
+ });
491
+ pending.set(cacheKey, trackedPromise);
492
+ return trackedPromise;
493
+ }
494
+ class AgentEventQueue {
495
+ constructor() {
496
+ this.events = [];
497
+ }
498
+ push(event) {
499
+ this.events.push(event);
500
+ if (this.wake) {
501
+ const wake = this.wake;
502
+ this.pending = undefined;
503
+ this.wake = undefined;
504
+ wake();
505
+ }
506
+ }
507
+ shift() {
508
+ return this.events.shift();
509
+ }
510
+ wait() {
511
+ if (this.events.length > 0) {
512
+ return Promise.resolve();
513
+ }
514
+ if (!this.pending) {
515
+ this.pending = new Promise((resolve) => {
516
+ this.wake = resolve;
517
+ });
518
+ }
519
+ return this.pending;
520
+ }
521
+ clearPendingWaiter() {
522
+ this.pending = undefined;
523
+ this.wake = undefined;
524
+ }
525
+ }
526
+ function isDynamicToolApprovalEvent(event) {
527
+ return (event.type === "action_approval_required" ||
528
+ event.type === "action_approval_resolved");
529
+ }
71
530
  function getGovernedToolResultEventMetadata(details) {
72
531
  if (!details || typeof details !== "object") {
73
532
  return {};
@@ -152,6 +611,11 @@ export class ProviderTransport {
152
611
  this.toolCallsThisMinute = 0;
153
612
  /** Last minute window start time */
154
613
  this.minuteWindowStart = 0;
614
+ this.reusableToolResults = new Map();
615
+ this.pendingReusableToolResults = new Map();
616
+ this.policyCheckedReusableToolResultKeys = new Set();
617
+ this.pendingReusableToolSafetyChecks = new Map();
618
+ this.reusableToolResultCacheGeneration = { value: 0 };
155
619
  this.clock = options.clock ?? systemClock;
156
620
  this.sessionTokenCounter = options.sessionTokenCounter;
157
621
  this.auditLogger = options.auditLogger;
@@ -187,6 +651,23 @@ export class ProviderTransport {
187
651
  },
188
652
  });
189
653
  }
654
+ refreshReusableToolResultState(tools, cwd) {
655
+ const registrySignature = getReusableToolRegistrySignature(tools);
656
+ const snapshot = computeReusableToolResultSnapshot(cwd);
657
+ if (snapshot === undefined) {
658
+ clearReusableToolResultState(this.reusableToolResults, this.pendingReusableToolResults, this.policyCheckedReusableToolResultKeys, this.pendingReusableToolSafetyChecks, this.reusableToolResultCacheGeneration);
659
+ this.reusableToolResultSnapshot = undefined;
660
+ this.reusableToolRegistrySignature = registrySignature;
661
+ return;
662
+ }
663
+ if (this.reusableToolResultSnapshot !== snapshot ||
664
+ (this.reusableToolRegistrySignature !== undefined &&
665
+ this.reusableToolRegistrySignature !== registrySignature)) {
666
+ clearReusableToolResultState(this.reusableToolResults, this.pendingReusableToolResults, this.policyCheckedReusableToolResultKeys, this.pendingReusableToolSafetyChecks, this.reusableToolResultCacheGeneration);
667
+ }
668
+ this.reusableToolResultSnapshot = snapshot;
669
+ this.reusableToolRegistrySignature = registrySignature;
670
+ }
190
671
  /**
191
672
  * Continue from current context without a new user message.
192
673
  *
@@ -233,8 +714,12 @@ export class ProviderTransport {
233
714
  })
234
715
  : undefined);
235
716
  this.workflowState.reset();
717
+ const scriptedReplayRun = model.provider === "scripted-replay";
718
+ const codexAppServerRun = model.api === "openai-codex-app-server";
236
719
  let credential;
237
- if (this.options.getAuthContext) {
720
+ if (this.options.getAuthContext &&
721
+ !scriptedReplayRun &&
722
+ !codexAppServerRun) {
238
723
  credential = await this.options.getAuthContext(model.provider);
239
724
  }
240
725
  if (!credential && this.options.getApiKey) {
@@ -248,6 +733,22 @@ export class ProviderTransport {
248
733
  };
249
734
  }
250
735
  }
736
+ if (!credential && scriptedReplayRun) {
737
+ credential = {
738
+ provider: model.provider,
739
+ token: "scripted-replay",
740
+ type: "api-key",
741
+ source: "env",
742
+ };
743
+ }
744
+ if (!credential && codexAppServerRun) {
745
+ credential = {
746
+ provider: model.provider,
747
+ token: "codex-app-server",
748
+ type: "api-key",
749
+ source: "env",
750
+ };
751
+ }
251
752
  if (!credential) {
252
753
  const envCredential = resolveEnvCredential(model.provider);
253
754
  if (envCredential) {
@@ -284,6 +785,18 @@ export class ProviderTransport {
284
785
  baseUrl: `${this.options.corsProxyUrl}/?url=${encodeURIComponent(model.baseUrl)}`,
285
786
  };
286
787
  }
788
+ const dynamicToolEventQueue = new AgentEventQueue();
789
+ const reusableToolResultCwd = this.options.cwd ?? process.cwd();
790
+ const toolMetadataCache = createToolMetadataCache(tools, reusableToolResultCwd);
791
+ this.refreshReusableToolResultState(tools, reusableToolResultCwd);
792
+ const reusableToolResults = this.reusableToolResults;
793
+ const pendingReusableToolResults = this.pendingReusableToolResults;
794
+ const policyCheckedReusableToolResultKeys = this.policyCheckedReusableToolResultKeys;
795
+ const pendingReusableToolSafetyChecks = this.pendingReusableToolSafetyChecks;
796
+ const reusableToolResultCacheGeneration = this.reusableToolResultCacheGeneration;
797
+ clearRunScopedReusableToolResultState(reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, pendingReusableToolSafetyChecks, reusableToolResultCacheGeneration);
798
+ const pendingDynamicToolExecutions = [];
799
+ const platformToolExecutionBridge = resolvePlatformToolExecutionBridge(this.options.platformToolExecutionBridge);
287
800
  const trainingHeaders = getTrainingHeaders();
288
801
  const headers = trainingHeaders || model.headers || credential?.headers
289
802
  ? {
@@ -292,6 +805,269 @@ export class ProviderTransport {
292
805
  ...(credential?.headers ?? {}),
293
806
  }
294
807
  : undefined;
808
+ const executeDynamicTool = async (toolCall) => {
809
+ const capturedResults = [];
810
+ const dynamicToolError = (message) => ({
811
+ content: [{ type: "text", text: message }],
812
+ isError: true,
813
+ });
814
+ const toAgentToolResult = (outcome) => {
815
+ if (!outcome) {
816
+ return dynamicToolError("Dynamic tool execution was blocked");
817
+ }
818
+ const message = "message" in outcome ? outcome.message : outcome;
819
+ return {
820
+ content: message.content,
821
+ isError: "message" in outcome ? outcome.isError : message.isError,
822
+ details: message.details,
823
+ ...("message" in outcome && outcome.toolExecutionId
824
+ ? { toolExecutionId: outcome.toolExecutionId }
825
+ : {}),
826
+ ...("message" in outcome && outcome.approvalRequestId
827
+ ? { approvalRequestId: outcome.approvalRequestId }
828
+ : {}),
829
+ };
830
+ };
831
+ const emitDynamicToolResult = (message, effectiveToolCall, isError, metadata) => {
832
+ try {
833
+ applyWorkflowStateHooks({
834
+ toolCall: effectiveToolCall,
835
+ result: message,
836
+ tracker: this.workflowState,
837
+ isError,
838
+ });
839
+ capturedResults.push({
840
+ message,
841
+ isError,
842
+ ...metadata,
843
+ });
844
+ }
845
+ catch (error) {
846
+ if (error instanceof WorkflowStateError) {
847
+ capturedResults.push({
848
+ message: {
849
+ role: "toolResult",
850
+ toolCallId: effectiveToolCall.id,
851
+ toolName: effectiveToolCall.name,
852
+ content: [{ type: "text", text: error.message }],
853
+ isError: true,
854
+ timestamp: this.clock.now(),
855
+ },
856
+ isError: true,
857
+ ...metadata,
858
+ });
859
+ }
860
+ else {
861
+ throw error;
862
+ }
863
+ }
864
+ return [];
865
+ };
866
+ try {
867
+ const reusableToolResultKey = getReusableToolResultCacheKey(toolCall, toolMetadataCache);
868
+ const alreadyHadReusableToolResultState = reusableToolResultKey !== undefined &&
869
+ hasReusableToolResultState(reusableToolResultKey, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, pendingReusableToolSafetyChecks);
870
+ incrementPendingReusableToolSafetyCheck(reusableToolResultKey, pendingReusableToolSafetyChecks);
871
+ const shouldSkipLoopDetection = (candidateToolCall) => {
872
+ const candidateKey = getReusableToolResultCacheKey(candidateToolCall, toolMetadataCache);
873
+ return (candidateKey !== undefined &&
874
+ candidateKey === reusableToolResultKey &&
875
+ alreadyHadReusableToolResultState &&
876
+ !hasPendingMutatingToolExecution(pendingDynamicToolExecutions, toolMetadataCache) &&
877
+ hasReusableToolResultState(candidateKey, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, pendingReusableToolSafetyChecks));
878
+ };
879
+ let safetyVerdict;
880
+ let rateLimitUpdate;
881
+ try {
882
+ const safetyIterator = evaluateToolSafety({
883
+ toolCall,
884
+ tools,
885
+ userMessage,
886
+ cfg,
887
+ signal,
888
+ clock: this.clock,
889
+ safetyMiddleware: this.safetyMiddleware,
890
+ workflowState: this.workflowState,
891
+ adaptiveThresholds: this.adaptiveThresholds,
892
+ auditLogger: this.auditLogger,
893
+ approvalService: this.options.approvalService,
894
+ toolExecutionBridge: platformToolExecutionBridge,
895
+ hookService,
896
+ firewall,
897
+ rateLimitState: {
898
+ recentToolTimestamps: this.recentToolTimestamps,
899
+ toolCallsThisMinute: this.toolCallsThisMinute,
900
+ minuteWindowStart: this.minuteWindowStart,
901
+ rateWindowMs: ProviderTransport.TOOL_RATE_WINDOW_MS,
902
+ rateLimit: ProviderTransport.TOOL_RATE_LIMIT,
903
+ },
904
+ shouldSkipLoopDetection,
905
+ emitToolResult: emitDynamicToolResult,
906
+ });
907
+ while (true) {
908
+ const safetyStep = await safetyIterator.next();
909
+ if (safetyStep.done) {
910
+ ({ verdict: safetyVerdict, rateLimitUpdate } = safetyStep.value);
911
+ break;
912
+ }
913
+ if (isDynamicToolApprovalEvent(safetyStep.value)) {
914
+ dynamicToolEventQueue.push(safetyStep.value);
915
+ }
916
+ }
917
+ }
918
+ finally {
919
+ decrementPendingReusableToolSafetyCheck(reusableToolResultKey, pendingReusableToolSafetyChecks);
920
+ }
921
+ if (!safetyVerdict || !rateLimitUpdate) {
922
+ return dynamicToolError("Safety pipeline did not return a verdict.");
923
+ }
924
+ this.toolCallsThisMinute = rateLimitUpdate.toolCallsThisMinute;
925
+ this.minuteWindowStart = rateLimitUpdate.minuteWindowStart;
926
+ if (safetyVerdict.outcome === "blocked") {
927
+ return toAgentToolResult(capturedResults.at(-1));
928
+ }
929
+ const { effectiveToolCall, validatedArgs, toolDef: tool, sanitizedExecutionArgs, } = safetyVerdict;
930
+ if (tool.executionLocation === "client") {
931
+ return dynamicToolError(`Client-side tool execution is not available for Codex app-server dynamic tool "${tool.name}".`);
932
+ }
933
+ const policyCheckedReusableToolResultKey = getReusableToolResultCacheKey(effectiveToolCall, toolMetadataCache);
934
+ const canReuseToolResult = reusableToolResultKey !== undefined &&
935
+ policyCheckedReusableToolResultKey === reusableToolResultKey;
936
+ if (canReuseToolResult && reusableToolResultKey) {
937
+ policyCheckedReusableToolResultKeys.add(reusableToolResultKey);
938
+ }
939
+ const canServeReusableToolResult = canReuseToolResult &&
940
+ !hasPendingMutatingToolExecution(pendingDynamicToolExecutions, toolMetadataCache);
941
+ if (canServeReusableToolResult) {
942
+ const cachedEntry = reusableToolResults.get(reusableToolResultKey);
943
+ if (cachedEntry) {
944
+ const cacheHitStart = this.clock.now();
945
+ const cachedOutcome = await recordReusableToolExecutionBridgeOutput({
946
+ bridge: platformToolExecutionBridge,
947
+ plan: safetyVerdict.toolExecutionBridgePlan,
948
+ outcome: {
949
+ message: {
950
+ ...cachedEntry.message,
951
+ toolCallId: toolCall.id,
952
+ toolName: toolCall.name,
953
+ content: cachedEntry.message.content.map((item) => ({
954
+ ...item,
955
+ })),
956
+ timestamp: this.clock.now(),
957
+ },
958
+ isError: false,
959
+ },
960
+ durationMs: this.clock.now() - cacheHitStart,
961
+ signal,
962
+ });
963
+ emitDynamicToolResult(cachedOutcome.message, effectiveToolCall, cachedOutcome.isError, {
964
+ toolExecutionId: cachedOutcome.toolExecutionId,
965
+ approvalRequestId: cachedOutcome.approvalRequestId,
966
+ });
967
+ return toAgentToolResult(capturedResults.at(-1) ?? cachedOutcome);
968
+ }
969
+ const pendingReusable = pendingReusableToolResults.get(reusableToolResultKey);
970
+ if (pendingReusable) {
971
+ const cacheHitStart = this.clock.now();
972
+ const cachedOutcome = await recordReusableToolExecutionBridgeOutput({
973
+ bridge: platformToolExecutionBridge,
974
+ plan: safetyVerdict.toolExecutionBridgePlan,
975
+ outcome: cloneToolOutcomeForCall(await pendingReusable, toolCall, this.clock.now()),
976
+ durationMs: this.clock.now() - cacheHitStart,
977
+ signal,
978
+ });
979
+ emitDynamicToolResult(cachedOutcome.message, effectiveToolCall, cachedOutcome.isError, {
980
+ toolExecutionId: cachedOutcome.toolExecutionId,
981
+ approvalRequestId: cachedOutcome.approvalRequestId,
982
+ });
983
+ return toAgentToolResult(capturedResults.at(-1) ?? cachedOutcome);
984
+ }
985
+ }
986
+ const toolUpdateQueue = createToolUpdateQueue();
987
+ const executionPromise = createToolExecutionPromise({
988
+ toolCall,
989
+ effectiveToolCall,
990
+ tool,
991
+ validatedArgs,
992
+ sanitizedExecutionArgs,
993
+ cfg,
994
+ signal,
995
+ clock: this.clock,
996
+ safetyMiddleware: this.safetyMiddleware,
997
+ adaptiveThresholds: this.adaptiveThresholds,
998
+ auditLogger: this.auditLogger,
999
+ hookService,
1000
+ toolRetryService: this.options.toolRetryService,
1001
+ toolRetryConfig: this.options.toolRetryConfig,
1002
+ clientToolService: this.options.clientToolService,
1003
+ toolExecutionBridge: platformToolExecutionBridge,
1004
+ toolExecutionBridgePlan: safetyVerdict.toolExecutionBridgePlan,
1005
+ toolUpdateQueue,
1006
+ });
1007
+ const trackedExecutionPromise = canReuseToolResult && reusableToolResultKey
1008
+ ? trackReusableToolResult(reusableToolResultKey, executionPromise, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, reusableToolResultCacheGeneration)
1009
+ : executionPromise;
1010
+ const pendingExecution = {
1011
+ toolCall: effectiveToolCall,
1012
+ promise: trackedExecutionPromise,
1013
+ };
1014
+ pendingDynamicToolExecutions.push(pendingExecution);
1015
+ const pendingExecutions = [pendingExecution];
1016
+ let outcome;
1017
+ try {
1018
+ while (pendingExecutions.length > 0) {
1019
+ const next = await waitForNextExecutionOrUpdate(pendingExecutions, toolUpdateQueue);
1020
+ if (next.kind === "update") {
1021
+ if (next.event.type === "tool_retry_required") {
1022
+ this.options.toolRetryService?.skip(next.event.request.id, "Codex app-server dynamic tool callbacks cannot prompt for retry", "runtime");
1023
+ }
1024
+ continue;
1025
+ }
1026
+ outcome = next.outcome;
1027
+ }
1028
+ }
1029
+ finally {
1030
+ const pendingIndex = pendingDynamicToolExecutions.indexOf(pendingExecution);
1031
+ if (pendingIndex >= 0) {
1032
+ pendingDynamicToolExecutions.splice(pendingIndex, 1);
1033
+ }
1034
+ }
1035
+ if (!outcome) {
1036
+ return dynamicToolError("Dynamic tool execution did not complete.");
1037
+ }
1038
+ invalidateReusableToolResultsAfterMutation(effectiveToolCall, toolMetadataCache, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, pendingReusableToolSafetyChecks, reusableToolResultCacheGeneration);
1039
+ try {
1040
+ applyWorkflowStateHooks({
1041
+ toolCall: effectiveToolCall,
1042
+ result: outcome.message,
1043
+ tracker: this.workflowState,
1044
+ isError: outcome.isError,
1045
+ });
1046
+ }
1047
+ catch (error) {
1048
+ if (error instanceof WorkflowStateError) {
1049
+ return toAgentToolResult({
1050
+ message: {
1051
+ role: "toolResult",
1052
+ toolCallId: effectiveToolCall.id,
1053
+ toolName: effectiveToolCall.name,
1054
+ content: [{ type: "text", text: error.message }],
1055
+ isError: true,
1056
+ timestamp: this.clock.now(),
1057
+ },
1058
+ isError: true,
1059
+ toolExecutionId: outcome.toolExecutionId,
1060
+ approvalRequestId: outcome.approvalRequestId,
1061
+ });
1062
+ }
1063
+ throw error;
1064
+ }
1065
+ return toAgentToolResult(outcome);
1066
+ }
1067
+ finally {
1068
+ this.safetyMiddleware.clearCredentials();
1069
+ }
1070
+ };
295
1071
  const streamOptions = {
296
1072
  apiKey,
297
1073
  maxTokens: model.maxTokens,
@@ -300,7 +1076,9 @@ export class ProviderTransport {
300
1076
  headers,
301
1077
  requestBody: credential?.requestBody,
302
1078
  sessionId: cfg.session?.id,
1079
+ cwd: this.options.cwd,
303
1080
  taskBudget: cfg.taskBudget,
1081
+ executeDynamicTool,
304
1082
  };
305
1083
  let hasMoreToolCalls = true;
306
1084
  const allMessages = [...context.messages];
@@ -355,7 +1133,8 @@ export class ProviderTransport {
355
1133
  let currentAssistantMessage = null;
356
1134
  let completedAssistantMessage = null;
357
1135
  const toolCallsToExecute = [];
358
- let toolResults = [];
1136
+ const toolResults = [];
1137
+ const pendingProviderToolResultMessages = [];
359
1138
  let steeringAfterTools = null;
360
1139
  let pendingNextTurn = false;
361
1140
  let encounteredError = false;
@@ -382,6 +1161,8 @@ export class ProviderTransport {
382
1161
  // Reset state for retry
383
1162
  currentAssistantMessage = null;
384
1163
  toolCallsToExecute.length = 0;
1164
+ toolResults.length = 0;
1165
+ pendingProviderToolResultMessages.length = 0;
385
1166
  pendingNextTurn = false;
386
1167
  const backoffMs = Math.min(networkConfig.backoffInitial * 2 ** (streamAttempt - 1), networkConfig.backoffMax);
387
1168
  logger.info("Retrying stream after idle timeout", {
@@ -397,8 +1178,34 @@ export class ProviderTransport {
397
1178
  attempt: streamAttempt,
398
1179
  });
399
1180
  const stream = createProviderStream(model, currentContext, streamOptions, { reasoning: cfg.reasoning, reasoningSummary: cfg.reasoningSummary });
1181
+ const streamIterator = stream[Symbol.asyncIterator]();
1182
+ let nextStreamEvent = streamIterator.next();
400
1183
  try {
401
- for await (const event of stream) {
1184
+ while (true) {
1185
+ const queuedDynamicToolEvent = dynamicToolEventQueue.shift();
1186
+ if (queuedDynamicToolEvent) {
1187
+ yield queuedDynamicToolEvent;
1188
+ continue;
1189
+ }
1190
+ const dynamicToolEventReady = dynamicToolEventQueue.wait();
1191
+ const nextEvent = await Promise.race([
1192
+ dynamicToolEventReady.then(() => ({
1193
+ type: "dynamicTool",
1194
+ })),
1195
+ nextStreamEvent.then((result) => ({
1196
+ type: "provider",
1197
+ result,
1198
+ })),
1199
+ ]);
1200
+ if (nextEvent.type === "dynamicTool") {
1201
+ continue;
1202
+ }
1203
+ dynamicToolEventQueue.clearPendingWaiter();
1204
+ if (nextEvent.result.done) {
1205
+ break;
1206
+ }
1207
+ const event = nextEvent.result.value;
1208
+ nextStreamEvent = streamIterator.next();
402
1209
  if (event.type === "start") {
403
1210
  currentAssistantMessage = event.partial;
404
1211
  if (currentAssistantMessage) {
@@ -425,6 +1232,51 @@ export class ProviderTransport {
425
1232
  }
426
1233
  continue;
427
1234
  }
1235
+ if (event.type === "provider_tool_execution_start") {
1236
+ if (!firstModelOutputSeen) {
1237
+ cfg.queryProfiler?.checkpoint("model:first-token");
1238
+ firstModelOutputSeen = true;
1239
+ }
1240
+ yield {
1241
+ type: "tool_execution_start",
1242
+ toolCallId: event.toolCallId,
1243
+ toolExecutionId: event.toolExecutionId,
1244
+ toolName: event.toolName,
1245
+ displayName: event.displayName,
1246
+ summaryLabel: event.summaryLabel,
1247
+ args: event.args,
1248
+ };
1249
+ continue;
1250
+ }
1251
+ if (event.type === "provider_tool_execution_update") {
1252
+ yield {
1253
+ type: "tool_execution_update",
1254
+ toolCallId: event.toolCallId,
1255
+ toolExecutionId: event.toolExecutionId,
1256
+ toolName: event.toolName,
1257
+ displayName: event.displayName,
1258
+ summaryLabel: event.summaryLabel,
1259
+ args: event.args,
1260
+ partialResult: event.partialResult,
1261
+ };
1262
+ continue;
1263
+ }
1264
+ if (event.type === "provider_tool_execution_end") {
1265
+ toolResults.push(event.result);
1266
+ pendingProviderToolResultMessages.push(event.result);
1267
+ yield {
1268
+ type: "tool_execution_end",
1269
+ toolCallId: event.toolCallId,
1270
+ toolExecutionId: event.toolExecutionId,
1271
+ approvalRequestId: event.approvalRequestId,
1272
+ toolName: event.toolName,
1273
+ displayName: event.displayName,
1274
+ summaryLabel: event.summaryLabel,
1275
+ result: event.result,
1276
+ isError: event.isError,
1277
+ };
1278
+ continue;
1279
+ }
428
1280
  if (event.type === "toolcall_end") {
429
1281
  if (!firstModelOutputSeen) {
430
1282
  cfg.queryProfiler?.checkpoint("model:first-token");
@@ -477,6 +1329,11 @@ export class ProviderTransport {
477
1329
  }
478
1330
  }
479
1331
  }
1332
+ for (const message of pendingProviderToolResultMessages) {
1333
+ yield { type: "message_start", message };
1334
+ yield { type: "message_end", message };
1335
+ }
1336
+ pendingProviderToolResultMessages.length = 0;
480
1337
  pendingNextTurn = toolCallsToExecute.length > 0;
481
1338
  continue;
482
1339
  }
@@ -490,9 +1347,17 @@ export class ProviderTransport {
490
1347
  break;
491
1348
  }
492
1349
  }
1350
+ for (let event = dynamicToolEventQueue.shift(); event; event = dynamicToolEventQueue.shift()) {
1351
+ yield event;
1352
+ }
1353
+ dynamicToolEventQueue.clearPendingWaiter();
493
1354
  streamSuccess = true;
494
1355
  }
495
1356
  catch (error) {
1357
+ while (dynamicToolEventQueue.shift()) {
1358
+ // Drop queued dynamic tool events from the abandoned stream attempt.
1359
+ }
1360
+ dynamicToolEventQueue.clearPendingWaiter();
496
1361
  if (isStreamIdleTimeoutError(error) &&
497
1362
  streamAttempt <= maxStreamRetries) {
498
1363
  logger.warn("Stream idle timeout, will retry", {
@@ -508,7 +1373,6 @@ export class ProviderTransport {
508
1373
  }
509
1374
  } // end while retry loop
510
1375
  if (toolCallsToExecute.length > 0) {
511
- toolResults = [];
512
1376
  const toolUpdateQueue = createToolUpdateQueue();
513
1377
  const pendingExecutions = [];
514
1378
  const rawConcurrency = this.options.maxConcurrentToolExecutions ?? 2;
@@ -517,12 +1381,285 @@ export class ProviderTransport {
517
1381
  : 2;
518
1382
  const hasWorkflowTrackedTool = toolCallsToExecute.some((call) => isWorkflowTrackedTool(call.name));
519
1383
  const requiresSerializedTurn = hasWorkflowTrackedTool && toolCallsToExecute.length > 1;
520
- // Calculate optimal concurrency - higher for read-only batches
521
- let concurrencyLimit = getOptimalConcurrency(toolCallsToExecute, tools, {
522
- baseConcurrency: configuredConcurrency,
523
- maxReadOnlyConcurrency: 8, // Allow up to 8x parallel for read-only
524
- enabled: true,
1384
+ const toolDefinitionsByName = toolMetadataCache.definitions;
1385
+ const isReadOnlyToolCall = (toolCall) => {
1386
+ const toolDef = toolDefinitionsByName.get(toolCall.name);
1387
+ return toolDef
1388
+ ? isReadOnlyTool(toolDef.name, toolDef.annotations, toolDef.source)
1389
+ : false;
1390
+ };
1391
+ const isParallelSafeToolCall = (toolCall, toolDef = toolDefinitionsByName.get(toolCall.name)) => toolDef
1392
+ ? isParallelSafeTool(toolDef.name, toolDef.annotations, toolDef.source)
1393
+ : false;
1394
+ const readOnlyToolCalls = toolCallsToExecute.filter(isReadOnlyToolCall);
1395
+ const readOnlyConcurrencyLimit = readOnlyToolCalls.length > 0
1396
+ ? Math.min(8, Math.max(configuredConcurrency, readOnlyToolCalls.length))
1397
+ : configuredConcurrency;
1398
+ const parallelSafeMutationConcurrencyLimit = Math.min(8, configuredConcurrency);
1399
+ const concurrencyLimitForTool = (defaultLimit, toolDef) => {
1400
+ const sourceMaxConcurrency = toolDef?.source?.type === "mcp"
1401
+ ? toolDef.source.parallelMaxConcurrency
1402
+ : undefined;
1403
+ return Math.min(defaultLimit, typeof sourceMaxConcurrency === "number" &&
1404
+ Number.isFinite(sourceMaxConcurrency) &&
1405
+ sourceMaxConcurrency > 0
1406
+ ? Math.floor(sourceMaxConcurrency)
1407
+ : defaultLimit);
1408
+ };
1409
+ const readOnlyConcurrencyLimitForTool = (toolDef) => concurrencyLimitForTool(readOnlyConcurrencyLimit, toolDef);
1410
+ const parallelSafeMutationConcurrencyLimitForTool = (toolDef) => concurrencyLimitForTool(parallelSafeMutationConcurrencyLimit, toolDef);
1411
+ let concurrencyLimit = configuredConcurrency;
1412
+ const pendingMutationScopes = new Map();
1413
+ const pendingExecutionWaveIndexes = new Map();
1414
+ const pendingExecutionScheduling = new Map();
1415
+ const toolSchedulingDecisions = new Map();
1416
+ const toolPhaseStartMs = this.clock.now();
1417
+ let currentWaveIndex = 0;
1418
+ const mutationPathBase = this.options.cwd ?? process.cwd();
1419
+ const toolSchedulingMetadata = new Map();
1420
+ const nextWaveIndex = () => {
1421
+ currentWaveIndex += 1;
1422
+ return currentWaveIndex;
1423
+ };
1424
+ const pendingWaveIndex = () => pendingExecutions.length > 0
1425
+ ? (pendingExecutionWaveIndexes.get(pendingExecutions[0]) ??
1426
+ currentWaveIndex)
1427
+ : nextWaveIndex();
1428
+ const schedulerWaitMs = () => Math.max(0, this.clock.now() - toolPhaseStartMs);
1429
+ const isMcpParallelOptIn = (toolDef) => toolDef.source?.type === "mcp" &&
1430
+ toolDef.source.supportsParallelToolCalls === true &&
1431
+ toolDef.annotations?.destructiveHint !== true;
1432
+ const buildToolPhaseSummary = () => {
1433
+ const rawDecisions = [...toolSchedulingDecisions.values()].sort((left, right) => left.emittedIndex - right.emittedIndex);
1434
+ if (rawDecisions.length === 0) {
1435
+ return undefined;
1436
+ }
1437
+ const waveCounts = new Map();
1438
+ for (const decision of rawDecisions) {
1439
+ if (decision.waveIndex !== undefined) {
1440
+ waveCounts.set(decision.waveIndex, (waveCounts.get(decision.waveIndex) ?? 0) + 1);
1441
+ }
1442
+ }
1443
+ const decisions = rawDecisions.map((decision) => {
1444
+ const isSingleModelToolCall = rawDecisions.length === 1;
1445
+ const waveSize = decision.waveIndex !== undefined
1446
+ ? (waveCounts.get(decision.waveIndex) ?? 1)
1447
+ : 1;
1448
+ const outcome = decision.cacheHit === true
1449
+ ? "cached"
1450
+ : decision.decision === "skipped"
1451
+ ? "skipped"
1452
+ : decision.decision === "delayed" ||
1453
+ decision.blockedByMutation === true
1454
+ ? "delayed"
1455
+ : decision.decision === "parallelized" ||
1456
+ (waveSize > 1 && decision.decision === "scheduled")
1457
+ ? "parallelized"
1458
+ : "serialized";
1459
+ const reason = outcome === "cached"
1460
+ ? "cache_hit"
1461
+ : decision.blockedByMutation === true
1462
+ ? decision.reason
1463
+ : decision.reason === "workflow_state_serialized"
1464
+ ? "workflow_state_serialized"
1465
+ : decision.mcpOptIn === true
1466
+ ? "mcp_parallel_opt_in"
1467
+ : decision.reason.startsWith("read_only")
1468
+ ? outcome === "parallelized"
1469
+ ? "read_only_parallel_safe"
1470
+ : isSingleModelToolCall
1471
+ ? "single_read_only_call"
1472
+ : decision.reason
1473
+ : decision.reason.startsWith("path_scoped_mutation")
1474
+ ? "path_scoped_mutation"
1475
+ : decision.reason;
1476
+ return {
1477
+ toolCallId: decision.callId,
1478
+ toolName: decision.toolName,
1479
+ emittedIndex: decision.emittedIndex,
1480
+ outcome,
1481
+ decision: outcome,
1482
+ reason,
1483
+ waveIndex: decision.waveIndex !== undefined
1484
+ ? Math.max(0, decision.waveIndex - 1)
1485
+ : undefined,
1486
+ waitMs: Math.max(0, Math.round(decision.schedulerWaitMs ?? 0)),
1487
+ schedulerWaitMs: Math.max(0, Math.round(decision.schedulerWaitMs ?? 0)),
1488
+ mcpOptIn: decision.mcpOptIn,
1489
+ cacheHit: decision.cacheHit,
1490
+ blockedByMutation: decision.blockedByMutation,
1491
+ };
1492
+ });
1493
+ const parallelizedCallCount = decisions.filter((decision) => decision.outcome === "parallelized").length;
1494
+ const delayedCallCount = decisions.filter((decision) => decision.outcome === "delayed").length;
1495
+ const batchShapingFeedback = decisions.length === 1 &&
1496
+ decisions[0]?.reason === "single_read_only_call"
1497
+ ? {
1498
+ avoidableSingleton: true,
1499
+ reason: "single_read_only_call",
1500
+ hint: "When you need several independent reads or searches, emit them together in one assistant message so Maestro can batch them safely.",
1501
+ }
1502
+ : undefined;
1503
+ const serializationReasons = Object.fromEntries([...decisions]
1504
+ .filter((decision) => decision.outcome === "serialized" ||
1505
+ decision.outcome === "delayed")
1506
+ .reduce((counts, decision) => {
1507
+ counts.set(decision.reason, (counts.get(decision.reason) ?? 0) + 1);
1508
+ return counts;
1509
+ }, new Map()));
1510
+ return {
1511
+ type: "tool_phase_summary",
1512
+ modelToolCallCount: rawDecisions.length,
1513
+ modelEmittedToolCallCount: rawDecisions.length,
1514
+ schedulableWaveCount: waveCounts.size,
1515
+ parallelizedCallCount,
1516
+ actuallyParallelizedCallCount: parallelizedCallCount,
1517
+ serializedCallCount: decisions.filter((decision) => decision.outcome === "serialized" ||
1518
+ decision.outcome === "delayed").length,
1519
+ delayedCallCount,
1520
+ blockedByMutationCount: decisions.filter((decision) => decision.blockedByMutation === true).length,
1521
+ mcpOptInCallCount: decisions.filter((decision) => decision.mcpOptIn === true).length,
1522
+ mcpOptInUseCount: decisions.filter((decision) => decision.mcpOptIn === true).length,
1523
+ cacheHitCount: decisions.filter((decision) => decision.cacheHit === true).length,
1524
+ totalToolWaitMs: decisions.reduce((total, decision) => total + decision.waitMs, 0),
1525
+ toolWaitTimeMs: decisions.reduce((total, decision) => total + decision.waitMs, 0),
1526
+ serializationReasons,
1527
+ decisions,
1528
+ batchShapingFeedback,
1529
+ };
1530
+ };
1531
+ const getMutationScope = (toolCall, toolDef = toolMetadataCache.get(toolCall.name)) => getPathScopedMutation(toolCall, toolDef, mutationPathBase);
1532
+ const sameMutationScope = (left, right) => {
1533
+ if (!left || !right) {
1534
+ return left === right;
1535
+ }
1536
+ const leftArgumentKeys = left.argumentKeys ?? [];
1537
+ const rightArgumentKeys = right.argumentKeys ?? [];
1538
+ return (left.source === right.source &&
1539
+ left.paths.length === right.paths.length &&
1540
+ left.paths.every((path, index) => path === right.paths[index]) &&
1541
+ leftArgumentKeys.length === rightArgumentKeys.length &&
1542
+ leftArgumentKeys.every((argumentKey, index) => argumentKey === rightArgumentKeys[index]));
1543
+ };
1544
+ const pendingMutationCount = () => pendingExecutions.filter((execution) => {
1545
+ const toolDef = toolMetadataCache.definitions.get(execution.toolCall.name);
1546
+ return (!!toolDef &&
1547
+ !isReadOnlyTool(toolDef.name, toolDef.annotations, toolDef.source));
1548
+ }).length;
1549
+ const mergeToolSchedulingMetadata = (toolCallId, metadata) => {
1550
+ toolSchedulingMetadata.set(toolCallId, metadata);
1551
+ return metadata;
1552
+ };
1553
+ const pathScopeSchedulingReason = (scope, canJoinPathScope) => {
1554
+ if (pendingExecutions.length === 0 || pendingMutationCount() === 0) {
1555
+ return "path_scope_available";
1556
+ }
1557
+ if (canJoinPathScope) {
1558
+ return "path_scope_disjoint";
1559
+ }
1560
+ const hasPathOverlap = pendingExecutions.some((execution) => {
1561
+ const pendingScope = pendingMutationScopes.get(execution);
1562
+ return pendingScope
1563
+ ? pathScopesOverlap(scope, pendingScope)
1564
+ : false;
1565
+ });
1566
+ return hasPathOverlap ? "path_scope_overlap" : "pending_mutation";
1567
+ };
1568
+ const buildToolSchedulingMetadata = ({ toolDef, readOnly, parallelSafe, scope, cache, canJoinPathScope, laneConcurrencyLimit = concurrencyLimit, }) => {
1569
+ const pendingMutations = pendingMutationCount();
1570
+ const base = {
1571
+ classification: "unknown",
1572
+ reason: "unknown_tool",
1573
+ concurrencyLimit: laneConcurrencyLimit,
1574
+ queueDepth: pendingExecutions.length,
1575
+ pendingMutations,
1576
+ cache,
1577
+ };
1578
+ if (!toolDef) {
1579
+ return base;
1580
+ }
1581
+ if (requiresSerializedTurn) {
1582
+ return {
1583
+ ...base,
1584
+ classification: "workflow_serialized",
1585
+ reason: "workflow_state_tracker",
1586
+ };
1587
+ }
1588
+ if (readOnly) {
1589
+ return {
1590
+ ...base,
1591
+ classification: "read_only",
1592
+ reason: "read_only_tool",
1593
+ };
1594
+ }
1595
+ if (scope) {
1596
+ return {
1597
+ ...base,
1598
+ classification: "path_scoped_mutation",
1599
+ reason: pathScopeSchedulingReason(scope, canJoinPathScope),
1600
+ pathScope: scope.paths,
1601
+ pathScopeSource: scope.source,
1602
+ pathArgumentKeys: scope.argumentKeys,
1603
+ };
1604
+ }
1605
+ if (parallelSafe && !readOnly) {
1606
+ return {
1607
+ ...base,
1608
+ classification: "parallel_safe_mutation",
1609
+ reason: "mcp_parallel_opt_in",
1610
+ };
1611
+ }
1612
+ if (pendingMutations > 0) {
1613
+ return {
1614
+ ...base,
1615
+ classification: "serialized_mutation",
1616
+ reason: "pending_mutation",
1617
+ };
1618
+ }
1619
+ return {
1620
+ ...base,
1621
+ classification: "serialized_mutation",
1622
+ reason: "mutating_tool",
1623
+ };
1624
+ };
1625
+ const hasPendingUnscopedMutation = () => pendingExecutions.some((execution) => {
1626
+ const toolDef = toolMetadataCache.get(execution.toolCall.name);
1627
+ return (!!toolDef &&
1628
+ !isReadOnlyTool(toolDef.name, toolDef.annotations, toolDef.source) &&
1629
+ !pendingMutationScopes.has(execution));
525
1630
  });
1631
+ const mutationBlockReason = (scope) => scope && !hasPendingUnscopedMutation()
1632
+ ? "mutation_scope_overlap"
1633
+ : "mutation_unknown_write_set";
1634
+ const isPendingParallelSafeMutation = (execution) => {
1635
+ const toolDef = toolMetadataCache.get(execution.toolCall.name);
1636
+ return (!!toolDef &&
1637
+ !isReadOnlyTool(toolDef.name, toolDef.annotations, toolDef.source) &&
1638
+ isParallelSafeTool(toolDef.name, toolDef.annotations, toolDef.source) &&
1639
+ !pendingMutationScopes.has(execution));
1640
+ };
1641
+ const canJoinParallelSafeMutationWave = (toolCall, toolDef = toolMetadataCache.get(toolCall.name)) => !!toolDef &&
1642
+ !isReadOnlyTool(toolDef.name, toolDef.annotations, toolDef.source) &&
1643
+ isParallelSafeTool(toolDef.name, toolDef.annotations, toolDef.source) &&
1644
+ pendingExecutions.length > 0 &&
1645
+ pendingExecutions.every(isPendingParallelSafeMutation);
1646
+ const canJoinPathScopedMutationIsland = (scope) => !!scope &&
1647
+ pendingExecutions.length > 0 &&
1648
+ pendingExecutions.every((execution) => {
1649
+ const pendingScope = pendingMutationScopes.get(execution);
1650
+ return pendingScope
1651
+ ? !pathScopesOverlap(scope, pendingScope)
1652
+ : false;
1653
+ });
1654
+ const laneConcurrencyLimit = ({ readOnly, scope, parallelSafe, toolDef, }) => requiresSerializedTurn
1655
+ ? 1
1656
+ : readOnly
1657
+ ? readOnlyConcurrencyLimitForTool(toolDef)
1658
+ : scope
1659
+ ? configuredConcurrency
1660
+ : parallelSafe
1661
+ ? parallelSafeMutationConcurrencyLimitForTool(toolDef)
1662
+ : 1;
526
1663
  // Override: workflow-tracked tools require serialization
527
1664
  if (configuredConcurrency > 1 && requiresSerializedTurn) {
528
1665
  concurrencyLimit = 1;
@@ -533,6 +1670,7 @@ export class ProviderTransport {
533
1670
  }
534
1671
  let steeringTriggered = false;
535
1672
  let remainingToolCalls = [];
1673
+ let mutatingToolCompletedInCurrentBatch = false;
536
1674
  const checkSteering = async () => {
537
1675
  if (steeringTriggered || !getSteeringMessages) {
538
1676
  return;
@@ -561,6 +1699,7 @@ export class ProviderTransport {
561
1699
  toolName: toolCall.name,
562
1700
  result: message,
563
1701
  isError,
1702
+ scheduling: toolSchedulingMetadata.get(toolCall.id),
564
1703
  },
565
1704
  ];
566
1705
  };
@@ -591,8 +1730,44 @@ export class ProviderTransport {
591
1730
  throw error;
592
1731
  }
593
1732
  };
1733
+ const emittedIndexForToolCall = (toolCall) => {
1734
+ const emittedIndex = toolCallsToExecute.findIndex((candidate) => candidate.id === toolCall.id);
1735
+ return emittedIndex >= 0
1736
+ ? emittedIndex
1737
+ : toolSchedulingDecisions.size;
1738
+ };
594
1739
  const emitSkippedToolCall = (toolCall) => {
595
1740
  const sanitizedSkippedArgs = this.safetyMiddleware.sanitizeForLogging(toolCall.arguments);
1741
+ const existingScheduling = toolSchedulingMetadata.get(toolCall.id);
1742
+ const toolDef = toolMetadataCache.get(toolCall.name);
1743
+ const skippedToolCallReadOnly = isReadOnlyToolCall(toolCall);
1744
+ const skippedToolCallParallelSafe = isParallelSafeToolCall(toolCall, toolDef);
1745
+ const mutationScope = getMutationScope(toolCall, toolDef);
1746
+ const reusableToolResultKey = getReusableToolResultCacheKey(toolCall, toolMetadataCache);
1747
+ const schedulingMetadata = mergeToolSchedulingMetadata(toolCall.id, existingScheduling ??
1748
+ buildToolSchedulingMetadata({
1749
+ toolDef,
1750
+ readOnly: skippedToolCallReadOnly,
1751
+ parallelSafe: skippedToolCallParallelSafe,
1752
+ scope: mutationScope,
1753
+ cache: reusableToolResultKey === undefined ? "disabled" : "miss",
1754
+ canJoinPathScope: canJoinPathScopedMutationIsland(mutationScope),
1755
+ laneConcurrencyLimit: laneConcurrencyLimit({
1756
+ readOnly: skippedToolCallReadOnly,
1757
+ parallelSafe: skippedToolCallParallelSafe,
1758
+ scope: mutationScope,
1759
+ toolDef,
1760
+ }),
1761
+ }));
1762
+ const schedulingDecision = {
1763
+ callId: toolCall.id,
1764
+ toolName: toolCall.name,
1765
+ emittedIndex: emittedIndexForToolCall(toolCall),
1766
+ decision: "skipped",
1767
+ reason: "steering_interrupted",
1768
+ schedulerWaitMs: schedulerWaitMs(),
1769
+ };
1770
+ toolSchedulingDecisions.set(toolCall.id, schedulingDecision);
596
1771
  const skippedResult = {
597
1772
  role: "toolResult",
598
1773
  toolCallId: toolCall.id,
@@ -612,31 +1787,69 @@ export class ProviderTransport {
612
1787
  toolCallId: toolCall.id,
613
1788
  toolName: toolCall.name,
614
1789
  args: sanitizedSkippedArgs,
1790
+ scheduling: schedulingMetadata,
615
1791
  },
616
1792
  ...emitToolResult(skippedResult, toolCall, true),
617
1793
  ];
618
1794
  };
619
- const scheduleResolveIfNeeded = async () => {
620
- if (pendingExecutions.length < concurrencyLimit) {
621
- return [];
1795
+ const recordSafetyBlockedToolCall = (toolCall) => {
1796
+ const existing = toolSchedulingDecisions.get(toolCall.id);
1797
+ if (existing) {
1798
+ return existing;
622
1799
  }
1800
+ const scheduling = {
1801
+ callId: toolCall.id,
1802
+ toolName: toolCall.name,
1803
+ emittedIndex: emittedIndexForToolCall(toolCall),
1804
+ decision: "skipped",
1805
+ reason: "safety_blocked",
1806
+ schedulerWaitMs: schedulerWaitMs(),
1807
+ };
1808
+ toolSchedulingDecisions.set(toolCall.id, scheduling);
1809
+ return scheduling;
1810
+ };
1811
+ const emitSafetyPipelineToolResult = (message, toolCall, isError, metadata) => {
1812
+ if (isError) {
1813
+ recordSafetyBlockedToolCall(toolCall);
1814
+ }
1815
+ return emitToolResult(message, toolCall, isError, metadata);
1816
+ };
1817
+ const resolveNextPendingExecution = async () => {
623
1818
  const events = [];
624
- while (pendingExecutions.length >= concurrencyLimit) {
1819
+ while (true) {
625
1820
  const next = await waitForNextExecutionOrUpdate(pendingExecutions, toolUpdateQueue);
626
1821
  if (next.kind === "update") {
627
1822
  events.push(next.event);
628
1823
  continue;
629
1824
  }
630
1825
  const outcome = next.outcome;
1826
+ pendingMutationScopes.delete(next.execution);
1827
+ pendingExecutionWaveIndexes.delete(next.execution);
1828
+ pendingExecutionScheduling.delete(next.execution);
1829
+ const completedToolWasMutating = getReusableToolResultCacheKey(next.execution.toolCall, toolMetadataCache) === undefined;
1830
+ invalidateReusableToolResultsAfterMutation(next.execution.toolCall, toolMetadataCache, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, pendingReusableToolSafetyChecks, reusableToolResultCacheGeneration);
1831
+ mutatingToolCompletedInCurrentBatch ||= completedToolWasMutating;
631
1832
  events.push(...emitToolResult(outcome.message, next.execution.toolCall, outcome.isError, {
632
1833
  toolExecutionId: outcome.toolExecutionId,
633
1834
  approvalRequestId: outcome.approvalRequestId,
634
1835
  }));
635
1836
  await checkSteering();
636
- break;
1837
+ return events;
1838
+ }
1839
+ };
1840
+ const drainPendingExecutions = async (targetPendingCount = 0) => {
1841
+ const events = [];
1842
+ while (pendingExecutions.length > targetPendingCount) {
1843
+ events.push(...(await resolveNextPendingExecution()));
637
1844
  }
638
1845
  return events;
639
1846
  };
1847
+ const scheduleResolveIfNeeded = async () => {
1848
+ if (pendingExecutions.length < concurrencyLimit) {
1849
+ return [];
1850
+ }
1851
+ return drainPendingExecutions(concurrencyLimit - 1);
1852
+ };
640
1853
  for (let toolIndex = 0; toolIndex < toolCallsToExecute.length; toolIndex++) {
641
1854
  if (steeringTriggered) {
642
1855
  remainingToolCalls = toolCallsToExecute.slice(toolIndex);
@@ -645,43 +1858,138 @@ export class ProviderTransport {
645
1858
  const toolCall = toolCallsToExecute[toolIndex];
646
1859
  if (!toolCall)
647
1860
  continue;
648
- // Run safety pipeline (rate limiting, hooks, firewall, approval, validation)
649
- const safetyIterator = evaluateToolSafety({
650
- toolCall,
651
- tools,
652
- userMessage,
653
- cfg,
654
- signal,
655
- clock: this.clock,
656
- safetyMiddleware: this.safetyMiddleware,
657
- workflowState: this.workflowState,
658
- adaptiveThresholds: this.adaptiveThresholds,
659
- auditLogger: this.auditLogger,
660
- approvalService: this.options.approvalService,
661
- toolExecutionBridge: this.options.platformToolExecutionBridge === false
662
- ? undefined
663
- : (this.options.platformToolExecutionBridge ??
664
- getDefaultPlatformToolExecutionBridge()),
665
- hookService,
666
- firewall,
667
- rateLimitState: {
668
- recentToolTimestamps: this.recentToolTimestamps,
669
- toolCallsThisMinute: this.toolCallsThisMinute,
670
- minuteWindowStart: this.minuteWindowStart,
671
- rateWindowMs: ProviderTransport.TOOL_RATE_WINDOW_MS,
672
- rateLimit: ProviderTransport.TOOL_RATE_LIMIT,
673
- },
674
- emitToolResult,
1861
+ let schedulingDelayReason;
1862
+ let blockedByMutation = false;
1863
+ const noteMutationDelay = (reason) => {
1864
+ schedulingDelayReason ??= reason;
1865
+ blockedByMutation = true;
1866
+ };
1867
+ const originalToolCallReadOnly = isReadOnlyToolCall(toolCall);
1868
+ const originalMutationScope = originalToolCallReadOnly
1869
+ ? undefined
1870
+ : getMutationScope(toolCall);
1871
+ const originalToolDef = toolDefinitionsByName.get(toolCall.name);
1872
+ const originalToolCallParallelSafe = isParallelSafeToolCall(toolCall, originalToolDef);
1873
+ const originalCanJoinPathScope = canJoinPathScopedMutationIsland(originalMutationScope);
1874
+ const originalJoinsParallelSafeMutationWave = !originalToolCallReadOnly &&
1875
+ canJoinParallelSafeMutationWave(toolCall);
1876
+ let preDrainSchedulingMetadata;
1877
+ if (!originalToolCallReadOnly &&
1878
+ pendingExecutions.length > 0 &&
1879
+ pendingMutationCount() > 0 &&
1880
+ !originalCanJoinPathScope &&
1881
+ !originalJoinsParallelSafeMutationWave) {
1882
+ preDrainSchedulingMetadata = buildToolSchedulingMetadata({
1883
+ toolDef: originalToolDef,
1884
+ readOnly: originalToolCallReadOnly,
1885
+ parallelSafe: originalToolCallParallelSafe,
1886
+ scope: originalMutationScope,
1887
+ cache: "disabled",
1888
+ canJoinPathScope: originalCanJoinPathScope,
1889
+ laneConcurrencyLimit: laneConcurrencyLimit({
1890
+ readOnly: originalToolCallReadOnly,
1891
+ parallelSafe: originalToolCallParallelSafe,
1892
+ scope: originalMutationScope,
1893
+ toolDef: originalToolDef,
1894
+ }),
1895
+ });
1896
+ if (hasPendingMutatingToolExecution(pendingExecutions, toolMetadataCache)) {
1897
+ noteMutationDelay(mutationBlockReason(originalMutationScope));
1898
+ }
1899
+ const events = await drainPendingExecutions();
1900
+ for (const event of events) {
1901
+ yield event;
1902
+ }
1903
+ if (steeringTriggered) {
1904
+ if (preDrainSchedulingMetadata) {
1905
+ mergeToolSchedulingMetadata(toolCall.id, preDrainSchedulingMetadata);
1906
+ }
1907
+ remainingToolCalls = toolCallsToExecute.slice(toolIndex);
1908
+ break;
1909
+ }
1910
+ }
1911
+ const reusableToolResultKey = getReusableToolResultCacheKey(toolCall, toolMetadataCache);
1912
+ const alreadyHadReusableToolResultState = reusableToolResultKey !== undefined &&
1913
+ hasReusableToolResultState(reusableToolResultKey, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, pendingReusableToolSafetyChecks);
1914
+ incrementPendingReusableToolSafetyCheck(reusableToolResultKey, pendingReusableToolSafetyChecks);
1915
+ const shouldSkipLoopDetection = (candidateToolCall) => {
1916
+ const candidateKey = getReusableToolResultCacheKey(candidateToolCall, toolMetadataCache);
1917
+ return (candidateKey !== undefined &&
1918
+ candidateKey === reusableToolResultKey &&
1919
+ alreadyHadReusableToolResultState &&
1920
+ !hasPendingMutatingToolExecution(pendingExecutions, toolMetadataCache) &&
1921
+ !mutatingToolCompletedInCurrentBatch &&
1922
+ hasReusableToolResultState(candidateKey, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, pendingReusableToolSafetyChecks));
1923
+ };
1924
+ const nextInitialSchedulingMetadata = buildToolSchedulingMetadata({
1925
+ toolDef: originalToolDef,
1926
+ readOnly: originalToolCallReadOnly,
1927
+ parallelSafe: originalToolCallParallelSafe,
1928
+ scope: originalMutationScope,
1929
+ cache: reusableToolResultKey === undefined
1930
+ ? "disabled"
1931
+ : alreadyHadReusableToolResultState
1932
+ ? "candidate"
1933
+ : "miss",
1934
+ canJoinPathScope: canJoinPathScopedMutationIsland(originalMutationScope),
1935
+ laneConcurrencyLimit: laneConcurrencyLimit({
1936
+ readOnly: originalToolCallReadOnly,
1937
+ parallelSafe: originalToolCallParallelSafe,
1938
+ scope: originalMutationScope,
1939
+ toolDef: originalToolDef,
1940
+ }),
675
1941
  });
1942
+ const initialSchedulingMetadata = mergeToolSchedulingMetadata(toolCall.id, preDrainSchedulingMetadata
1943
+ ? {
1944
+ ...nextInitialSchedulingMetadata,
1945
+ classification: preDrainSchedulingMetadata.classification,
1946
+ reason: preDrainSchedulingMetadata.reason,
1947
+ queueDepth: preDrainSchedulingMetadata.queueDepth,
1948
+ pendingMutations: preDrainSchedulingMetadata.pendingMutations,
1949
+ }
1950
+ : nextInitialSchedulingMetadata);
1951
+ // Run safety pipeline (rate limiting, hooks, firewall, approval, validation)
676
1952
  let safetyVerdict;
677
1953
  let rateLimitUpdate;
678
- while (true) {
679
- const safetyStep = await safetyIterator.next();
680
- if (safetyStep.done) {
681
- ({ verdict: safetyVerdict, rateLimitUpdate } = safetyStep.value);
682
- break;
1954
+ try {
1955
+ const safetyIterator = evaluateToolSafety({
1956
+ toolCall,
1957
+ tools,
1958
+ userMessage,
1959
+ cfg,
1960
+ signal,
1961
+ clock: this.clock,
1962
+ safetyMiddleware: this.safetyMiddleware,
1963
+ workflowState: this.workflowState,
1964
+ adaptiveThresholds: this.adaptiveThresholds,
1965
+ auditLogger: this.auditLogger,
1966
+ approvalService: this.options.approvalService,
1967
+ toolExecutionBridge: platformToolExecutionBridge,
1968
+ hookService,
1969
+ firewall,
1970
+ rateLimitState: {
1971
+ recentToolTimestamps: this.recentToolTimestamps,
1972
+ toolCallsThisMinute: this.toolCallsThisMinute,
1973
+ minuteWindowStart: this.minuteWindowStart,
1974
+ rateWindowMs: ProviderTransport.TOOL_RATE_WINDOW_MS,
1975
+ rateLimit: ProviderTransport.TOOL_RATE_LIMIT,
1976
+ },
1977
+ shouldSkipLoopDetection,
1978
+ schedulingMetadata: initialSchedulingMetadata,
1979
+ emitToolResult: emitSafetyPipelineToolResult,
1980
+ });
1981
+ while (true) {
1982
+ const safetyStep = await safetyIterator.next();
1983
+ if (safetyStep.done) {
1984
+ ({ verdict: safetyVerdict, rateLimitUpdate } =
1985
+ safetyStep.value);
1986
+ break;
1987
+ }
1988
+ yield safetyStep.value;
683
1989
  }
684
- yield safetyStep.value;
1990
+ }
1991
+ finally {
1992
+ decrementPendingReusableToolSafetyCheck(reusableToolResultKey, pendingReusableToolSafetyChecks);
685
1993
  }
686
1994
  if (!safetyVerdict || !rateLimitUpdate) {
687
1995
  throw new Error("Safety pipeline did not return a verdict.");
@@ -698,7 +2006,244 @@ export class ProviderTransport {
698
2006
  continue;
699
2007
  }
700
2008
  const { effectiveToolCall, validatedArgs, toolDef: tool, sanitizedExecutionArgs, } = safetyVerdict;
2009
+ const effectiveToolCallReadOnly = isReadOnlyTool(tool.name, tool.annotations, tool.source) &&
2010
+ tool.annotations?.destructiveHint !== true;
2011
+ const effectiveToolCallParallelSafe = isParallelSafeTool(tool.name, tool.annotations, tool.source);
2012
+ if (effectiveToolCallReadOnly &&
2013
+ hasPendingMutatingToolExecution(pendingExecutions, toolMetadataCache)) {
2014
+ noteMutationDelay("pending_mutation");
2015
+ const events = await drainPendingExecutions();
2016
+ for (const event of events) {
2017
+ yield event;
2018
+ }
2019
+ if (steeringTriggered) {
2020
+ remainingToolCalls = toolCallsToExecute.slice(toolIndex);
2021
+ break;
2022
+ }
2023
+ }
2024
+ const effectiveMutationScope = effectiveToolCallReadOnly
2025
+ ? undefined
2026
+ : getMutationScope(effectiveToolCall, tool);
2027
+ const joinsPathScopedMutationIsland = !requiresSerializedTurn &&
2028
+ canJoinPathScopedMutationIsland(effectiveMutationScope);
2029
+ const joinsParallelSafeMutationWave = !requiresSerializedTurn &&
2030
+ !effectiveToolCallReadOnly &&
2031
+ canJoinParallelSafeMutationWave(effectiveToolCall, tool);
2032
+ if (!effectiveToolCallReadOnly &&
2033
+ pendingExecutions.length > 0 &&
2034
+ !joinsPathScopedMutationIsland &&
2035
+ !joinsParallelSafeMutationWave) {
2036
+ if (hasPendingMutatingToolExecution(pendingExecutions, toolMetadataCache)) {
2037
+ noteMutationDelay(mutationBlockReason(effectiveMutationScope));
2038
+ }
2039
+ const events = await drainPendingExecutions();
2040
+ for (const event of events) {
2041
+ yield event;
2042
+ }
2043
+ if (steeringTriggered) {
2044
+ remainingToolCalls = toolCallsToExecute.slice(toolIndex);
2045
+ break;
2046
+ }
2047
+ }
2048
+ concurrencyLimit = requiresSerializedTurn
2049
+ ? 1
2050
+ : effectiveToolCallReadOnly
2051
+ ? readOnlyConcurrencyLimitForTool(tool)
2052
+ : effectiveMutationScope
2053
+ ? configuredConcurrency
2054
+ : effectiveToolCallParallelSafe
2055
+ ? parallelSafeMutationConcurrencyLimitForTool(tool)
2056
+ : 1;
2057
+ const effectiveSchedulingMetadata = buildToolSchedulingMetadata({
2058
+ toolDef: tool,
2059
+ readOnly: effectiveToolCallReadOnly,
2060
+ parallelSafe: effectiveToolCallParallelSafe,
2061
+ scope: effectiveMutationScope,
2062
+ cache: reusableToolResultKey === undefined
2063
+ ? "disabled"
2064
+ : alreadyHadReusableToolResultState
2065
+ ? "candidate"
2066
+ : "miss",
2067
+ canJoinPathScope: joinsPathScopedMutationIsland,
2068
+ laneConcurrencyLimit: laneConcurrencyLimit({
2069
+ readOnly: effectiveToolCallReadOnly,
2070
+ parallelSafe: effectiveToolCallParallelSafe,
2071
+ scope: effectiveMutationScope,
2072
+ toolDef: tool,
2073
+ }),
2074
+ });
2075
+ const previousSchedulingMetadata = toolSchedulingMetadata.get(toolCall.id);
2076
+ const preservePreHookBlockedSchedulingReason = (previousSchedulingMetadata?.reason === "path_scope_overlap" ||
2077
+ previousSchedulingMetadata?.reason === "pending_mutation") &&
2078
+ sameMutationScope(originalMutationScope, effectiveMutationScope);
2079
+ mergeToolSchedulingMetadata(toolCall.id, preservePreHookBlockedSchedulingReason
2080
+ ? {
2081
+ ...effectiveSchedulingMetadata,
2082
+ classification: previousSchedulingMetadata.classification,
2083
+ reason: previousSchedulingMetadata.reason,
2084
+ queueDepth: previousSchedulingMetadata.queueDepth,
2085
+ pendingMutations: previousSchedulingMetadata.pendingMutations,
2086
+ }
2087
+ : effectiveSchedulingMetadata);
701
2088
  // Use hook-modified (pre-validation) args for hook inputs
2089
+ const policyCheckedReusableToolResultKey = getReusableToolResultCacheKey(effectiveToolCall, toolMetadataCache);
2090
+ const canReuseToolResult = reusableToolResultKey !== undefined &&
2091
+ policyCheckedReusableToolResultKey === reusableToolResultKey;
2092
+ if (canReuseToolResult && reusableToolResultKey) {
2093
+ policyCheckedReusableToolResultKeys.add(reusableToolResultKey);
2094
+ }
2095
+ const canServeReusableToolResult = canReuseToolResult &&
2096
+ !hasPendingMutatingToolExecution(pendingExecutions, toolMetadataCache) &&
2097
+ !mutatingToolCompletedInCurrentBatch;
2098
+ if (canServeReusableToolResult) {
2099
+ const cachedEntry = reusableToolResults.get(reusableToolResultKey);
2100
+ if (cachedEntry) {
2101
+ const scheduling = {
2102
+ callId: toolCall.id,
2103
+ toolName: toolCall.name,
2104
+ emittedIndex: toolIndex,
2105
+ decision: "cached",
2106
+ reason: "reusable_tool_result_ready",
2107
+ schedulerWaitMs: schedulerWaitMs(),
2108
+ cacheHit: true,
2109
+ };
2110
+ toolSchedulingDecisions.set(toolCall.id, scheduling);
2111
+ const cacheHitStart = this.clock.now();
2112
+ const cachedOutcome = await recordReusableToolExecutionBridgeOutput({
2113
+ bridge: platformToolExecutionBridge,
2114
+ plan: safetyVerdict.toolExecutionBridgePlan,
2115
+ outcome: {
2116
+ message: {
2117
+ ...cachedEntry.message,
2118
+ toolCallId: toolCall.id,
2119
+ toolName: toolCall.name,
2120
+ content: cachedEntry.message.content.map((item) => ({
2121
+ ...item,
2122
+ })),
2123
+ timestamp: this.clock.now(),
2124
+ },
2125
+ isError: false,
2126
+ },
2127
+ durationMs: this.clock.now() - cacheHitStart,
2128
+ signal,
2129
+ });
2130
+ mergeToolSchedulingMetadata(toolCall.id, {
2131
+ classification: "cache_reuse",
2132
+ reason: "cache_hit",
2133
+ concurrencyLimit,
2134
+ queueDepth: pendingExecutions.length,
2135
+ pendingMutations: pendingMutationCount(),
2136
+ cache: "hit",
2137
+ });
2138
+ for (const event of emitToolResult(cachedOutcome.message, toolCall, cachedOutcome.isError, {
2139
+ toolExecutionId: cachedOutcome.toolExecutionId,
2140
+ approvalRequestId: cachedOutcome.approvalRequestId,
2141
+ })) {
2142
+ yield event;
2143
+ }
2144
+ await checkSteering();
2145
+ if (steeringTriggered) {
2146
+ remainingToolCalls = toolCallsToExecute.slice(toolIndex + 1);
2147
+ break;
2148
+ }
2149
+ continue;
2150
+ }
2151
+ const pendingReusable = pendingReusableToolResults.get(reusableToolResultKey);
2152
+ if (pendingReusable) {
2153
+ mergeToolSchedulingMetadata(toolCall.id, {
2154
+ classification: "cache_reuse",
2155
+ reason: "cache_pending",
2156
+ concurrencyLimit,
2157
+ queueDepth: pendingExecutions.length,
2158
+ pendingMutations: pendingMutationCount(),
2159
+ cache: "pending_hit",
2160
+ });
2161
+ const waveIndex = pendingWaveIndex();
2162
+ const scheduling = {
2163
+ callId: toolCall.id,
2164
+ toolName: toolCall.name,
2165
+ emittedIndex: toolIndex,
2166
+ waveIndex,
2167
+ decision: "cached",
2168
+ reason: "reusable_tool_result_pending",
2169
+ schedulerWaitMs: schedulerWaitMs(),
2170
+ cacheHit: true,
2171
+ };
2172
+ toolSchedulingDecisions.set(toolCall.id, scheduling);
2173
+ const pendingExecution = {
2174
+ toolCall,
2175
+ promise: (async () => {
2176
+ const cacheHitStart = this.clock.now();
2177
+ return recordReusableToolExecutionBridgeOutput({
2178
+ bridge: platformToolExecutionBridge,
2179
+ plan: safetyVerdict.toolExecutionBridgePlan,
2180
+ outcome: cloneToolOutcomeForCall(await pendingReusable, toolCall, this.clock.now()),
2181
+ durationMs: this.clock.now() - cacheHitStart,
2182
+ signal,
2183
+ });
2184
+ })(),
2185
+ };
2186
+ pendingExecutions.push(pendingExecution);
2187
+ pendingExecutionWaveIndexes.set(pendingExecution, waveIndex);
2188
+ pendingExecutionScheduling.set(pendingExecution, scheduling);
2189
+ const events = await scheduleResolveIfNeeded();
2190
+ for (const event of events) {
2191
+ yield event;
2192
+ }
2193
+ if (steeringTriggered) {
2194
+ remainingToolCalls = toolCallsToExecute.slice(toolIndex + 1);
2195
+ break;
2196
+ }
2197
+ continue;
2198
+ }
2199
+ }
2200
+ const pendingBeforeSchedule = pendingExecutions.length;
2201
+ const waveIndex = pendingBeforeSchedule > 0 ? pendingWaveIndex() : nextWaveIndex();
2202
+ const mcpOptIn = isMcpParallelOptIn(tool) && !effectiveToolCallReadOnly;
2203
+ const decision = schedulingDelayReason !== undefined
2204
+ ? "delayed"
2205
+ : pendingBeforeSchedule > 0
2206
+ ? "parallelized"
2207
+ : requiresSerializedTurn ||
2208
+ (!effectiveToolCallReadOnly &&
2209
+ !effectiveMutationScope &&
2210
+ !effectiveToolCallParallelSafe)
2211
+ ? "serialized"
2212
+ : "scheduled";
2213
+ const reason = schedulingDelayReason ??
2214
+ (effectiveToolCallReadOnly
2215
+ ? requiresSerializedTurn
2216
+ ? "workflow_state_serialized"
2217
+ : pendingBeforeSchedule > 0
2218
+ ? "read_only_wave"
2219
+ : "read_only_wave_start"
2220
+ : requiresSerializedTurn
2221
+ ? "workflow_state_serialized"
2222
+ : joinsPathScopedMutationIsland
2223
+ ? "path_scoped_mutation_disjoint"
2224
+ : joinsParallelSafeMutationWave && mcpOptIn
2225
+ ? "mcp_parallel_opt_in"
2226
+ : joinsParallelSafeMutationWave
2227
+ ? "parallel_safe_mutation_wave"
2228
+ : mcpOptIn
2229
+ ? pendingBeforeSchedule > 0
2230
+ ? "mcp_parallel_opt_in"
2231
+ : "mcp_parallel_opt_in_wave_start"
2232
+ : effectiveMutationScope
2233
+ ? "path_scoped_mutation_wave_start"
2234
+ : "serialized_tool");
2235
+ const scheduling = {
2236
+ callId: toolCall.id,
2237
+ toolName: toolCall.name,
2238
+ emittedIndex: toolIndex,
2239
+ waveIndex,
2240
+ decision,
2241
+ reason,
2242
+ schedulerWaitMs: schedulerWaitMs(),
2243
+ mcpOptIn,
2244
+ blockedByMutation,
2245
+ };
2246
+ toolSchedulingDecisions.set(toolCall.id, scheduling);
702
2247
  // For client tools, set up the execution promise first, then emit event
703
2248
  // This prevents race conditions where the client responds before we're listening
704
2249
  let clientToolExecPromise;
@@ -731,18 +2276,24 @@ export class ProviderTransport {
731
2276
  toolRetryService: this.options.toolRetryService,
732
2277
  toolRetryConfig: this.options.toolRetryConfig,
733
2278
  clientToolService: this.options.clientToolService,
734
- toolExecutionBridge: this.options.platformToolExecutionBridge === false
735
- ? undefined
736
- : (this.options.platformToolExecutionBridge ??
737
- getDefaultPlatformToolExecutionBridge()),
2279
+ toolExecutionBridge: platformToolExecutionBridge,
738
2280
  toolExecutionBridgePlan: safetyVerdict.toolExecutionBridgePlan,
739
2281
  toolUpdateQueue,
740
2282
  clientToolExecPromise,
741
2283
  });
742
- pendingExecutions.push({
2284
+ const trackedExecutionPromise = canReuseToolResult && reusableToolResultKey
2285
+ ? trackReusableToolResult(reusableToolResultKey, executionPromise, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, reusableToolResultCacheGeneration)
2286
+ : executionPromise;
2287
+ const pendingExecution = {
743
2288
  toolCall,
744
- promise: executionPromise,
745
- });
2289
+ promise: trackedExecutionPromise,
2290
+ };
2291
+ pendingExecutions.push(pendingExecution);
2292
+ pendingExecutionWaveIndexes.set(pendingExecution, waveIndex);
2293
+ pendingExecutionScheduling.set(pendingExecution, scheduling);
2294
+ if (effectiveMutationScope) {
2295
+ pendingMutationScopes.set(pendingExecution, effectiveMutationScope);
2296
+ }
746
2297
  const events = await scheduleResolveIfNeeded();
747
2298
  for (const event of events) {
748
2299
  yield event;
@@ -753,21 +2304,10 @@ export class ProviderTransport {
753
2304
  }
754
2305
  }
755
2306
  while (pendingExecutions.length > 0) {
756
- const next = await waitForNextExecutionOrUpdate(pendingExecutions, toolUpdateQueue);
757
- if (next.kind === "update") {
758
- yield next.event;
759
- continue;
760
- }
761
- const outcome = next.outcome;
762
- for (const event of emitToolResult(outcome.message, next.execution.toolCall, outcome.isError, {
763
- toolExecutionId: outcome.toolExecutionId,
764
- approvalRequestId: outcome.approvalRequestId,
765
- })) {
2307
+ for (const event of await resolveNextPendingExecution()) {
766
2308
  yield event;
767
2309
  }
768
- await checkSteering();
769
2310
  }
770
- this.safetyMiddleware.clearCredentials();
771
2311
  if (steeringTriggered && remainingToolCalls.length > 0) {
772
2312
  for (const toolCall of remainingToolCalls) {
773
2313
  for (const event of emitSkippedToolCall(toolCall)) {
@@ -775,6 +2315,11 @@ export class ProviderTransport {
775
2315
  }
776
2316
  }
777
2317
  }
2318
+ const toolPhaseSummary = buildToolPhaseSummary();
2319
+ if (toolPhaseSummary) {
2320
+ yield toolPhaseSummary;
2321
+ }
2322
+ this.safetyMiddleware.clearCredentials();
778
2323
  if (!steeringTriggered && getSteeringMessages) {
779
2324
  const steering = await getSteeringMessages();
780
2325
  if (steering.length > 0) {