open-multi-agent-kit 0.98.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +4 -3
- package/dist/bun/cli.d.ts.map +1 -1
- package/dist/bun/cli.js +1 -0
- package/dist/bun/cli.js.map +1 -1
- package/dist/bun/register-bundled-coding-agent.d.ts +10 -0
- package/dist/bun/register-bundled-coding-agent.d.ts.map +1 -0
- package/dist/bun/register-bundled-coding-agent.js +12 -0
- package/dist/bun/register-bundled-coding-agent.js.map +1 -0
- package/dist/cli/args.d.ts +1 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +1 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +2 -1
- package/dist/cli/help.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/neo-cli.d.ts +9 -0
- package/dist/commands/neo-cli.d.ts.map +1 -0
- package/dist/commands/neo-cli.js +61 -0
- package/dist/commands/neo-cli.js.map +1 -0
- package/dist/commands/verified-run-cli.d.ts.map +1 -1
- package/dist/commands/verified-run-cli.js +2 -2
- package/dist/commands/verified-run-cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +29 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +126 -32
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bundled-skills.d.ts +4 -0
- package/dist/core/bundled-skills.d.ts.map +1 -0
- package/dist/core/bundled-skills.js +32 -0
- package/dist/core/bundled-skills.js.map +1 -0
- package/dist/core/cli-diagnostics.d.ts +6 -0
- package/dist/core/cli-diagnostics.d.ts.map +1 -0
- package/dist/core/cli-diagnostics.js +20 -0
- package/dist/core/cli-diagnostics.js.map +1 -0
- package/dist/core/context-budget-headroom.d.ts +12 -0
- package/dist/core/context-budget-headroom.d.ts.map +1 -1
- package/dist/core/context-budget-headroom.js +35 -0
- package/dist/core/context-budget-headroom.js.map +1 -1
- package/dist/core/context-budget-v2-input-validation.d.ts +4 -0
- package/dist/core/context-budget-v2-input-validation.d.ts.map +1 -0
- package/dist/core/context-budget-v2-input-validation.js +79 -0
- package/dist/core/context-budget-v2-input-validation.js.map +1 -0
- package/dist/core/context-budget-v2-observability.d.ts +15 -0
- package/dist/core/context-budget-v2-observability.d.ts.map +1 -0
- package/dist/core/context-budget-v2-observability.js +35 -0
- package/dist/core/context-budget-v2-observability.js.map +1 -0
- package/dist/core/context-budget-v2-planned-items.d.ts +5 -0
- package/dist/core/context-budget-v2-planned-items.d.ts.map +1 -0
- package/dist/core/context-budget-v2-planned-items.js +40 -0
- package/dist/core/context-budget-v2-planned-items.js.map +1 -0
- package/dist/core/context-budget-v2-planner.d.ts.map +1 -1
- package/dist/core/context-budget-v2-planner.js +57 -38
- package/dist/core/context-budget-v2-planner.js.map +1 -1
- package/dist/core/context-budget-v2-selection.d.ts +19 -3
- package/dist/core/context-budget-v2-selection.d.ts.map +1 -1
- package/dist/core/context-budget-v2-selection.js +35 -57
- package/dist/core/context-budget-v2-selection.js.map +1 -1
- package/dist/core/context-budget-v2-tiers.d.ts.map +1 -1
- package/dist/core/context-budget-v2-tiers.js +9 -42
- package/dist/core/context-budget-v2-tiers.js.map +1 -1
- package/dist/core/context-budget-v2-types.d.ts +8 -1
- package/dist/core/context-budget-v2-types.d.ts.map +1 -1
- package/dist/core/context-budget-v2-types.js.map +1 -1
- package/dist/core/devin-harness-dispatch.d.ts +12 -0
- package/dist/core/devin-harness-dispatch.d.ts.map +1 -0
- package/dist/core/devin-harness-dispatch.js +12 -0
- package/dist/core/devin-harness-dispatch.js.map +1 -0
- package/dist/core/devin-harness.d.ts +53 -0
- package/dist/core/devin-harness.d.ts.map +1 -0
- package/dist/core/devin-harness.js +112 -0
- package/dist/core/devin-harness.js.map +1 -0
- package/dist/core/domain-dispatch.d.ts +4 -1
- package/dist/core/domain-dispatch.d.ts.map +1 -1
- package/dist/core/domain-dispatch.js +5 -0
- package/dist/core/domain-dispatch.js.map +1 -1
- package/dist/core/domain-loadouts-provider-harness.d.ts +12 -0
- package/dist/core/domain-loadouts-provider-harness.d.ts.map +1 -0
- package/dist/core/domain-loadouts-provider-harness.js +122 -0
- package/dist/core/domain-loadouts-provider-harness.js.map +1 -0
- package/dist/core/domain-loadouts.d.ts +2 -33
- package/dist/core/domain-loadouts.d.ts.map +1 -1
- package/dist/core/domain-loadouts.js +3 -56
- package/dist/core/domain-loadouts.js.map +1 -1
- package/dist/core/domain-profile.d.ts +40 -0
- package/dist/core/domain-profile.d.ts.map +1 -0
- package/dist/core/domain-profile.js +7 -0
- package/dist/core/domain-profile.js.map +1 -0
- package/dist/core/extensions/bundled-virtual-modules.d.ts +15 -0
- package/dist/core/extensions/bundled-virtual-modules.d.ts.map +1 -0
- package/dist/core/extensions/bundled-virtual-modules.js +63 -0
- package/dist/core/extensions/bundled-virtual-modules.js.map +1 -0
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +2 -42
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +6 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +10 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/grok-harness-dispatch.d.ts +6 -20
- package/dist/core/grok-harness-dispatch.d.ts.map +1 -1
- package/dist/core/grok-harness-dispatch.js +6 -55
- package/dist/core/grok-harness-dispatch.js.map +1 -1
- package/dist/core/grok-harness.d.ts +7 -9
- package/dist/core/grok-harness.d.ts.map +1 -1
- package/dist/core/grok-harness.js +9 -23
- package/dist/core/grok-harness.js.map +1 -1
- package/dist/core/harness-skills.d.ts +20 -0
- package/dist/core/harness-skills.d.ts.map +1 -0
- package/dist/core/harness-skills.js +36 -0
- package/dist/core/harness-skills.js.map +1 -0
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/loadout-runtime-state.d.ts +25 -0
- package/dist/core/loadout-runtime-state.d.ts.map +1 -0
- package/dist/core/loadout-runtime-state.js +39 -0
- package/dist/core/loadout-runtime-state.js.map +1 -0
- package/dist/core/loadout-runtime.d.ts +4 -20
- package/dist/core/loadout-runtime.d.ts.map +1 -1
- package/dist/core/loadout-runtime.js +6 -13
- package/dist/core/loadout-runtime.js.map +1 -1
- package/dist/core/mcp/client.d.ts +27 -6
- package/dist/core/mcp/client.d.ts.map +1 -1
- package/dist/core/mcp/client.js +80 -20
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/manager.d.ts +10 -1
- package/dist/core/mcp/manager.d.ts.map +1 -1
- package/dist/core/mcp/manager.js +68 -9
- package/dist/core/mcp/manager.js.map +1 -1
- package/dist/core/mcp/protocol.d.ts +9 -3
- package/dist/core/mcp/protocol.d.ts.map +1 -1
- package/dist/core/mcp/protocol.js +61 -15
- package/dist/core/mcp/protocol.js.map +1 -1
- package/dist/core/mcp/stdio-transport.d.ts +12 -1
- package/dist/core/mcp/stdio-transport.d.ts.map +1 -1
- package/dist/core/mcp/stdio-transport.js +30 -2
- package/dist/core/mcp/stdio-transport.js.map +1 -1
- package/dist/core/mcp-descriptor-injection.d.ts +26 -0
- package/dist/core/mcp-descriptor-injection.d.ts.map +1 -0
- package/dist/core/mcp-descriptor-injection.js +25 -0
- package/dist/core/mcp-descriptor-injection.js.map +1 -0
- package/dist/core/mcp-public-presets.d.ts +1 -3
- package/dist/core/mcp-public-presets.d.ts.map +1 -1
- package/dist/core/mcp-public-presets.js +3 -15
- package/dist/core/mcp-public-presets.js.map +1 -1
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +24 -3
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -41
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +2 -49
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/neo/catalog.d.ts +20 -0
- package/dist/core/neo/catalog.d.ts.map +1 -0
- package/dist/core/neo/catalog.js +50 -0
- package/dist/core/neo/catalog.js.map +1 -0
- package/dist/core/neo/setup.d.ts +3 -0
- package/dist/core/neo/setup.d.ts.map +1 -0
- package/dist/core/neo/setup.js +47 -0
- package/dist/core/neo/setup.js.map +1 -0
- package/dist/core/provider-default-models.d.ts +43 -0
- package/dist/core/provider-default-models.d.ts.map +1 -0
- package/dist/core/provider-default-models.js +51 -0
- package/dist/core/provider-default-models.js.map +1 -0
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +2 -0
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/provider-error-classification.d.ts +57 -0
- package/dist/core/provider-error-classification.d.ts.map +1 -0
- package/dist/core/provider-error-classification.js +103 -0
- package/dist/core/provider-error-classification.js.map +1 -0
- package/dist/core/provider-harness-dispatch.d.ts +63 -0
- package/dist/core/provider-harness-dispatch.d.ts.map +1 -0
- package/dist/core/provider-harness-dispatch.js +60 -0
- package/dist/core/provider-harness-dispatch.js.map +1 -0
- package/dist/core/provider-resilience.d.ts +10 -0
- package/dist/core/provider-resilience.d.ts.map +1 -1
- package/dist/core/provider-resilience.js +36 -3
- package/dist/core/provider-resilience.js.map +1 -1
- package/dist/core/provider-usage-commandcode.d.ts +9 -0
- package/dist/core/provider-usage-commandcode.d.ts.map +1 -0
- package/dist/core/provider-usage-commandcode.js +198 -0
- package/dist/core/provider-usage-commandcode.js.map +1 -0
- package/dist/core/provider-usage-devin.d.ts +18 -0
- package/dist/core/provider-usage-devin.d.ts.map +1 -0
- package/dist/core/provider-usage-devin.js +71 -0
- package/dist/core/provider-usage-devin.js.map +1 -0
- package/dist/core/provider-usage-text.d.ts +5 -0
- package/dist/core/provider-usage-text.d.ts.map +1 -0
- package/dist/core/provider-usage-text.js +15 -0
- package/dist/core/provider-usage-text.js.map +1 -0
- package/dist/core/provider-usage-types.d.ts +2 -1
- package/dist/core/provider-usage-types.d.ts.map +1 -1
- package/dist/core/provider-usage-types.js.map +1 -1
- package/dist/core/provider-usage.d.ts +1 -2
- package/dist/core/provider-usage.d.ts.map +1 -1
- package/dist/core/provider-usage.js +18 -7
- package/dist/core/provider-usage.js.map +1 -1
- package/dist/core/resource-admission.d.ts +36 -0
- package/dist/core/resource-admission.d.ts.map +1 -1
- package/dist/core/resource-admission.js +59 -0
- package/dist/core/resource-admission.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +2 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/run-execution-api.d.ts +1 -1
- package/dist/core/run-execution-api.d.ts.map +1 -1
- package/dist/core/run-execution-api.js.map +1 -1
- package/dist/core/run-usage-ledger.d.ts +47 -0
- package/dist/core/run-usage-ledger.d.ts.map +1 -0
- package/dist/core/run-usage-ledger.js +162 -0
- package/dist/core/run-usage-ledger.js.map +1 -0
- package/dist/core/run-usage-operation.d.ts +8 -0
- package/dist/core/run-usage-operation.d.ts.map +1 -0
- package/dist/core/run-usage-operation.js +12 -0
- package/dist/core/run-usage-operation.js.map +1 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +20 -16
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-failure-cause.d.ts.map +1 -1
- package/dist/core/session-failure-cause.js +14 -5
- package/dist/core/session-failure-cause.js.map +1 -1
- package/dist/core/session-prompt-lifecycle.d.ts +6 -0
- package/dist/core/session-prompt-lifecycle.d.ts.map +1 -1
- package/dist/core/session-prompt-lifecycle.js +47 -2
- package/dist/core/session-prompt-lifecycle.js.map +1 -1
- package/dist/core/session-termination.d.ts.map +1 -1
- package/dist/core/session-termination.js +4 -2
- package/dist/core/session-termination.js.map +1 -1
- package/dist/core/subagent-lane-authority.d.ts +28 -0
- package/dist/core/subagent-lane-authority.d.ts.map +1 -0
- package/dist/core/subagent-lane-authority.js +119 -0
- package/dist/core/subagent-lane-authority.js.map +1 -0
- package/dist/core/subagent-lane-contract.d.ts +114 -0
- package/dist/core/subagent-lane-contract.d.ts.map +1 -0
- package/dist/core/subagent-lane-contract.js +18 -0
- package/dist/core/subagent-lane-contract.js.map +1 -0
- package/dist/core/subagent-lane-launcher.d.ts +3 -6
- package/dist/core/subagent-lane-launcher.d.ts.map +1 -1
- package/dist/core/subagent-lane-launcher.js +53 -12
- package/dist/core/subagent-lane-launcher.js.map +1 -1
- package/dist/core/subagent-orchestration.d.ts +4 -17
- package/dist/core/subagent-orchestration.d.ts.map +1 -1
- package/dist/core/subagent-orchestration.js.map +1 -1
- package/dist/core/verified-run/broker.d.ts.map +1 -1
- package/dist/core/verified-run/broker.js +4 -1
- package/dist/core/verified-run/broker.js.map +1 -1
- package/dist/core/verified-run/dag-phase.d.ts +1 -1
- package/dist/core/verified-run/dag-phase.d.ts.map +1 -1
- package/dist/core/verified-run/dag-phase.js +46 -8
- package/dist/core/verified-run/dag-phase.js.map +1 -1
- package/dist/core/verified-run/dag-projection.d.ts.map +1 -1
- package/dist/core/verified-run/dag-projection.js +25 -12
- package/dist/core/verified-run/dag-projection.js.map +1 -1
- package/dist/core/verified-run/dag-types.d.ts +11 -0
- package/dist/core/verified-run/dag-types.d.ts.map +1 -1
- package/dist/core/verified-run/dag-types.js.map +1 -1
- package/dist/core/verified-run/event-parser.d.ts.map +1 -1
- package/dist/core/verified-run/event-parser.js +1 -0
- package/dist/core/verified-run/event-parser.js.map +1 -1
- package/dist/core/verified-run/owned-execution.d.ts +1 -0
- package/dist/core/verified-run/owned-execution.d.ts.map +1 -1
- package/dist/core/verified-run/owned-execution.js +7 -1
- package/dist/core/verified-run/owned-execution.js.map +1 -1
- package/dist/core/verified-run/process-projection.d.ts +13 -0
- package/dist/core/verified-run/process-projection.d.ts.map +1 -0
- package/dist/core/verified-run/process-projection.js +82 -0
- package/dist/core/verified-run/process-projection.js.map +1 -0
- package/dist/core/verified-run/projection.d.ts.map +1 -1
- package/dist/core/verified-run/projection.js +11 -55
- package/dist/core/verified-run/projection.js.map +1 -1
- package/dist/core/verified-run/run-types.d.ts +1 -0
- package/dist/core/verified-run/run-types.d.ts.map +1 -1
- package/dist/core/verified-run/run-types.js.map +1 -1
- package/dist/core/verified-run/task-execution.d.ts +9 -0
- package/dist/core/verified-run/task-execution.d.ts.map +1 -0
- package/dist/core/verified-run/task-execution.js +29 -0
- package/dist/core/verified-run/task-execution.js.map +1 -0
- package/dist/core/verified-run/writer-projection.d.ts.map +1 -1
- package/dist/core/verified-run/writer-projection.js +6 -5
- package/dist/core/verified-run/writer-projection.js.map +1 -1
- package/dist/core/workload-permit-pool.d.ts +1 -1
- package/dist/core/workload-permit-pool.d.ts.map +1 -1
- package/dist/core/workload-permit-pool.js +3 -0
- package/dist/core/workload-permit-pool.js.map +1 -1
- package/dist/guardrails/strict-evidence-approval-adapter.d.ts +34 -0
- package/dist/guardrails/strict-evidence-approval-adapter.d.ts.map +1 -0
- package/dist/guardrails/strict-evidence-approval-adapter.js +70 -0
- package/dist/guardrails/strict-evidence-approval-adapter.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +11 -18
- package/dist/main.js.map +1 -1
- package/dist/modes/acp/acp-agent.d.ts +24 -0
- package/dist/modes/acp/acp-agent.d.ts.map +1 -0
- package/dist/modes/acp/acp-agent.js +133 -0
- package/dist/modes/acp/acp-agent.js.map +1 -0
- package/dist/modes/acp/acp-mode.d.ts +4 -0
- package/dist/modes/acp/acp-mode.d.ts.map +1 -0
- package/dist/modes/acp/acp-mode.js +34 -0
- package/dist/modes/acp/acp-mode.js.map +1 -0
- package/dist/modes/acp/acp-session.d.ts +4 -0
- package/dist/modes/acp/acp-session.d.ts.map +1 -0
- package/dist/modes/acp/acp-session.js +76 -0
- package/dist/modes/acp/acp-session.js.map +1 -0
- package/dist/modes/acp/acp-transport.d.ts +5 -0
- package/dist/modes/acp/acp-transport.d.ts.map +1 -0
- package/dist/modes/acp/acp-transport.js +90 -0
- package/dist/modes/acp/acp-transport.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +3 -5
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/resource-description.d.ts +3 -0
- package/dist/modes/interactive/resource-description.d.ts.map +1 -0
- package/dist/modes/interactive/resource-description.js +15 -0
- package/dist/modes/interactive/resource-description.js.map +1 -0
- package/docs/audit-revalidation-2026-09-17.md +77 -0
- package/docs/devin-harness.md +150 -0
- package/docs/docs.json +4 -0
- package/docs/ecraf-normalization.md +83 -0
- package/docs/environment-variables.md +2 -1
- package/docs/index.md +1 -0
- package/docs/loadout-domains/README.md +2 -1
- package/docs/loadout-domains/devin-harness.md +72 -0
- package/docs/metrics.md +57 -16
- package/docs/model-catalog-refresh.md +51 -1
- package/docs/models.md +1 -1
- package/docs/neo.md +134 -0
- package/docs/providers.md +143 -1
- package/docs/release-audit-0.98.5.md +17 -0
- package/docs/release-audit-0.99.0.md +68 -0
- package/docs/run-protocol.md +4 -3
- package/docs/run-usage-ledger.md +56 -0
- package/docs/runtime-algorithms.md +48 -1
- package/docs/sdk.md +9 -5
- package/docs/settings.md +1 -1
- package/docs/skills.md +1 -1
- package/docs/startup-resource-labels-testing.md +47 -0
- package/docs/tb21-audit.md +18 -4
- package/docs/usage.md +7 -1
- package/docs/verified-run-remaining-design.md +881 -0
- package/docs/verified-run-testing.md +91 -0
- package/docs/verified-run.md +30 -9
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/adaptive-agent-runtime.ts +14 -1
- package/examples/extensions/subagent/graph-result.ts +48 -0
- package/examples/extensions/subagent/index.ts +246 -111
- package/examples/extensions/subagent/managed-process-tree.ts +42 -0
- package/examples/extensions/subagent/managed-process.test.ts +24 -0
- package/examples/extensions/subagent/managed-process.ts +93 -112
- package/examples/extensions/subagent/subagent-runtime-types.ts +17 -1
- package/examples/extensions/subagent/subagent-stream.ts +161 -0
- package/examples/extensions/terminal-browser/README.md +54 -0
- package/examples/extensions/terminal-browser/bridge-protocol.ts +29 -0
- package/examples/extensions/terminal-browser/bridge.ts +219 -0
- package/examples/extensions/terminal-browser/browser-surface.ts +288 -0
- package/examples/extensions/terminal-browser/index.ts +215 -0
- package/examples/extensions/terminal-browser/placeholders.ts +49 -0
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +18 -18
- package/package.json +8 -7
- package/resources/neo/skills/omk-browser/SKILL.md +32 -0
- package/resources/neo/skills/omk-code-review/SKILL.md +24 -0
- package/resources/neo/skills/omk-computeruse/SKILL.md +34 -0
- package/resources/neo/skills/omk-mcp-setup/SKILL.md +48 -0
- package/resources/neo/skills/omk-research/SKILL.md +24 -0
- package/resources/neo/skills/omk-site/SKILL.md +28 -0
|
@@ -18,7 +18,7 @@ import { basename, dirname, join as joinPath } from "node:path";
|
|
|
18
18
|
import { isDeepStrictEqual } from "node:util";
|
|
19
19
|
import { getVisionRouteModel } from "omk-agent-core";
|
|
20
20
|
import { clampThinkingLevel, cleanupSessionResources, deriveContextPromptCacheKey, getSupportedThinkingLevels, isBuiltinStreamFn, modelsAreEqual, resetApiProviders, } from "omk-ai";
|
|
21
|
-
import { APP_NAME, VERSION } from "../config.js";
|
|
21
|
+
import { APP_NAME, getAgentDir, VERSION } from "../config.js";
|
|
22
22
|
import { theme } from "../modes/interactive/theme/theme.js";
|
|
23
23
|
import { stripFrontmatter } from "../utils/frontmatter.js";
|
|
24
24
|
import { resolvePath } from "../utils/paths.js";
|
|
@@ -33,6 +33,7 @@ import { getCompactionHeadroomThreshold } from "./compaction/compaction.js";
|
|
|
33
33
|
import { createCompactionHysteresisConfig, createCompactionHysteresisState, stepCompactionHysteresis, } from "./compaction/hysteresis.js";
|
|
34
34
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateProjectedContextTokens, generateBranchSummary, prepareCompaction, resolveCompactionModel, } from "./compaction/index.js";
|
|
35
35
|
import { summarizeWithOAuthRecovery } from "./compaction/oauth-recovery.js";
|
|
36
|
+
import { overflowRetryBlocked } from "./compaction/overflow-retry-guard.js";
|
|
36
37
|
import { compactionEmitWillRetry } from "./compaction/resume-policy.js";
|
|
37
38
|
import { isSessionModelOverflow, shouldSkipCompactionCheck } from "./compaction-gate.js";
|
|
38
39
|
import { estimateToolResultReserve, } from "./context-budget-reserved-tokens.js";
|
|
@@ -40,17 +41,21 @@ import { createDiskContextBudgetCacheProviderV2, DiskContextBudgetCacheProviderV
|
|
|
40
41
|
import { applyContextCacheInvalidation, createContextCacheInvalidationSnapshot, } from "./context-budget-v2-cache-invalidation.js";
|
|
41
42
|
import { createMemoryContextBudgetCacheProviderV2 } from "./context-budget-v2-cache-provider.js";
|
|
42
43
|
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
44
|
+
import { devinHarnessAutoApplyEnabled, devinPlaybookAppendForProvider, isDevinProvider, selectDevinHarnessSkills, } from "./devin-harness.js";
|
|
43
45
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
44
46
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
45
47
|
import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
46
48
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
47
49
|
import { assertTextChatModelForCompletion, grokHarnessAutoApplyEnabled, isGrokOAuthProvider, selectGrokHarnessSkills, } from "./grok-harness.js";
|
|
48
50
|
import { grokPlaybookAppendForProvider } from "./grok-playbook.js";
|
|
51
|
+
import { loadHookInventory } from "./hook-inventory.js";
|
|
49
52
|
import { captureHostResourceSnapshot } from "./host-resource-snapshot.js";
|
|
50
53
|
import { decideLoadoutAccess } from "./loadout-access-policy.js";
|
|
54
|
+
import { buildCapabilityInventory } from "./loadout-runtime.js";
|
|
51
55
|
import { loadMcpServerConfigs } from "./mcp/config.js";
|
|
52
56
|
import { McpManager } from "./mcp/manager.js";
|
|
53
57
|
import { buildRuntimeProvenance } from "./runtime-provenance.js";
|
|
58
|
+
import { createSubagentLaneAuthority } from "./subagent-lane-authority.js";
|
|
54
59
|
import { TurnMetricsSink } from "./turn-metrics.js";
|
|
55
60
|
/** Values that disable a session-level feature through its environment variable. */
|
|
56
61
|
const DISABLED_ENV_VALUES = new Set(["0", "false", "off", "disable", "disabled"]);
|
|
@@ -93,12 +98,12 @@ import { classifyPromptCacheTransition } from "./prompt-cache.js";
|
|
|
93
98
|
import * as promptSettlement from "./prompt-settlement.js";
|
|
94
99
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
95
100
|
import { isQuotaExhaustionMessage, isStickySafetyModel, isUpstreamUnavailableMessage, pickFailoverCandidate, resolveFailoverCandidates, resolveProviderResilience, sameModelRouteCandidates, shouldEjectStickySafetyModel, shouldHonorSafetyFailover, stickySafetyBlockMessage, } from "./provider-resilience.js";
|
|
96
|
-
import { computeRetryDelayMs, failoverModelKey, isFailoverTriggerError, isRetryableAssistantError, nextRetryAttempt, retryBudgetForAssistantError, } from "./provider-retry.js";
|
|
101
|
+
import { computeRetryDelayMs, failoverModelKey, isEmptyStreamedCompletion, isFailoverTriggerError, isRetryableAssistantError, nextRetryAttempt, retryBudgetForAssistantError, } from "./provider-retry.js";
|
|
97
102
|
import { getBiasStepsForCell, parseRouterBiasSnapshot } from "./reasoning-router-bias.js";
|
|
98
103
|
import { classifyTaskV4, deriveRouterFeedbackFeaturesV4, resolveThinkingLevelV4WithUncertainty, TASK_CLASS_THINKING_LEVELS_V4, } from "./reasoning-router-v4.js";
|
|
99
104
|
import { redactSensitiveText, redactSensitiveTextForced } from "./redaction.js";
|
|
100
105
|
import { getRepositoryRouterLearningPaths } from "./repository-learning-scope.js";
|
|
101
|
-
import { decideResourceAdmission } from "./resource-admission.js";
|
|
106
|
+
import { createResourcePressureStabilizer, decideResourceAdmission, evaluateResourcePressure, rederiveResourceAdmissionForPressure, } from "./resource-admission.js";
|
|
102
107
|
import { resolveResourceGovernorSettings } from "./resource-governor-settings.js";
|
|
103
108
|
import { admissionObservationFacts, classificationObservationFacts, ResourceObservationJournal, settledObservationFacts, snapshotObservationFacts, soundObservationFacts, } from "./resource-observation-journal.js";
|
|
104
109
|
import { decideResourceSafetyGate, RESOURCE_PRESSURE_REQUIRED_ACTION } from "./resource-safety-gate.js";
|
|
@@ -288,6 +293,10 @@ export class AgentSession {
|
|
|
288
293
|
_resourceObservationJournals = new Map();
|
|
289
294
|
_latestResourcePromptRunId = null;
|
|
290
295
|
_lastResourceAdmission = null;
|
|
296
|
+
// Per-session pressure hysteresis (audit §16.1): escalation is immediate,
|
|
297
|
+
// recovery requires consecutive healthier probes so the applied cap does
|
|
298
|
+
// not flap around a threshold between prompts.
|
|
299
|
+
_resourcePressureStabilizer;
|
|
291
300
|
_workloadPermitPool;
|
|
292
301
|
_pendingRuntimeTerminationCause;
|
|
293
302
|
_activeRunToolTermination;
|
|
@@ -534,6 +543,12 @@ export class AgentSession {
|
|
|
534
543
|
this._emit({ type: "session_termination", termination });
|
|
535
544
|
}
|
|
536
545
|
_publishRuntimeFailure(error) {
|
|
546
|
+
// A caller rejected by "Agent is already processing" never owned a run: the
|
|
547
|
+
// open journal run belongs to the live run, and closing it here would make
|
|
548
|
+
// that run die later with "agent_end without run_started". Let the caller
|
|
549
|
+
// surface its own error and leave the live run's journal alone.
|
|
550
|
+
if (this.isStreaming)
|
|
551
|
+
return;
|
|
537
552
|
const cause = this._pendingRuntimeTerminationCause ?? runtimeFailureCause(error);
|
|
538
553
|
const runId = this._activeRunId ?? `runtime-${randomUUID()}`;
|
|
539
554
|
const timestamp = new Date().toISOString();
|
|
@@ -854,8 +869,13 @@ export class AgentSession {
|
|
|
854
869
|
this._overflowRecoveryAttempts = 0;
|
|
855
870
|
}
|
|
856
871
|
// Reset retry counter immediately on successful assistant response
|
|
857
|
-
// This prevents accumulation across multiple LLM calls within a turn
|
|
858
|
-
|
|
872
|
+
// This prevents accumulation across multiple LLM calls within a turn.
|
|
873
|
+
// An empty streamed completion wears a success shape (stop=stop, zero
|
|
874
|
+
// usable output) but is a dead stream — counting it as success reset
|
|
875
|
+
// the budget every cycle and retried forever (union-alpha relay loop).
|
|
876
|
+
if (assistantMsg.stopReason !== "error" &&
|
|
877
|
+
!isEmptyStreamedCompletion(assistantMsg) &&
|
|
878
|
+
this._retryAttempt > 0) {
|
|
859
879
|
this._emit({
|
|
860
880
|
type: "auto_retry_end",
|
|
861
881
|
success: true,
|
|
@@ -1364,16 +1384,19 @@ export class AgentSession {
|
|
|
1364
1384
|
* Extract the most recent user query text from conversation messages.
|
|
1365
1385
|
* Returns undefined when no user message exists or content is empty.
|
|
1366
1386
|
* Handles both string content and multimodal (array) content.
|
|
1387
|
+
*
|
|
1388
|
+
* The scan walks the whole transcript backwards and stops at the first user
|
|
1389
|
+
* message. A fixed tail window cannot work here: tool results are their own
|
|
1390
|
+
* messages, so a single turn that calls two tools already leaves
|
|
1391
|
+
* `[user, assistant, toolResult, toolResult]` and buries the task four deep.
|
|
1392
|
+
* Losing it mid-turn collapses every skill to the neutral relevance score and
|
|
1393
|
+
* degrades ranking to catalogue order, precisely while tools are running and
|
|
1394
|
+
* a matching skill matters most.
|
|
1367
1395
|
*/
|
|
1368
1396
|
_extractCurrentQuery() {
|
|
1369
1397
|
const messages = this.messages;
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
}
|
|
1373
|
-
// Scan recent messages (last 3) for the most recent user message
|
|
1374
|
-
const recent = messages.slice(-3);
|
|
1375
|
-
for (let i = recent.length - 1; i >= 0; i--) {
|
|
1376
|
-
const msg = recent[i];
|
|
1398
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1399
|
+
const msg = messages[i];
|
|
1377
1400
|
if (!msg || !("role" in msg) || msg.role !== "user") {
|
|
1378
1401
|
continue;
|
|
1379
1402
|
}
|
|
@@ -1470,7 +1493,7 @@ export class AgentSession {
|
|
|
1470
1493
|
toolPromptGuidelines: this._toolPromptGuidelines,
|
|
1471
1494
|
customPrompt: this._resourceLoader.getSystemPrompt(),
|
|
1472
1495
|
appendSystemPrompt: this._resourceLoader.getAppendSystemPrompt(),
|
|
1473
|
-
providerAppend: grokPlaybookAppendForProvider(model?.provider),
|
|
1496
|
+
providerAppend: grokPlaybookAppendForProvider(model?.provider) ?? devinPlaybookAppendForProvider(model?.provider),
|
|
1474
1497
|
skills: this._resourceLoader.getSkills().skills,
|
|
1475
1498
|
activeSkillNames: defaultActiveSkills,
|
|
1476
1499
|
activeSkillSource: defaultActiveSkills.length > 0 ? "settings" : undefined,
|
|
@@ -1569,8 +1592,12 @@ export class AgentSession {
|
|
|
1569
1592
|
}
|
|
1570
1593
|
const snapshot = await captureHostResourceSnapshot(probeOptions);
|
|
1571
1594
|
const decision = decideResourceAdmission({ snapshot, config: resolved.admission, configuredCaps });
|
|
1595
|
+
const stabilized = this._stabilizeResourcePressure(snapshot, resolved);
|
|
1596
|
+
const appliedDecision = stabilized === decision.pressure
|
|
1597
|
+
? decision
|
|
1598
|
+
: rederiveResourceAdmissionForPressure(decision, resolved.admission.caps, configuredCaps, stabilized);
|
|
1572
1599
|
if (this._latestResourcePromptRunId === promptRunId) {
|
|
1573
|
-
this._lastResourceAdmission =
|
|
1600
|
+
this._lastResourceAdmission = appliedDecision;
|
|
1574
1601
|
}
|
|
1575
1602
|
resourceObservations?.record("resource_snapshot_v1", snapshotObservationFacts(snapshot));
|
|
1576
1603
|
resourceObservations?.record("resource_admission_v1", admissionObservationFacts(decision));
|
|
@@ -1580,7 +1607,7 @@ export class AgentSession {
|
|
|
1580
1607
|
this.agent.maxToolConcurrency = cap;
|
|
1581
1608
|
},
|
|
1582
1609
|
});
|
|
1583
|
-
const lease = this._resourceLeaseController.acquire({ promptRunId, decision });
|
|
1610
|
+
const lease = this._resourceLeaseController.acquire({ promptRunId, decision: appliedDecision });
|
|
1584
1611
|
resourceObservations?.record("resource_lease_acquired_v1", {
|
|
1585
1612
|
decisionId: decision.decisionId,
|
|
1586
1613
|
appliedToolCap: decision.maxToolConcurrency,
|
|
@@ -1591,6 +1618,15 @@ export class AgentSession {
|
|
|
1591
1618
|
return null;
|
|
1592
1619
|
}
|
|
1593
1620
|
}
|
|
1621
|
+
/**
|
|
1622
|
+
* Feed one snapshot's raw pressure through the per-session stabilizer.
|
|
1623
|
+
* Created lazily so sessions that never probe carry no state; the first
|
|
1624
|
+
* observation installs its own level directly (no warmup lag).
|
|
1625
|
+
*/
|
|
1626
|
+
_stabilizeResourcePressure(snapshot, resolved) {
|
|
1627
|
+
this._resourcePressureStabilizer ??= createResourcePressureStabilizer();
|
|
1628
|
+
return this._resourcePressureStabilizer.observe(evaluateResourcePressure(snapshot, resolved.admission.thresholds));
|
|
1629
|
+
}
|
|
1594
1630
|
_openResourceObservations(promptRunId) {
|
|
1595
1631
|
this._latestResourcePromptRunId = promptRunId;
|
|
1596
1632
|
try {
|
|
@@ -1626,6 +1662,30 @@ export class AgentSession {
|
|
|
1626
1662
|
getCurrentResourceAdmission() {
|
|
1627
1663
|
return this._lastResourceAdmission;
|
|
1628
1664
|
}
|
|
1665
|
+
/**
|
|
1666
|
+
* Spec 020 Req1 — canonical subagent lane authority bound to this session.
|
|
1667
|
+
* Rebuilt on each call so it tracks the live admission decision, shared
|
|
1668
|
+
* permit pool, and open prompt run. Extension tool contexts read it through
|
|
1669
|
+
* `ctx.getSubagentLaneAuthority()`.
|
|
1670
|
+
*/
|
|
1671
|
+
_getSubagentLaneAuthority() {
|
|
1672
|
+
const hookInventory = loadHookInventory(getAgentDir());
|
|
1673
|
+
const sessionView = {
|
|
1674
|
+
_baseToolDefinitions: this._baseToolDefinitions,
|
|
1675
|
+
_extensionRunner: this._extensionRunner,
|
|
1676
|
+
_customTools: this._customTools,
|
|
1677
|
+
};
|
|
1678
|
+
const inventory = buildCapabilityInventory(sessionView, this._resourceLoader, this._cwd, hookInventory);
|
|
1679
|
+
return createSubagentLaneAuthority({
|
|
1680
|
+
runId: this._activeRunId ?? `session-${this.sessionManager.getSessionId() ?? "unknown"}`,
|
|
1681
|
+
promptRunId: this._promptLifecycle.activePromptRunId,
|
|
1682
|
+
decision: this._lastResourceAdmission,
|
|
1683
|
+
permitPool: this.workloadPermitPool,
|
|
1684
|
+
inventory,
|
|
1685
|
+
signal: this.agent?.signal,
|
|
1686
|
+
noteDetachedChild: () => this._promptLifecycle.noteDetachedChild(),
|
|
1687
|
+
});
|
|
1688
|
+
}
|
|
1629
1689
|
/** §19.4 read-only SDK surface: capture a fresh host resource snapshot. */
|
|
1630
1690
|
async getHostResourceSnapshot() {
|
|
1631
1691
|
const resolved = resolveResourceGovernorSettings(this.settingsManager.getResourceGovernorSettings());
|
|
@@ -1734,12 +1794,15 @@ export class AgentSession {
|
|
|
1734
1794
|
if (this._isRetryableError(msg) && (await this._prepareRetry(msg))) {
|
|
1735
1795
|
return true;
|
|
1736
1796
|
}
|
|
1737
|
-
|
|
1797
|
+
// The retry budget is exhausted without a real answer. This covers the
|
|
1798
|
+
// empty-streamed-completion path whose success-shaped stopReason
|
|
1799
|
+
// otherwise left the UI pinned in the retrying state forever.
|
|
1800
|
+
if (this._retryAttempt > 0) {
|
|
1738
1801
|
this._emit({
|
|
1739
1802
|
type: "auto_retry_end",
|
|
1740
1803
|
success: false,
|
|
1741
1804
|
attempt: this._retryAttempt,
|
|
1742
|
-
finalError: msg.errorMessage,
|
|
1805
|
+
finalError: msg.errorMessage ?? "The provider returned an empty response.",
|
|
1743
1806
|
});
|
|
1744
1807
|
this._retryAttempt = 0;
|
|
1745
1808
|
this._refusedModels.clear();
|
|
@@ -1893,6 +1956,13 @@ export class AgentSession {
|
|
|
1893
1956
|
});
|
|
1894
1957
|
promptSkills = addActiveSkills(promptSkills, grokSkills, "grok-harness");
|
|
1895
1958
|
}
|
|
1959
|
+
else if (isDevinProvider(this.model?.provider) && devinHarnessAutoApplyEnabled(process.env)) {
|
|
1960
|
+
const skillQuery = isBangSkillInvocation ? currentText : expandedText;
|
|
1961
|
+
const devinSkills = selectDevinHarnessSkills(skillQuery, this._resourceLoader.getSkills().skills, {
|
|
1962
|
+
contextPressure: this._computePressureBucket(messages) > 0,
|
|
1963
|
+
});
|
|
1964
|
+
promptSkills = addActiveSkills(promptSkills, devinSkills, "devin-harness");
|
|
1965
|
+
}
|
|
1896
1966
|
const turnSystemPromptOptions = {
|
|
1897
1967
|
...this._baseSystemPromptOptions,
|
|
1898
1968
|
contextBudget: this._getContextBudgetOptions(expandedText),
|
|
@@ -2124,7 +2194,10 @@ export class AgentSession {
|
|
|
2124
2194
|
if (options?.deliverAs === "nextTurn") {
|
|
2125
2195
|
this._pendingNextTurnMessages.push(appMessage);
|
|
2126
2196
|
}
|
|
2127
|
-
else if (this.isStreaming) {
|
|
2197
|
+
else if (this.isStreaming || this.isRetrying) {
|
|
2198
|
+
// Retry backoff still owns the session (mirrors prompt()): starting a
|
|
2199
|
+
// top-level run here races the pending agent.continue() and wedges the
|
|
2200
|
+
// run journal, so queue for the retried run to drain instead.
|
|
2128
2201
|
if (options?.deliverAs === "followUp") {
|
|
2129
2202
|
this.agent.followUp(appMessage);
|
|
2130
2203
|
}
|
|
@@ -2991,8 +3064,13 @@ export class AgentSession {
|
|
|
2991
3064
|
/**
|
|
2992
3065
|
* Effective context window for the upcoming turn.
|
|
2993
3066
|
* Image-bearing turns with a text-only session model are auto-routed to the
|
|
2994
|
-
* vision model (gpt-5.6-luna, 1M)
|
|
2995
|
-
*
|
|
3067
|
+
* vision model (gpt-5.6-luna, 1M), so the request has to fit both windows and
|
|
3068
|
+
* the binding limit is the smaller one. Session windows fall on both sides of
|
|
3069
|
+
* 1M: most catalogued models are smaller (median near 300K) and keep their own
|
|
3070
|
+
* window as the limit, while the larger-than-1M models are the ones the clamp
|
|
3071
|
+
* exists for — without it their threshold is computed against a window the
|
|
3072
|
+
* vision route will not honour, and the request overflows before compaction
|
|
3073
|
+
* fires. Text-only turns keep the session model's window untouched.
|
|
2996
3074
|
*/
|
|
2997
3075
|
_effectiveTurnContextWindow(pendingMessages, sessionWindow) {
|
|
2998
3076
|
// Vision routing keys off the full transcript, not just the pending turn:
|
|
@@ -3271,16 +3349,25 @@ export class AgentSession {
|
|
|
3271
3349
|
// the compaction_end event (so the TUI flushes its queued messages
|
|
3272
3350
|
// correctly) and the return value below.
|
|
3273
3351
|
const resumeMessages = this.agent.state.messages;
|
|
3274
|
-
|
|
3275
|
-
for (let i = resumeMessages.length - 1; i >= 0; i--) {
|
|
3276
|
-
const candidate = resumeMessages[i];
|
|
3277
|
-
if (candidate.role === "assistant") {
|
|
3278
|
-
lastAssistantMsg = candidate;
|
|
3279
|
-
break;
|
|
3280
|
-
}
|
|
3281
|
-
}
|
|
3352
|
+
const lastAssistantMsg = this._findLastAssistantMessage();
|
|
3282
3353
|
const endedCleanly = lastAssistantMsg?.stopReason === "stop";
|
|
3283
3354
|
const willResume = this.agent.hasQueuedMessages() || !endedCleanly;
|
|
3355
|
+
// overflow-retry-guard 배선: 압축 후 재전송 컨텍스트가 창을 확실히 초과하면
|
|
3356
|
+
// 재시도는 프로바이더 왕복만 소모한다 — 정확한 수치 진단과 함께 차단한다.
|
|
3357
|
+
const overflowBlock = willRetry
|
|
3358
|
+
? overflowRetryBlocked(resumeMessages, this.model?.contextWindow ?? 0)
|
|
3359
|
+
: undefined;
|
|
3360
|
+
if (overflowBlock !== undefined) {
|
|
3361
|
+
this._emit({
|
|
3362
|
+
type: "compaction_end",
|
|
3363
|
+
reason,
|
|
3364
|
+
result,
|
|
3365
|
+
aborted: false,
|
|
3366
|
+
willRetry: false,
|
|
3367
|
+
errorMessage: overflowBlock,
|
|
3368
|
+
});
|
|
3369
|
+
return false;
|
|
3370
|
+
}
|
|
3284
3371
|
const emitWillRetry = compactionEmitWillRetry(willRetry, willResume);
|
|
3285
3372
|
this._emit({ type: "compaction_end", reason, result, aborted: false, willRetry: emitWillRetry });
|
|
3286
3373
|
if (willRetry) {
|
|
@@ -3517,6 +3604,10 @@ export class AgentSession {
|
|
|
3517
3604
|
},
|
|
3518
3605
|
getSystemPrompt: () => this.systemPrompt,
|
|
3519
3606
|
getSystemPromptOptions: () => this._baseSystemPromptOptions,
|
|
3607
|
+
// Spec 020 Req1 — session-bound lane authority for extension tool
|
|
3608
|
+
// contexts (subagent spawn funnel). Rebuilt on demand so it always
|
|
3609
|
+
// sees the live admission decision, permit pool, and prompt run.
|
|
3610
|
+
getSubagentLaneAuthority: () => this._getSubagentLaneAuthority(),
|
|
3520
3611
|
}, {
|
|
3521
3612
|
registerProvider: (name, config) => {
|
|
3522
3613
|
this._modelRegistry.registerProvider(name, config);
|
|
@@ -3948,10 +4039,13 @@ export class AgentSession {
|
|
|
3948
4039
|
if (attempt === undefined)
|
|
3949
4040
|
return false;
|
|
3950
4041
|
this._retryAttempt = attempt;
|
|
3951
|
-
// Upstream-unavailable (gateway 5xx / dropped stream
|
|
3952
|
-
// authenticated route of the SAME model family so the
|
|
3953
|
-
// live endpoint instead of hammering the dead one.
|
|
3954
|
-
|
|
4042
|
+
// Upstream-unavailable (gateway 5xx / dropped stream / dead relay stream):
|
|
4043
|
+
// rotate to another authenticated route of the SAME model family so the
|
|
4044
|
+
// retry lands on a live endpoint instead of hammering the dead one. An
|
|
4045
|
+
// empty streamed completion is the same dead-stream signature wearing a
|
|
4046
|
+
// success stopReason, so it rotates too — otherwise the retry re-hits the
|
|
4047
|
+
// route that just returned nothing.
|
|
4048
|
+
const rotatedTo = isUpstreamUnavailableMessage(message.errorMessage) || isEmptyStreamedCompletion(message)
|
|
3955
4049
|
? await this._maybeRotateModelRoutes()
|
|
3956
4050
|
: undefined;
|
|
3957
4051
|
// Content/safety stop (Fable/Opus/Sonnet): switch model BEFORE delay so retry is not same-model refusal.
|