@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.
- package/README.md +56 -1
- package/dist/agent/action-approval.d.ts +12 -2
- package/dist/agent/action-approval.d.ts.map +1 -1
- package/dist/agent/action-approval.js +19 -32
- package/dist/agent/action-approval.js.map +1 -1
- package/dist/agent/agent.d.ts +1 -0
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +26 -0
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/compaction.d.ts +2 -0
- package/dist/agent/compaction.d.ts.map +1 -1
- package/dist/agent/compaction.js +4 -2
- package/dist/agent/compaction.js.map +1 -1
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/modes.d.ts +56 -4
- package/dist/agent/modes.d.ts.map +1 -1
- package/dist/agent/modes.js +163 -2
- package/dist/agent/modes.js.map +1 -1
- package/dist/agent/prompt-recovery.d.ts.map +1 -1
- package/dist/agent/prompt-recovery.js +1 -3
- package/dist/agent/prompt-recovery.js.map +1 -1
- package/dist/agent/providers/anthropic.d.ts.map +1 -1
- package/dist/agent/providers/anthropic.js +9 -1
- package/dist/agent/providers/anthropic.js.map +1 -1
- package/dist/agent/providers/codex-app-server.d.ts +12 -0
- package/dist/agent/providers/codex-app-server.d.ts.map +1 -0
- package/dist/agent/providers/codex-app-server.js +788 -0
- package/dist/agent/providers/codex-app-server.js.map +1 -0
- package/dist/agent/providers/google-gemini-cli.js +14 -3
- package/dist/agent/providers/google.js +22 -3
- package/dist/agent/providers/scripted.d.ts +11 -0
- package/dist/agent/providers/scripted.d.ts.map +1 -0
- package/dist/agent/providers/scripted.js +399 -0
- package/dist/agent/providers/scripted.js.map +1 -0
- package/dist/agent/providers/vertex.js +14 -3
- package/dist/agent/scenario-source.d.ts +19 -0
- package/dist/agent/scenario-source.d.ts.map +1 -0
- package/dist/agent/scenario-source.js +112 -0
- package/dist/agent/scenario-source.js.map +1 -0
- package/dist/agent/subagent-specs.d.ts +1 -1
- package/dist/agent/subagent-specs.js +1 -1
- package/dist/agent/subagent-specs.js.map +1 -1
- package/dist/agent/swarm/executor.d.ts +25 -0
- package/dist/agent/swarm/executor.d.ts.map +1 -1
- package/dist/agent/swarm/executor.js +795 -20
- package/dist/agent/swarm/executor.js.map +1 -1
- package/dist/agent/swarm/runtime-events.d.ts +11 -0
- package/dist/agent/swarm/runtime-events.d.ts.map +1 -0
- package/dist/agent/swarm/runtime-events.js +26 -0
- package/dist/agent/swarm/runtime-events.js.map +1 -0
- package/dist/agent/swarm/types.d.ts +78 -0
- package/dist/agent/swarm/types.d.ts.map +1 -1
- package/dist/agent/swarm/types.js.map +1 -1
- package/dist/agent/tracing.d.ts +1 -1
- package/dist/agent/tracing.d.ts.map +1 -1
- package/dist/agent/tracing.js +17 -9
- package/dist/agent/tracing.js.map +1 -1
- package/dist/agent/transport/create-provider-stream.d.ts.map +1 -1
- package/dist/agent/transport/create-provider-stream.js +14 -0
- package/dist/agent/transport/create-provider-stream.js.map +1 -1
- package/dist/agent/transport/stable-stringify.d.ts +2 -0
- package/dist/agent/transport/stable-stringify.d.ts.map +1 -0
- package/dist/agent/transport/stable-stringify.js +14 -0
- package/dist/agent/transport/stable-stringify.js.map +1 -0
- package/dist/agent/transport/tool-execution-bridge.d.ts.map +1 -1
- package/dist/agent/transport/tool-execution-bridge.js +2 -15
- package/dist/agent/transport/tool-execution-bridge.js.map +1 -1
- package/dist/agent/transport/tool-safety-pipeline.d.ts +5 -1
- package/dist/agent/transport/tool-safety-pipeline.d.ts.map +1 -1
- package/dist/agent/transport/tool-safety-pipeline.js +184 -36
- package/dist/agent/transport/tool-safety-pipeline.js.map +1 -1
- package/dist/agent/transport.d.ts +8 -0
- package/dist/agent/transport.d.ts.map +1 -1
- package/dist/agent/transport.js +1613 -68
- package/dist/agent/transport.js.map +1 -1
- package/dist/agent/types.d.ts +170 -2
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/enterprise-routes.d.ts.map +1 -1
- package/dist/api/enterprise-routes.js +34 -3
- package/dist/api/enterprise-routes.js.map +1 -1
- package/dist/app-server/in-process-client.d.ts +32 -0
- package/dist/app-server/in-process-client.d.ts.map +1 -0
- package/dist/app-server/in-process-client.js +73 -0
- package/dist/app-server/in-process-client.js.map +1 -0
- package/dist/app-server/session-api.d.ts +36 -0
- package/dist/app-server/session-api.d.ts.map +1 -0
- package/dist/app-server/session-api.js +713 -0
- package/dist/app-server/session-api.js.map +1 -0
- package/dist/approvals/platform-action-approval.d.ts +3 -1
- package/dist/approvals/platform-action-approval.d.ts.map +1 -1
- package/dist/approvals/platform-action-approval.js +16 -9
- package/dist/approvals/platform-action-approval.js.map +1 -1
- package/dist/approvals/service-client.d.ts.map +1 -1
- package/dist/approvals/service-client.js +7 -7
- package/dist/approvals/service-client.js.map +1 -1
- package/dist/audit/logger.d.ts +4 -4
- package/dist/bootstrap/agent-creation-setup.d.ts +4 -0
- package/dist/bootstrap/agent-creation-setup.d.ts.map +1 -1
- package/dist/bootstrap/agent-creation-setup.js +3 -1
- package/dist/bootstrap/agent-creation-setup.js.map +1 -1
- package/dist/bootstrap/auth-setup.js +1 -1
- package/dist/bootstrap/auth-setup.js.map +1 -1
- package/dist/bootstrap/event-subscriptions-setup.d.ts +6 -0
- package/dist/bootstrap/event-subscriptions-setup.d.ts.map +1 -1
- package/dist/bootstrap/event-subscriptions-setup.js +26 -2
- package/dist/bootstrap/event-subscriptions-setup.js.map +1 -1
- package/dist/bootstrap/model-resolution-setup.d.ts.map +1 -1
- package/dist/bootstrap/model-resolution-setup.js +4 -1
- package/dist/bootstrap/model-resolution-setup.js.map +1 -1
- package/dist/bootstrap/tools-setup.d.ts +2 -1
- package/dist/bootstrap/tools-setup.d.ts.map +1 -1
- package/dist/bootstrap/tools-setup.js +5 -1
- package/dist/bootstrap/tools-setup.js.map +1 -1
- package/dist/cli/args.d.ts +9 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +130 -5
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/commands/a2a.d.ts +9 -0
- package/dist/cli/commands/a2a.d.ts.map +1 -0
- package/dist/cli/commands/a2a.js +1714 -0
- package/dist/cli/commands/a2a.js.map +1 -0
- package/dist/cli/commands/agents.d.ts +16 -2
- package/dist/cli/commands/agents.d.ts.map +1 -1
- package/dist/cli/commands/agents.js +223 -35
- package/dist/cli/commands/agents.js.map +1 -1
- package/dist/cli/commands/codex.d.ts +1 -1
- package/dist/cli/commands/codex.d.ts.map +1 -1
- package/dist/cli/commands/codex.js +145 -39
- package/dist/cli/commands/codex.js.map +1 -1
- package/dist/cli/commands/context.d.ts +10 -0
- package/dist/cli/commands/context.d.ts.map +1 -0
- package/dist/cli/commands/context.js +176 -0
- package/dist/cli/commands/context.js.map +1 -0
- package/dist/cli/commands/hosted-runner.d.ts +1 -0
- package/dist/cli/commands/hosted-runner.d.ts.map +1 -1
- package/dist/cli/commands/hosted-runner.js +9 -1
- package/dist/cli/commands/hosted-runner.js.map +1 -1
- package/dist/cli/commands/modes.d.ts +8 -0
- package/dist/cli/commands/modes.d.ts.map +1 -0
- package/dist/cli/commands/modes.js +151 -0
- package/dist/cli/commands/modes.js.map +1 -0
- package/dist/cli/commands/operating-plane.d.ts +14 -0
- package/dist/cli/commands/operating-plane.d.ts.map +1 -0
- package/dist/cli/commands/operating-plane.js +160 -0
- package/dist/cli/commands/operating-plane.js.map +1 -0
- package/dist/cli/commands/run.d.ts +87 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +356 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/scenario.d.ts +7 -0
- package/dist/cli/commands/scenario.d.ts.map +1 -0
- package/dist/cli/commands/scenario.js +195 -0
- package/dist/cli/commands/scenario.js.map +1 -0
- package/dist/cli/commands/skill.d.ts +7 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +286 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/headless-protocol.d.ts +55 -1
- package/dist/cli/headless-protocol.d.ts.map +1 -1
- package/dist/cli/headless-protocol.js +446 -7
- package/dist/cli/headless-protocol.js.map +1 -1
- package/dist/cli/headless-runtime-selection.d.ts +38 -0
- package/dist/cli/headless-runtime-selection.d.ts.map +1 -0
- package/dist/cli/headless-runtime-selection.js +48 -0
- package/dist/cli/headless-runtime-selection.js.map +1 -0
- package/dist/cli/headless.d.ts +5 -1
- package/dist/cli/headless.d.ts.map +1 -1
- package/dist/cli/headless.js +11 -1
- package/dist/cli/headless.js.map +1 -1
- package/dist/cli/help.d.ts +3 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +135 -30
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/system-prompt.d.ts +22 -4
- package/dist/cli/system-prompt.d.ts.map +1 -1
- package/dist/cli/system-prompt.js +224 -127
- package/dist/cli/system-prompt.js.map +1 -1
- package/dist/cli-tui/commands/a2a-handlers.d.ts +7 -0
- package/dist/cli-tui/commands/a2a-handlers.d.ts.map +1 -0
- package/dist/cli-tui/commands/a2a-handlers.js +160 -0
- package/dist/cli-tui/commands/a2a-handlers.js.map +1 -0
- package/dist/cli-tui/commands/command-catalog.d.ts.map +1 -1
- package/dist/cli-tui/commands/command-catalog.js +15 -0
- package/dist/cli-tui/commands/command-catalog.js.map +1 -1
- package/dist/cli-tui/commands/command-registry-adapter.js +10 -1
- package/dist/cli-tui/commands/command-registry-adapter.js.map +1 -1
- package/dist/cli-tui/commands/handlers/mode-handler.d.ts.map +1 -1
- package/dist/cli-tui/commands/handlers/mode-handler.js +22 -10
- package/dist/cli-tui/commands/handlers/mode-handler.js.map +1 -1
- package/dist/cli-tui/commands/mcp-handlers.d.ts.map +1 -1
- package/dist/cli-tui/commands/mcp-handlers.js +6 -5
- package/dist/cli-tui/commands/mcp-handlers.js.map +1 -1
- package/dist/cli-tui/commands/types.d.ts +1 -0
- package/dist/cli-tui/commands/types.d.ts.map +1 -1
- package/dist/cli-tui/commands/types.js.map +1 -1
- package/dist/cli-tui/commands/utility-handlers.d.ts +4 -0
- package/dist/cli-tui/commands/utility-handlers.d.ts.map +1 -1
- package/dist/cli-tui/commands/utility-handlers.js +45 -6
- package/dist/cli-tui/commands/utility-handlers.js.map +1 -1
- package/dist/cli-tui/run/run-shell-command.d.ts.map +1 -1
- package/dist/cli-tui/run/run-shell-command.js +14 -5
- package/dist/cli-tui/run/run-shell-command.js.map +1 -1
- package/dist/cli-tui/run/streaming-shell-command.d.ts.map +1 -1
- package/dist/cli-tui/run/streaming-shell-command.js +14 -5
- package/dist/cli-tui/run/streaming-shell-command.js.map +1 -1
- package/dist/cli-tui/selectors/model-selector.d.ts +1 -0
- package/dist/cli-tui/selectors/model-selector.d.ts.map +1 -1
- package/dist/cli-tui/selectors/model-selector.js +6 -2
- package/dist/cli-tui/selectors/model-selector.js.map +1 -1
- package/dist/cli-tui/tui-renderer/command-registry-options.d.ts.map +1 -1
- package/dist/cli-tui/tui-renderer/command-registry-options.js +5 -0
- package/dist/cli-tui/tui-renderer/command-registry-options.js.map +1 -1
- package/dist/cli-tui/utils/commands/review-prompt.d.ts +1 -1
- package/dist/cli-tui/utils/commands/review-prompt.d.ts.map +1 -1
- package/dist/cli-tui/utils/commands/review-prompt.js +8 -3
- package/dist/cli-tui/utils/commands/review-prompt.js.map +1 -1
- package/dist/cli-tui/utils/runtime-badges.d.ts +1 -0
- package/dist/cli-tui/utils/runtime-badges.d.ts.map +1 -1
- package/dist/cli-tui/utils/runtime-badges.js +7 -0
- package/dist/cli-tui/utils/runtime-badges.js.map +1 -1
- package/dist/cli-tui/utils/text-formatting.d.ts +1 -0
- package/dist/cli-tui/utils/text-formatting.d.ts.map +1 -1
- package/dist/cli-tui/utils/text-formatting.js +5 -0
- package/dist/cli-tui/utils/text-formatting.js.map +1 -1
- package/dist/cli.js +49158 -26161
- package/dist/cli.js.map +1 -1
- package/dist/codex/app-server-client.d.ts +139 -0
- package/dist/codex/app-server-client.d.ts.map +1 -0
- package/dist/codex/app-server-client.js +352 -0
- package/dist/codex/app-server-client.js.map +1 -0
- package/dist/codex/compatibility.d.ts +48 -0
- package/dist/codex/compatibility.d.ts.map +1 -0
- package/dist/codex/compatibility.js +344 -0
- package/dist/codex/compatibility.js.map +1 -0
- package/dist/codex/subagent-dispatch-table.d.ts +66 -0
- package/dist/codex/subagent-dispatch-table.d.ts.map +1 -0
- package/dist/codex/subagent-dispatch-table.js +127 -0
- package/dist/codex/subagent-dispatch-table.js.map +1 -0
- package/dist/codex/subagent-workgraph.d.ts +56 -0
- package/dist/codex/subagent-workgraph.d.ts.map +1 -0
- package/dist/codex/subagent-workgraph.js +89 -0
- package/dist/codex/subagent-workgraph.js.map +1 -0
- package/dist/config/constants.d.ts +3 -1
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +9 -0
- package/dist/config/constants.js.map +1 -1
- package/dist/config/feature-flags.d.ts +10 -1
- package/dist/config/feature-flags.d.ts.map +1 -1
- package/dist/config/feature-flags.js +17 -6
- package/dist/config/feature-flags.js.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/toml-config.d.ts +32 -0
- package/dist/config/toml-config.d.ts.map +1 -1
- package/dist/config/toml-config.js +152 -43
- package/dist/config/toml-config.js.map +1 -1
- package/dist/connectors/service-client.d.ts.map +1 -1
- package/dist/connectors/service-client.js +4 -7
- package/dist/connectors/service-client.js.map +1 -1
- package/dist/context/manifest-types.d.ts +59 -0
- package/dist/context/manifest-types.d.ts.map +1 -0
- package/dist/context/manifest-types.js +2 -0
- package/dist/context/manifest-types.js.map +1 -0
- package/dist/context/manifest.d.ts +16 -0
- package/dist/context/manifest.d.ts.map +1 -0
- package/dist/context/manifest.js +503 -0
- package/dist/context/manifest.js.map +1 -0
- package/dist/db/schema.d.ts +10 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js.map +1 -1
- package/dist/evalops/env-aliases.d.ts +13 -0
- package/dist/evalops/env-aliases.d.ts.map +1 -0
- package/dist/evalops/env-aliases.js +60 -0
- package/dist/evalops/env-aliases.js.map +1 -0
- package/dist/evalops/managed-context.d.ts.map +1 -1
- package/dist/evalops/managed-context.js +28 -62
- package/dist/evalops/managed-context.js.map +1 -1
- package/dist/guardian/config.d.ts.map +1 -1
- package/dist/guardian/config.js +1 -0
- package/dist/guardian/config.js.map +1 -1
- package/dist/guardian/runner.d.ts +2 -0
- package/dist/guardian/runner.d.ts.map +1 -1
- package/dist/guardian/runner.js +105 -2
- package/dist/guardian/runner.js.map +1 -1
- package/dist/guardian/types.d.ts +1 -0
- package/dist/guardian/types.d.ts.map +1 -1
- package/dist/guardian/types.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +267 -55
- package/dist/main.js.map +1 -1
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +89 -7
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/manager.d.ts +5 -1
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +159 -4
- package/dist/mcp/manager.js.map +1 -1
- package/dist/mcp/platform-plugin.d.ts.map +1 -1
- package/dist/mcp/platform-plugin.js +9 -26
- package/dist/mcp/platform-plugin.js.map +1 -1
- package/dist/mcp/schema.d.ts +15 -0
- package/dist/mcp/schema.d.ts.map +1 -1
- package/dist/mcp/schema.js +24 -0
- package/dist/mcp/schema.js.map +1 -1
- package/dist/mcp/tool-bridge.d.ts +39 -10
- package/dist/mcp/tool-bridge.d.ts.map +1 -1
- package/dist/mcp/tool-bridge.js +101 -24
- package/dist/mcp/tool-bridge.js.map +1 -1
- package/dist/mcp/types.d.ts +27 -0
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/mcp/types.js.map +1 -1
- package/dist/mcp/workspace-trust.d.ts +10 -0
- package/dist/mcp/workspace-trust.d.ts.map +1 -0
- package/dist/mcp/workspace-trust.js +295 -0
- package/dist/mcp/workspace-trust.js.map +1 -0
- package/dist/memory/service-client.d.ts +1 -0
- package/dist/memory/service-client.d.ts.map +1 -1
- package/dist/memory/service-client.js +194 -9
- package/dist/memory/service-client.js.map +1 -1
- package/dist/models/builtin.d.ts.map +1 -1
- package/dist/models/builtin.js +66 -25
- package/dist/models/builtin.js.map +1 -1
- package/dist/models/config-loader.d.ts +10 -10
- package/dist/models/config-loader.d.ts.map +1 -1
- package/dist/models/config-loader.js +2 -0
- package/dist/models/config-loader.js.map +1 -1
- package/dist/models/registry.d.ts +1 -0
- package/dist/models/registry.d.ts.map +1 -1
- package/dist/models/registry.js +1 -0
- package/dist/models/registry.js.map +1 -1
- package/dist/oauth/device-identity.d.ts.map +1 -1
- package/dist/oauth/device-identity.js +1 -3
- package/dist/oauth/device-identity.js.map +1 -1
- package/dist/oauth/evalops.d.ts.map +1 -1
- package/dist/oauth/evalops.js +2 -5
- package/dist/oauth/evalops.js.map +1 -1
- package/dist/opentelemetry.d.ts.map +1 -1
- package/dist/opentelemetry.js +12 -12
- package/dist/opentelemetry.js.map +1 -1
- package/dist/package-version.d.ts +2 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +11 -0
- package/dist/package-version.js.map +1 -0
- package/dist/packages/constants.d.ts +3 -0
- package/dist/packages/constants.d.ts.map +1 -0
- package/dist/packages/constants.js +3 -0
- package/dist/packages/constants.js.map +1 -0
- package/dist/packages/inspection.d.ts.map +1 -1
- package/dist/packages/inspection.js +2 -1
- package/dist/packages/inspection.js.map +1 -1
- package/dist/packages/search.d.ts.map +1 -1
- package/dist/packages/search.js +1 -1
- package/dist/packages/search.js.map +1 -1
- package/dist/platform/a2a-capability-market.d.ts +21 -0
- package/dist/platform/a2a-capability-market.d.ts.map +1 -0
- package/dist/platform/a2a-capability-market.js +176 -0
- package/dist/platform/a2a-capability-market.js.map +1 -0
- package/dist/platform/a2a-client.d.ts +119 -0
- package/dist/platform/a2a-client.d.ts.map +1 -1
- package/dist/platform/a2a-client.js +413 -24
- package/dist/platform/a2a-client.js.map +1 -1
- package/dist/platform/a2a-fleet.d.ts +41 -0
- package/dist/platform/a2a-fleet.d.ts.map +1 -0
- package/dist/platform/a2a-fleet.js +109 -0
- package/dist/platform/a2a-fleet.js.map +1 -0
- package/dist/platform/a2a-maestro-peer.d.ts +20 -0
- package/dist/platform/a2a-maestro-peer.d.ts.map +1 -0
- package/dist/platform/a2a-maestro-peer.js +176 -0
- package/dist/platform/a2a-maestro-peer.js.map +1 -0
- package/dist/platform/a2a-peer-pairing.d.ts +107 -0
- package/dist/platform/a2a-peer-pairing.d.ts.map +1 -0
- package/dist/platform/a2a-peer-pairing.js +489 -0
- package/dist/platform/a2a-peer-pairing.js.map +1 -0
- package/dist/platform/a2a-peer-registry.d.ts +68 -0
- package/dist/platform/a2a-peer-registry.d.ts.map +1 -0
- package/dist/platform/a2a-peer-registry.js +320 -0
- package/dist/platform/a2a-peer-registry.js.map +1 -0
- package/dist/platform/a2a-task-ledger.d.ts +86 -0
- package/dist/platform/a2a-task-ledger.d.ts.map +1 -0
- package/dist/platform/a2a-task-ledger.js +546 -0
- package/dist/platform/a2a-task-ledger.js.map +1 -0
- package/dist/platform/a2a-work-graph.d.ts +43 -0
- package/dist/platform/a2a-work-graph.d.ts.map +1 -0
- package/dist/platform/a2a-work-graph.js +267 -0
- package/dist/platform/a2a-work-graph.js.map +1 -0
- package/dist/platform/agent-registry-client.d.ts +327 -0
- package/dist/platform/agent-registry-client.d.ts.map +1 -0
- package/dist/platform/agent-registry-client.js +803 -0
- package/dist/platform/agent-registry-client.js.map +1 -0
- package/dist/platform/agent-runtime-client.d.ts +135 -1
- package/dist/platform/agent-runtime-client.d.ts.map +1 -1
- package/dist/platform/agent-runtime-client.js +467 -10
- package/dist/platform/agent-runtime-client.js.map +1 -1
- package/dist/platform/cerebro-facts-client.d.ts.map +1 -1
- package/dist/platform/cerebro-facts-client.js +4 -7
- package/dist/platform/cerebro-facts-client.js.map +1 -1
- package/dist/platform/client.d.ts.map +1 -1
- package/dist/platform/client.js +3 -12
- package/dist/platform/client.js.map +1 -1
- package/dist/platform/core-services.d.ts +68 -0
- package/dist/platform/core-services.d.ts.map +1 -1
- package/dist/platform/core-services.js +68 -0
- package/dist/platform/core-services.js.map +1 -1
- package/dist/platform/fermata-eval-client.d.ts +195 -0
- package/dist/platform/fermata-eval-client.d.ts.map +1 -0
- package/dist/platform/fermata-eval-client.js +146 -0
- package/dist/platform/fermata-eval-client.js.map +1 -0
- package/dist/platform/fermata-scenario-suite.d.ts +99 -0
- package/dist/platform/fermata-scenario-suite.d.ts.map +1 -0
- package/dist/platform/fermata-scenario-suite.js +459 -0
- package/dist/platform/fermata-scenario-suite.js.map +1 -0
- package/dist/platform/maestro-timeline-client.d.ts.map +1 -1
- package/dist/platform/maestro-timeline-client.js +5 -11
- package/dist/platform/maestro-timeline-client.js.map +1 -1
- package/dist/platform/operating-plane-client.d.ts +156 -0
- package/dist/platform/operating-plane-client.d.ts.map +1 -0
- package/dist/platform/operating-plane-client.js +131 -0
- package/dist/platform/operating-plane-client.js.map +1 -0
- package/dist/platform/operating-plane-summary.d.ts +47 -0
- package/dist/platform/operating-plane-summary.d.ts.map +1 -0
- package/dist/platform/operating-plane-summary.js +209 -0
- package/dist/platform/operating-plane-summary.js.map +1 -0
- package/dist/platform/tool-execution-client.d.ts.map +1 -1
- package/dist/platform/tool-execution-client.js +4 -11
- package/dist/platform/tool-execution-client.js.map +1 -1
- package/dist/prompts/service-client.d.ts.map +1 -1
- package/dist/prompts/service-client.js +3 -5
- package/dist/prompts/service-client.js.map +1 -1
- package/dist/prompts/system-prompt.d.ts +3 -0
- package/dist/prompts/system-prompt.d.ts.map +1 -1
- package/dist/prompts/system-prompt.js +13 -3
- package/dist/prompts/system-prompt.js.map +1 -1
- package/dist/prompts/types.d.ts +2 -0
- package/dist/prompts/types.d.ts.map +1 -1
- package/dist/prompts/types.js.map +1 -1
- package/dist/providers/api-keys.d.ts +1 -1
- package/dist/providers/api-keys.d.ts.map +1 -1
- package/dist/providers/api-keys.js +2 -1
- package/dist/providers/api-keys.js.map +1 -1
- package/dist/providers/auth.d.ts.map +1 -1
- package/dist/providers/auth.js +48 -25
- package/dist/providers/auth.js.map +1 -1
- package/dist/remote-runner/attach-client.d.ts.map +1 -1
- package/dist/remote-runner/attach-client.js +1 -0
- package/dist/remote-runner/attach-client.js.map +1 -1
- package/dist/remote-runner/client.d.ts.map +1 -1
- package/dist/remote-runner/client.js +4 -7
- package/dist/remote-runner/client.js.map +1 -1
- package/dist/rpc/rpc-types.d.ts.map +1 -1
- package/dist/rpc/rpc-types.js +1 -0
- package/dist/rpc/rpc-types.js.map +1 -1
- package/dist/safety/action-firewall.d.ts.map +1 -1
- package/dist/safety/action-firewall.js +69 -6
- package/dist/safety/action-firewall.js.map +1 -1
- package/dist/safety/attack-patterns.d.ts.map +1 -1
- package/dist/safety/attack-patterns.js +31 -14
- package/dist/safety/attack-patterns.js.map +1 -1
- package/dist/safety/bash-parser.d.ts.map +1 -1
- package/dist/safety/bash-parser.js +4 -3
- package/dist/safety/bash-parser.js.map +1 -1
- package/dist/safety/execpolicy.d.ts +15 -3
- package/dist/safety/execpolicy.d.ts.map +1 -1
- package/dist/safety/execpolicy.js +248 -37
- package/dist/safety/execpolicy.js.map +1 -1
- package/dist/safety/governance-service-client.d.ts.map +1 -1
- package/dist/safety/governance-service-client.js +4 -7
- package/dist/safety/governance-service-client.js.map +1 -1
- package/dist/safety/guarded-files.d.ts +34 -0
- package/dist/safety/guarded-files.d.ts.map +1 -0
- package/dist/safety/guarded-files.js +372 -0
- package/dist/safety/guarded-files.js.map +1 -0
- package/dist/safety/loop-detector.d.ts.map +1 -1
- package/dist/safety/loop-detector.js +6 -1
- package/dist/safety/loop-detector.js.map +1 -1
- package/dist/safety/permission-profile.d.ts +47 -0
- package/dist/safety/permission-profile.d.ts.map +1 -0
- package/dist/safety/permission-profile.js +349 -0
- package/dist/safety/permission-profile.js.map +1 -0
- package/dist/safety/safety-middleware.d.ts +5 -1
- package/dist/safety/safety-middleware.d.ts.map +1 -1
- package/dist/safety/safety-middleware.js +3 -2
- package/dist/safety/safety-middleware.js.map +1 -1
- package/dist/safety/suspicious-patterns.d.ts.map +1 -1
- package/dist/safety/suspicious-patterns.js +12 -7
- package/dist/safety/suspicious-patterns.js.map +1 -1
- package/dist/safety/tool-categorization.js +1 -1
- package/dist/safety/tool-categorization.js.map +1 -1
- package/dist/safety/validators/path-policy-validator.d.ts.map +1 -1
- package/dist/safety/validators/path-policy-validator.js +7 -0
- package/dist/safety/validators/path-policy-validator.js.map +1 -1
- package/dist/sandbox/index.d.ts +6 -1
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +30 -4
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/native-sandbox.d.ts +3 -0
- package/dist/sandbox/native-sandbox.d.ts.map +1 -1
- package/dist/sandbox/native-sandbox.js +139 -18
- package/dist/sandbox/native-sandbox.js.map +1 -1
- package/dist/sentry.d.ts +17 -0
- package/dist/sentry.d.ts.map +1 -0
- package/dist/sentry.js +91 -0
- package/dist/sentry.js.map +1 -0
- package/dist/server/agent-runtime-ledger.d.ts +141 -0
- package/dist/server/agent-runtime-ledger.d.ts.map +1 -0
- package/dist/server/agent-runtime-ledger.js +334 -0
- package/dist/server/agent-runtime-ledger.js.map +1 -0
- package/dist/server/agent-trajectory-inspection.d.ts +104 -0
- package/dist/server/agent-trajectory-inspection.d.ts.map +1 -0
- package/dist/server/agent-trajectory-inspection.js +168 -0
- package/dist/server/agent-trajectory-inspection.js.map +1 -0
- package/dist/server/agent-trajectory-replay.d.ts +56 -0
- package/dist/server/agent-trajectory-replay.d.ts.map +1 -0
- package/dist/server/agent-trajectory-replay.js +214 -0
- package/dist/server/agent-trajectory-replay.js.map +1 -0
- package/dist/server/agent-trajectory-scenarios.d.ts +109 -0
- package/dist/server/agent-trajectory-scenarios.d.ts.map +1 -0
- package/dist/server/agent-trajectory-scenarios.js +822 -0
- package/dist/server/agent-trajectory-scenarios.js.map +1 -0
- package/dist/server/agent-trajectory-scorers.d.ts +61 -0
- package/dist/server/agent-trajectory-scorers.d.ts.map +1 -0
- package/dist/server/agent-trajectory-scorers.js +162 -0
- package/dist/server/agent-trajectory-scorers.js.map +1 -0
- package/dist/server/agent-trajectory-validation.d.ts +7 -0
- package/dist/server/agent-trajectory-validation.d.ts.map +1 -0
- package/dist/server/agent-trajectory-validation.js +101 -0
- package/dist/server/agent-trajectory-validation.js.map +1 -0
- package/dist/server/agent-trajectory.d.ts +50 -0
- package/dist/server/agent-trajectory.d.ts.map +1 -0
- package/dist/server/agent-trajectory.js +159 -0
- package/dist/server/agent-trajectory.js.map +1 -0
- package/dist/server/app-context.d.ts +18 -0
- package/dist/server/app-context.d.ts.map +1 -1
- package/dist/server/app-context.js.map +1 -1
- package/dist/server/handlers/headless-sessions.d.ts.map +1 -1
- package/dist/server/handlers/headless-sessions.js +64 -27
- package/dist/server/handlers/headless-sessions.js.map +1 -1
- package/dist/server/handlers/health.d.ts +6 -0
- package/dist/server/handlers/health.d.ts.map +1 -1
- package/dist/server/handlers/health.js +6 -0
- package/dist/server/handlers/health.js.map +1 -1
- package/dist/server/handlers/hosted-runner-drain.d.ts +69 -1
- package/dist/server/handlers/hosted-runner-drain.d.ts.map +1 -1
- package/dist/server/handlers/hosted-runner-drain.js +309 -18
- package/dist/server/handlers/hosted-runner-drain.js.map +1 -1
- package/dist/server/handlers/hosted-runner-identity.d.ts +16 -0
- package/dist/server/handlers/hosted-runner-identity.d.ts.map +1 -1
- package/dist/server/handlers/hosted-runner-identity.js +43 -0
- package/dist/server/handlers/hosted-runner-identity.js.map +1 -1
- package/dist/server/handlers/mode.d.ts.map +1 -1
- package/dist/server/handlers/mode.js +3 -1
- package/dist/server/handlers/mode.js.map +1 -1
- package/dist/server/handlers/pending-requests.d.ts.map +1 -1
- package/dist/server/handlers/pending-requests.js +336 -51
- package/dist/server/handlers/pending-requests.js.map +1 -1
- package/dist/server/handlers/platform-a2a-push.d.ts +6 -0
- package/dist/server/handlers/platform-a2a-push.d.ts.map +1 -0
- package/dist/server/handlers/platform-a2a-push.js +136 -0
- package/dist/server/handlers/platform-a2a-push.js.map +1 -0
- package/dist/server/handlers/sessions.d.ts.map +1 -1
- package/dist/server/handlers/sessions.js +21 -1
- package/dist/server/handlers/sessions.js.map +1 -1
- package/dist/server/headless-runtime-service.d.ts +9 -2
- package/dist/server/headless-runtime-service.d.ts.map +1 -1
- package/dist/server/headless-runtime-service.js +39 -0
- package/dist/server/headless-runtime-service.js.map +1 -1
- package/dist/server/hosted-agent-runtime-progress.d.ts +144 -0
- package/dist/server/hosted-agent-runtime-progress.d.ts.map +1 -0
- package/dist/server/hosted-agent-runtime-progress.js +1650 -0
- package/dist/server/hosted-agent-runtime-progress.js.map +1 -0
- package/dist/server/hosted-runner-lease.d.ts +41 -0
- package/dist/server/hosted-runner-lease.d.ts.map +1 -0
- package/dist/server/hosted-runner-lease.js +140 -0
- package/dist/server/hosted-runner-lease.js.map +1 -0
- package/dist/server/hosted-session-manager.d.ts +16 -8
- package/dist/server/hosted-session-manager.d.ts.map +1 -1
- package/dist/server/hosted-session-manager.js +98 -76
- package/dist/server/hosted-session-manager.js.map +1 -1
- package/dist/server/junit-xml.d.ts +2 -0
- package/dist/server/junit-xml.d.ts.map +1 -0
- package/dist/server/junit-xml.js +9 -0
- package/dist/server/junit-xml.js.map +1 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +6 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/server/scenario-recorder.d.ts +56 -0
- package/dist/server/scenario-recorder.d.ts.map +1 -0
- package/dist/server/scenario-recorder.js +109 -0
- package/dist/server/scenario-recorder.js.map +1 -0
- package/dist/server/scripted-scenario-runner.d.ts +46 -0
- package/dist/server/scripted-scenario-runner.d.ts.map +1 -0
- package/dist/server/scripted-scenario-runner.js +190 -0
- package/dist/server/scripted-scenario-runner.js.map +1 -0
- package/dist/server/server-middlewares.d.ts +6 -2
- package/dist/server/server-middlewares.d.ts.map +1 -1
- package/dist/server/server-middlewares.js +8 -2
- package/dist/server/server-middlewares.js.map +1 -1
- package/dist/server/server-request-manager.d.ts +9 -1
- package/dist/server/server-request-manager.d.ts.map +1 -1
- package/dist/server/server-request-manager.js +49 -4
- package/dist/server/server-request-manager.js.map +1 -1
- package/dist/services/intelligent-router/service.d.ts +2 -0
- package/dist/services/intelligent-router/service.d.ts.map +1 -1
- package/dist/services/intelligent-router/service.js +4 -0
- package/dist/services/intelligent-router/service.js.map +1 -1
- package/dist/services/service-authority.d.ts +25 -0
- package/dist/services/service-authority.d.ts.map +1 -0
- package/dist/services/service-authority.js +143 -0
- package/dist/services/service-authority.js.map +1 -0
- package/dist/services/workspace-config/service.d.ts +2 -0
- package/dist/services/workspace-config/service.d.ts.map +1 -1
- package/dist/services/workspace-config/service.js +4 -0
- package/dist/services/workspace-config/service.js.map +1 -1
- package/dist/session/manager.d.ts +8 -2
- package/dist/session/manager.d.ts.map +1 -1
- package/dist/session/manager.js +19 -4
- package/dist/session/manager.js.map +1 -1
- package/dist/session/session-branch.d.ts.map +1 -1
- package/dist/session/session-branch.js +5 -1
- package/dist/session/session-branch.js.map +1 -1
- package/dist/session/session-catalog.d.ts +7 -2
- package/dist/session/session-catalog.d.ts.map +1 -1
- package/dist/session/session-catalog.js +13 -2
- package/dist/session/session-catalog.js.map +1 -1
- package/dist/session/session-context.d.ts +6 -2
- package/dist/session/session-context.d.ts.map +1 -1
- package/dist/session/session-context.js +44 -4
- package/dist/session/session-context.js.map +1 -1
- package/dist/session/session-graph-projection.d.ts +32 -0
- package/dist/session/session-graph-projection.d.ts.map +1 -0
- package/dist/session/session-graph-projection.js +133 -0
- package/dist/session/session-graph-projection.js.map +1 -0
- package/dist/session/types.d.ts +18 -0
- package/dist/session/types.d.ts.map +1 -1
- package/dist/session/types.js +8 -0
- package/dist/session/types.js.map +1 -1
- package/dist/session/wire-format.generated.d.ts +3 -0
- package/dist/session/wire-format.generated.d.ts.map +1 -1
- package/dist/session/wire-format.generated.js +20 -0
- package/dist/session/wire-format.generated.js.map +1 -1
- package/dist/skills/eval-harness.d.ts +38 -0
- package/dist/skills/eval-harness.d.ts.map +1 -0
- package/dist/skills/eval-harness.js +112 -0
- package/dist/skills/eval-harness.js.map +1 -0
- package/dist/skills/index.d.ts +5 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +5 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/linter.d.ts +36 -0
- package/dist/skills/linter.d.ts.map +1 -0
- package/dist/skills/linter.js +398 -0
- package/dist/skills/linter.js.map +1 -0
- package/dist/skills/loader.d.ts +36 -6
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +169 -86
- package/dist/skills/loader.js.map +1 -1
- package/dist/skills/package-contract.d.ts +45 -0
- package/dist/skills/package-contract.d.ts.map +1 -0
- package/dist/skills/package-contract.js +153 -0
- package/dist/skills/package-contract.js.map +1 -0
- package/dist/skills/runtime-activation.d.ts +68 -0
- package/dist/skills/runtime-activation.d.ts.map +1 -0
- package/dist/skills/runtime-activation.js +228 -0
- package/dist/skills/runtime-activation.js.map +1 -0
- package/dist/skills/service-client.d.ts.map +1 -1
- package/dist/skills/service-client.js +3 -4
- package/dist/skills/service-client.js.map +1 -1
- package/dist/skills/tool.d.ts.map +1 -1
- package/dist/skills/tool.js +2 -0
- package/dist/skills/tool.js.map +1 -1
- package/dist/skills/types.d.ts +14 -0
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/skills/types.js.map +1 -1
- package/dist/telemetry/agent-operating-plane-context.d.ts +24 -0
- package/dist/telemetry/agent-operating-plane-context.d.ts.map +1 -0
- package/dist/telemetry/agent-operating-plane-context.js +54 -0
- package/dist/telemetry/agent-operating-plane-context.js.map +1 -0
- package/dist/telemetry/beacon.d.ts +24 -0
- package/dist/telemetry/beacon.d.ts.map +1 -0
- package/dist/telemetry/beacon.js +115 -0
- package/dist/telemetry/beacon.js.map +1 -0
- package/dist/telemetry/cli-command-aggregator.d.ts +36 -0
- package/dist/telemetry/cli-command-aggregator.d.ts.map +1 -0
- package/dist/telemetry/cli-command-aggregator.js +251 -0
- package/dist/telemetry/cli-command-aggregator.js.map +1 -0
- package/dist/telemetry/cli-startup.d.ts +21 -0
- package/dist/telemetry/cli-startup.d.ts.map +1 -0
- package/dist/telemetry/cli-startup.js +83 -0
- package/dist/telemetry/cli-startup.js.map +1 -0
- package/dist/telemetry/disablement.d.ts +13 -0
- package/dist/telemetry/disablement.d.ts.map +1 -0
- package/dist/telemetry/disablement.js +19 -0
- package/dist/telemetry/disablement.js.map +1 -0
- package/dist/telemetry/index.d.ts +6 -2
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/index.js +6 -2
- package/dist/telemetry/index.js.map +1 -1
- package/dist/telemetry/maestro-event-bus.d.ts +52 -0
- package/dist/telemetry/maestro-event-bus.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-bus.js +179 -3
- package/dist/telemetry/maestro-event-bus.js.map +1 -1
- package/dist/telemetry/maestro-event-catalog.d.ts +3 -1
- package/dist/telemetry/maestro-event-catalog.d.ts.map +1 -1
- package/dist/telemetry/maestro-event-catalog.js +2 -0
- package/dist/telemetry/maestro-event-catalog.js.map +1 -1
- package/dist/telemetry/maestro-platform-replay-fixture.d.ts.map +1 -1
- package/dist/telemetry/maestro-platform-replay-fixture.js +74 -9
- package/dist/telemetry/maestro-platform-replay-fixture.js.map +1 -1
- package/dist/telemetry/maestro-publisher-conformance-fixture.d.ts +1 -1
- package/dist/telemetry/maestro-publisher-conformance-fixture.d.ts.map +1 -1
- package/dist/telemetry/maestro-publisher-conformance-fixture.js +46 -11
- package/dist/telemetry/maestro-publisher-conformance-fixture.js.map +1 -1
- package/dist/telemetry/mcp-beacon.d.ts +20 -0
- package/dist/telemetry/mcp-beacon.d.ts.map +1 -0
- package/dist/telemetry/mcp-beacon.js +54 -0
- package/dist/telemetry/mcp-beacon.js.map +1 -0
- package/dist/telemetry/metadata-normalization.d.ts +7 -0
- package/dist/telemetry/metadata-normalization.d.ts.map +1 -0
- package/dist/telemetry/metadata-normalization.js +189 -0
- package/dist/telemetry/metadata-normalization.js.map +1 -0
- package/dist/telemetry/meter-service-client.d.ts.map +1 -1
- package/dist/telemetry/meter-service-client.js +5 -10
- package/dist/telemetry/meter-service-client.js.map +1 -1
- package/dist/telemetry/metrics.d.ts +123 -0
- package/dist/telemetry/metrics.d.ts.map +1 -0
- package/dist/telemetry/metrics.js +184 -0
- package/dist/telemetry/metrics.js.map +1 -0
- package/dist/telemetry/turn-tracker.d.ts +1 -0
- package/dist/telemetry/turn-tracker.d.ts.map +1 -1
- package/dist/telemetry/turn-tracker.js +22 -1
- package/dist/telemetry/turn-tracker.js.map +1 -1
- package/dist/telemetry/wide-events.d.ts +31 -1
- package/dist/telemetry/wide-events.d.ts.map +1 -1
- package/dist/telemetry/wide-events.js +229 -1
- package/dist/telemetry/wide-events.js.map +1 -1
- package/dist/telemetry.d.ts +39 -3
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +160 -3
- package/dist/telemetry.js.map +1 -1
- package/dist/testing/test-verification-hook.d.ts.map +1 -1
- package/dist/testing/test-verification-hook.js +34 -21
- package/dist/testing/test-verification-hook.js.map +1 -1
- package/dist/tools/apply-patch-parser.d.ts +26 -0
- package/dist/tools/apply-patch-parser.d.ts.map +1 -0
- package/dist/tools/apply-patch-parser.js +146 -0
- package/dist/tools/apply-patch-parser.js.map +1 -0
- package/dist/tools/apply-patch.d.ts +42 -0
- package/dist/tools/apply-patch.d.ts.map +1 -0
- package/dist/tools/apply-patch.js +648 -0
- package/dist/tools/apply-patch.js.map +1 -0
- package/dist/tools/ask-user.d.ts +1 -0
- package/dist/tools/ask-user.d.ts.map +1 -1
- package/dist/tools/background/tool-handler.d.ts +1 -0
- package/dist/tools/background/tool-handler.d.ts.map +1 -1
- package/dist/tools/bash.d.ts +1 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/codesearch.d.ts +1 -0
- package/dist/tools/codesearch.d.ts.map +1 -1
- package/dist/tools/conductor-client.d.ts +1 -0
- package/dist/tools/conductor-client.d.ts.map +1 -1
- package/dist/tools/conductor-client.js +63 -0
- package/dist/tools/conductor-client.js.map +1 -1
- package/dist/tools/diff.d.ts +1 -0
- package/dist/tools/diff.d.ts.map +1 -1
- package/dist/tools/edit.d.ts +1 -0
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/extract-document.d.ts +1 -0
- package/dist/tools/extract-document.d.ts.map +1 -1
- package/dist/tools/find.d.ts +10 -0
- package/dist/tools/find.d.ts.map +1 -1
- package/dist/tools/find.js +236 -27
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/gh.d.ts +3 -0
- package/dist/tools/gh.d.ts.map +1 -1
- package/dist/tools/index.d.ts +50 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/list.d.ts +1 -0
- package/dist/tools/list.d.ts.map +1 -1
- package/dist/tools/notebook.d.ts +1 -0
- package/dist/tools/notebook.d.ts.map +1 -1
- package/dist/tools/oracle.d.ts +1 -0
- package/dist/tools/oracle.d.ts.map +1 -1
- package/dist/tools/oracle.js +17 -32
- package/dist/tools/oracle.js.map +1 -1
- package/dist/tools/parallel-execution.d.ts +13 -2
- package/dist/tools/parallel-execution.d.ts.map +1 -1
- package/dist/tools/parallel-execution.js +178 -7
- package/dist/tools/parallel-execution.js.map +1 -1
- package/dist/tools/parallel-ripgrep.d.ts +1 -0
- package/dist/tools/parallel-ripgrep.d.ts.map +1 -1
- package/dist/tools/pipeline.d.ts +4 -0
- package/dist/tools/pipeline.d.ts.map +1 -1
- package/dist/tools/read.d.ts +1 -0
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/search.d.ts +1 -0
- package/dist/tools/search.d.ts.map +1 -1
- package/dist/tools/status.d.ts +1 -0
- package/dist/tools/status.d.ts.map +1 -1
- package/dist/tools/todo.d.ts +1 -0
- package/dist/tools/todo.d.ts.map +1 -1
- package/dist/tools/tool-dsl.d.ts +5 -1
- package/dist/tools/tool-dsl.d.ts.map +1 -1
- package/dist/tools/tool-dsl.js +1 -0
- package/dist/tools/tool-dsl.js.map +1 -1
- package/dist/tools/tool-result-cache.d.ts.map +1 -1
- package/dist/tools/tool-result-cache.js +1 -0
- package/dist/tools/tool-result-cache.js.map +1 -1
- package/dist/tools/typebox-tool.d.ts.map +1 -1
- package/dist/tools/typebox-tool.js +3 -0
- package/dist/tools/typebox-tool.js.map +1 -1
- package/dist/tools/webfetch.d.ts +1 -0
- package/dist/tools/webfetch.d.ts.map +1 -1
- package/dist/tools/websearch.d.ts +1 -0
- package/dist/tools/websearch.d.ts.map +1 -1
- package/dist/tools/write.d.ts +1 -0
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/utils/abort-error.d.ts +2 -0
- package/dist/utils/abort-error.d.ts.map +1 -0
- package/dist/utils/abort-error.js +7 -0
- package/dist/utils/abort-error.js.map +1 -0
- package/dist/utils/downstream.d.ts.map +1 -1
- package/dist/utils/downstream.js +4 -0
- package/dist/utils/downstream.js.map +1 -1
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +14 -3
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/path-containment.d.ts +2 -0
- package/dist/utils/path-containment.d.ts.map +1 -0
- package/dist/utils/path-containment.js +14 -0
- package/dist/utils/path-containment.js.map +1 -0
- package/dist/utils/prompt-safe-text.d.ts +7 -0
- package/dist/utils/prompt-safe-text.d.ts.map +1 -0
- package/dist/utils/prompt-safe-text.js +44 -0
- package/dist/utils/prompt-safe-text.js.map +1 -0
- package/dist/version.json +2 -2
- package/dist/web-server.d.ts.map +1 -1
- package/dist/web-server.js +32 -7
- package/dist/web-server.js.map +1 -1
- package/dist/workspace/root-resolver.d.ts +4 -1
- package/dist/workspace/root-resolver.d.ts.map +1 -1
- package/dist/workspace/root-resolver.js +16 -6
- package/dist/workspace/root-resolver.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/advisor-effort.d.ts +8 -0
- package/node_modules/@evalops/contracts/dist/advisor-effort.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/advisor-effort.js +35 -0
- package/node_modules/@evalops/contracts/dist/advisor-effort.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/delegation-prompt.d.ts +10 -0
- package/node_modules/@evalops/contracts/dist/delegation-prompt.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/delegation-prompt.js +48 -0
- package/node_modules/@evalops/contracts/dist/delegation-prompt.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/guarded-files-settings.d.ts +20 -0
- package/node_modules/@evalops/contracts/dist/guarded-files-settings.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/guarded-files-settings.js +147 -0
- package/node_modules/@evalops/contracts/dist/guarded-files-settings.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/headless-protocol-generated.d.ts +2 -0
- package/node_modules/@evalops/contracts/dist/headless-protocol-generated.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/headless-protocol-generated.js +1 -0
- package/node_modules/@evalops/contracts/dist/headless-protocol-generated.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts +280 -5
- package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.js +36 -1
- package/node_modules/@evalops/contracts/dist/headless-protocol-schemas.generated.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/index.d.ts +15 -1
- package/node_modules/@evalops/contracts/dist/index.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/index.js +6 -0
- package/node_modules/@evalops/contracts/dist/index.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts +593 -0
- package/node_modules/@evalops/contracts/dist/maestro-app-server.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/maestro-app-server.js +218 -0
- package/node_modules/@evalops/contracts/dist/maestro-app-server.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.d.ts +91 -0
- package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.js +92 -61
- package/node_modules/@evalops/contracts/dist/proto/maestro/v1/headless_pb.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts +3 -0
- package/node_modules/@evalops/contracts/dist/runtime-app-server.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/runtime-constraints.d.ts +28 -0
- package/node_modules/@evalops/contracts/dist/runtime-constraints.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/runtime-constraints.js +71 -0
- package/node_modules/@evalops/contracts/dist/runtime-constraints.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts +7 -0
- package/node_modules/@evalops/contracts/dist/runtime-server-request.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/runtime-server-request.js +2 -0
- package/node_modules/@evalops/contracts/dist/runtime-server-request.js.map +1 -1
- package/node_modules/@evalops/contracts/dist/scenario.d.ts +191 -0
- package/node_modules/@evalops/contracts/dist/scenario.d.ts.map +1 -0
- package/node_modules/@evalops/contracts/dist/scenario.js +4 -0
- package/node_modules/@evalops/contracts/dist/scenario.js.map +1 -0
- package/node_modules/@evalops/contracts/dist/schemas.d.ts +17 -3
- package/node_modules/@evalops/contracts/dist/schemas.d.ts.map +1 -1
- package/node_modules/@evalops/contracts/dist/schemas.js +16 -0
- package/node_modules/@evalops/contracts/dist/schemas.js.map +1 -1
- package/node_modules/@evalops/contracts/package.json +1 -1
- package/node_modules/@evalops/tui/package.json +1 -1
- package/package.json +41 -7
- package/skills/incident-triage/SKILL.md +40 -0
- package/skills/incident-triage/mcp.json +14 -0
- package/skills/incident-triage/reference/triage.md +20 -0
- package/skills/incident-triage/toolbox/incident-timeline +22 -0
- package/skills/incident-triage/toolbox/incident-timeline.cmd +16 -0
- package/skills/pr-review/SKILL.md +40 -0
- package/skills/pr-review/mcp.json +14 -0
- package/skills/pr-review/reference/rubric.md +20 -0
- package/skills/pr-review/toolbox/review-summary +20 -0
- package/skills/pr-review/toolbox/review-summary.cmd +14 -0
- package/skills/release-verification/SKILL.md +40 -0
- package/skills/release-verification/mcp.json +15 -0
- package/skills/release-verification/reference/checklist.md +21 -0
- package/skills/release-verification/toolbox/release-readiness +18 -0
- package/skills/release-verification/toolbox/release-readiness.cmd +12 -0
package/dist/agent/transport.js
CHANGED
|
@@ -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 {
|
|
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 {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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
|
|
620
|
-
|
|
621
|
-
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
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
|
-
|
|
679
|
-
const
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
2284
|
+
const trackedExecutionPromise = canReuseToolResult && reusableToolResultKey
|
|
2285
|
+
? trackReusableToolResult(reusableToolResultKey, executionPromise, reusableToolResults, pendingReusableToolResults, policyCheckedReusableToolResultKeys, reusableToolResultCacheGeneration)
|
|
2286
|
+
: executionPromise;
|
|
2287
|
+
const pendingExecution = {
|
|
743
2288
|
toolCall,
|
|
744
|
-
promise:
|
|
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
|
|
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) {
|