mixdog 1.4.0 → 1.4.2
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/package.json +3 -2
- package/scripts/build-shipped-history.mjs +115 -33
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/gate-local.mjs +183 -63
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/gate-scheduler.mjs +138 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +91 -66
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +124 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +16 -4
- package/scripts/lib/test-spawn-ledger.mjs +12 -3
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -5
- package/scripts/suite-health.mjs +115 -24
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/app.mjs +4 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +23 -2
- package/src/defaults/skills/browser-use/SKILL.md +10 -5
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +16 -4
- package/src/defaults/skills/goal-management/SKILL.md +1 -1
- package/src/defaults/skills/setup/references/actions.md +12 -6
- package/src/defaults/skills/setup/references/surfaces.md +2 -2
- package/src/defaults/skills/setup-guide/SKILL.md +5 -2
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/rules-builder.cjs +35 -42
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +5 -4
- package/src/rules/lead/LEAD.md +12 -7
- package/src/rules/shared/10-tool-workflow.md +3 -1
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/45-destructive.md +0 -2
- package/src/rules/shared/50-execution.md +2 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +8 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +156 -24
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -0
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +8 -8
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +5 -26
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +122 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -3
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +13 -2
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +152 -58
- package/src/runtime/agent/orchestrator/mcp/client.mjs +51 -18
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +88 -54
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +42 -26
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +54 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +37 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +248 -41
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
- package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
- package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +160 -31
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +22 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +49 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +45 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +567 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +41 -13
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +6 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +14 -5
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +102 -12
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +160 -36
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +164 -23
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +139 -19
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +100 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -6
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +23 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +39 -21
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +50 -28
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +30 -13
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +63 -6
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +35 -13
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +10 -6
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +56 -29
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +30 -7
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +252 -39
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +164 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +61 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -20
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +67 -31
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +96 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +103 -13
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +34 -10
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +28 -4
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/whisper-port.mjs +29 -11
- package/src/runtime/channels/lib/whisper-server.mjs +10 -1
- package/src/runtime/computer-bridge/action-schema.mjs +2 -2
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +5 -4
- package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
- package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
- package/src/runtime/connectors/connector-accounts-mcp.mjs +236 -103
- package/src/runtime/connectors/gmail-app-password.mjs +3 -3
- package/src/runtime/explore/explorer.mjs +93 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/server-process.mjs +2 -1
- package/src/runtime/media/adapters/gemini-video.mjs +4 -1
- package/src/runtime/media/adapters/xai-media.mjs +2 -1
- package/src/runtime/memory/index.mjs +4 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-worker.mjs +10 -3
- package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
- package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
- package/src/runtime/office/design/design-art-direction.mjs +29 -27
- package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
- package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
- package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
- package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
- package/src/runtime/office/quality/assurance-structure-docx.mjs +4 -2
- package/src/runtime/office/quality/design-review.mjs +1 -5
- package/src/runtime/office/quality/document-brief.mjs +1 -5
- package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
- package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +15 -6
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +11 -4
- package/src/runtime/shared/connector-catalog.mjs +60 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/defaults-separation.mjs +1 -4
- package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
- package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +13 -15
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/idle-auto-clear-gate.mjs +29 -7
- package/src/runtime/shared/llm/cost.mjs +11 -2
- package/src/runtime/shared/llm/http-agent.mjs +313 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +452 -0
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/model-route-chain.d.mts +7 -2
- package/src/runtime/shared/model-route-chain.mjs +22 -4
- package/src/runtime/shared/open-url.mjs +10 -0
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/session-activity-signal.mjs +14 -0
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
- package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
- package/src/runtime/shared/tool-result-summary.mjs +1 -1
- package/src/runtime/shared/tool-surface.mjs +113 -36
- package/src/runtime/shared/tool-work-units.mjs +6 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/turn-worktree-snapshot.mjs +414 -54
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +9 -3
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +72 -0
- package/src/runtime/shared/worktrees/manager.mjs +285 -168
- package/src/runtime/shared/worktrees/test-support.mjs +6 -10
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +7 -4
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +6 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +1 -1
- package/src/session-runtime/agent-home-delivery.mjs +41 -0
- package/src/session-runtime/agent-task-sessions.mjs +458 -312
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/tools.mjs +7 -1
- package/src/session-runtime/bot-status.mjs +107 -101
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +401 -36
- package/src/session-runtime/conversation-import/service.mjs +35 -8
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +12 -13
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +1 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -0
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +145 -112
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -1
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -1
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +16 -10
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-catalog-cache.mjs +82 -36
- package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
- package/src/session-runtime/provider-models.mjs +4 -2
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +44 -31
- package/src/session-runtime/resource-mcp-secrets.mjs +28 -11
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
- package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
- package/src/session-runtime/services/agent-tool/render.mjs +71 -17
- package/src/session-runtime/services/agent-tool/send-flow.mjs +10 -2
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +6 -2
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +10 -6
- package/src/session-runtime/services/provider-admin.mjs +283 -11
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +4 -1
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +6 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +2 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +1 -0
- package/src/session-runtime/turn/agent-ops.mjs +23 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +49 -11
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +25 -5
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +108 -1041
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +80 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +85 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +73 -56
- package/src/standalone/daemon-desktop-runtime.mjs +2 -0
- package/src/standalone/daemon-session-control.mjs +169 -138
- package/src/standalone/daemon.mjs +7 -0
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +5 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +3 -0
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +4 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/session-calls/session-action.mjs +10 -3
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/App.jsx +154 -164
- package/src/tui/app/app-view/floating-panel.jsx +10 -4
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +21 -10
- package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
- package/src/tui/app/model-picker/route-selection.mjs +5 -6
- package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +58 -21
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +29 -18
- package/src/tui/app/shell-layout/row-budgets.mjs +12 -10
- package/src/tui/app/slash-commands.mjs +1 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +46 -0
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +3 -2
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +47 -32
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +19 -5
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/dist/index.mjs +1963 -1361
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/routes-agent-definitions.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +11 -0
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
|
@@ -278,14 +278,21 @@ function currentSkillResolver(sessionRef, { preview = false } = {}) {
|
|
|
278
278
|
return (name) => {
|
|
279
279
|
const delivery = currentSkillDelivery(name, cwd, config, skills);
|
|
280
280
|
if (!delivery) return null;
|
|
281
|
-
if (preview) return { body: delivery.body, native: undefined };
|
|
282
281
|
const { resource } = delivery;
|
|
282
|
+
// The tools whose use counts as use of the skill: its tool dependencies,
|
|
283
|
+
// an MCP server as `mcp:<server>`.
|
|
284
|
+
const tools = (resource.toolDependencies || []).flatMap(({ type, value }) => {
|
|
285
|
+
if (type === 'tool') return [value];
|
|
286
|
+
if (type === 'mcp') return [`mcp:${value}`];
|
|
287
|
+
return [];
|
|
288
|
+
});
|
|
289
|
+
if (preview) return { body: delivery.body, native: undefined, tools };
|
|
283
290
|
const envelope = loadSkillToolDependencies(
|
|
284
291
|
buildSkillToolEnvelope(name, resource.content, resource.dir, resource),
|
|
285
292
|
sessionRef
|
|
286
293
|
);
|
|
287
294
|
const native = parseNativeToolSearchPayload('Skill', envelope.result);
|
|
288
|
-
return { body: delivery.body, native, summary: native?.summary ?? envelope.result };
|
|
295
|
+
return { body: delivery.body, native, summary: native?.summary ?? envelope.result, tools };
|
|
289
296
|
};
|
|
290
297
|
}
|
|
291
298
|
|
|
@@ -19,7 +19,7 @@ import { providerToolExclusionReason } from './provider-tool-exclusions.mjs';
|
|
|
19
19
|
import { workflowOverlayDenial } from '../manager/workflow-switch-notice.mjs';
|
|
20
20
|
import { agentMcpToolPermission, connectorPolicyAgentOf, projectMcpToolDisabled } from '../../mcp/agent-connectors.mjs';
|
|
21
21
|
|
|
22
|
-
const WORKER_DENIED_TOOLS = new Set(['agent', 'ask_user', 'session']);
|
|
22
|
+
const WORKER_DENIED_TOOLS = new Set(['agent', 'ask_user', 'handoff_user', 'session']);
|
|
23
23
|
const BRIDGE_DISCOVERY_TOOL_NAMES = new Set(['load_tool']);
|
|
24
24
|
|
|
25
25
|
const IMAGE_PATH_RE = /\.(?:png|jpe?g|gif|webp)(?:$|[?#])/i;
|
|
@@ -31,6 +31,13 @@ function exclusionsFor(sessionRef) {
|
|
|
31
31
|
|
|
32
32
|
const isSessionRef = (value) => value !== null && typeof value === 'object';
|
|
33
33
|
|
|
34
|
+
// A schema 400 drop holds for the schema rule that refused it: a route on
|
|
35
|
+
// another wire family (a fallback hop, a model switch) sends the tool again.
|
|
36
|
+
function droppedOnRoute(sessionRef, name) {
|
|
37
|
+
const entry = isSessionRef(sessionRef) ? sessions.get(sessionRef)?.dropped.get(String(name || '')) : null;
|
|
38
|
+
return entry && entry.family === routeSchemaFamily(sessionRef) ? entry : null;
|
|
39
|
+
}
|
|
40
|
+
|
|
34
41
|
/** A new provider request: exclusions describe the latest request only. */
|
|
35
42
|
export function beginProviderToolExclusions(sessionRef) {
|
|
36
43
|
if (isSessionRef(sessionRef)) sessions.get(sessionRef)?.current.clear();
|
|
@@ -64,15 +71,16 @@ export function providerToolExclusionReason(sessionRef, name) {
|
|
|
64
71
|
if (!isSessionRef(sessionRef)) return null;
|
|
65
72
|
const state = sessions.get(sessionRef);
|
|
66
73
|
const key = String(name || '');
|
|
67
|
-
const exclusion = state?.current.get(key) ||
|
|
74
|
+
const exclusion = state?.current.get(key) || droppedOnRoute(sessionRef, key);
|
|
68
75
|
return exclusion ? unavailableText(exclusion) : null;
|
|
69
76
|
}
|
|
70
77
|
|
|
71
78
|
/** The provider rejected `exclusion.name`'s schema with an HTTP 400: leave the
|
|
72
|
-
* tool out of
|
|
79
|
+
* tool out of the session's later requests on this wire family and tell the
|
|
80
|
+
* user once. */
|
|
73
81
|
export function dropSessionTool(sessionRef, exclusion, onStageChange) {
|
|
74
82
|
if (!isSessionRef(sessionRef)) return;
|
|
75
|
-
exclusionsFor(sessionRef).dropped.set(exclusion.name, exclusion);
|
|
83
|
+
exclusionsFor(sessionRef).dropped.set(exclusion.name, { ...exclusion, family: routeSchemaFamily(sessionRef) });
|
|
76
84
|
recordProviderToolExclusion(sessionRef, exclusion, onStageChange);
|
|
77
85
|
}
|
|
78
86
|
|
|
@@ -82,7 +90,7 @@ export function withoutDroppedTools(sessionRef, { sendTools, requestToolScope })
|
|
|
82
90
|
const dropped = isSessionRef(sessionRef) ? sessions.get(sessionRef)?.dropped : null;
|
|
83
91
|
if (!dropped?.size) return { sendTools, requestToolScope };
|
|
84
92
|
const prefix = providerNativeToolPrefixCount(sendTools);
|
|
85
|
-
const kept = sendTools.filter((tool, index) => index < prefix || !
|
|
93
|
+
const kept = sendTools.filter((tool, index) => index < prefix || !droppedOnRoute(sessionRef, tool?.name));
|
|
86
94
|
if (kept.length === sendTools.length) return { sendTools, requestToolScope };
|
|
87
95
|
const next = finalizeProviderRequestTools(kept, prefix);
|
|
88
96
|
return { sendTools: next, requestToolScope: { ...requestToolScope, requestTools: next } };
|
|
@@ -128,7 +136,7 @@ function schemaExclusion(session, family, tool) {
|
|
|
128
136
|
* tools are never excluded by the schema rule. */
|
|
129
137
|
export function routeToolExclusionReason(session, tool) {
|
|
130
138
|
if (!tool) return null;
|
|
131
|
-
const dropped =
|
|
139
|
+
const dropped = droppedOnRoute(session, tool.name);
|
|
132
140
|
if (dropped) return unavailableText(dropped);
|
|
133
141
|
const exclusion = schemaExclusion(session, routeSchemaFamily(session), tool);
|
|
134
142
|
return exclusion ? unavailableText(exclusion) : null;
|
|
@@ -17,6 +17,8 @@ import { buildRequestSendOptions } from '../manager/ask-turn-loop-options.mjs';
|
|
|
17
17
|
import { prepareTurnEffortConfiguration } from '../../providers/effort-configuration.mjs';
|
|
18
18
|
import { resolveSessionContextMeta } from '../manager/context-meta.mjs';
|
|
19
19
|
import { stripProviderReplayMessages } from '../manager/provider-replay.mjs';
|
|
20
|
+
import { isAgentOwner } from '../../agent-owner.mjs';
|
|
21
|
+
import { rebuildToolSurfaceForProviderWithMigration } from './tool-exposure-migration.mjs';
|
|
20
22
|
|
|
21
23
|
// The short reason a notice gives for leaving a model, by provider kind.
|
|
22
24
|
const HOP_REASONS = {
|
|
@@ -149,6 +151,11 @@ export async function advanceAgentRoute(state, error) {
|
|
|
149
151
|
updated.routeFallbackFailures = [...(session.routeFallbackFailures || []), failed];
|
|
150
152
|
await pinSessionWireRoute(updated, provider);
|
|
151
153
|
state.throwIfAborted();
|
|
154
|
+
// The route change replaced the session's tools with its whole resolved list.
|
|
155
|
+
// A delegated agent's surface was already re-applied by updateSessionRoute
|
|
156
|
+
// (applyAgentToolExposure); a Lead-class session gets its deferred surface
|
|
157
|
+
// restored for the new provider, as a manual model switch does.
|
|
158
|
+
if (!isAgentOwner(updated)) rebuildToolSurfaceForProviderWithMigration(updated, next.provider, state.messages);
|
|
152
159
|
// The live turn (prompt, assistant tool calls, tool results) carries on;
|
|
153
160
|
// only the previous provider's native replay state is dropped from it.
|
|
154
161
|
state.messages.splice(0, state.messages.length, ...stripProviderReplayMessages(state.messages));
|
|
@@ -164,6 +171,13 @@ export async function advanceAgentRoute(state, error) {
|
|
|
164
171
|
state.cacheBreakTraceKeys.clear();
|
|
165
172
|
state.transportRetriesUsed = 0;
|
|
166
173
|
state.transportRetryMax = 0;
|
|
174
|
+
// The one-shot recoveries the left model spent belong to its requests; the
|
|
175
|
+
// next model's first request gets its own (its window, images and schemas).
|
|
176
|
+
state.contextOverflowRetryUsed = false;
|
|
177
|
+
state.imageStripUsed = false;
|
|
178
|
+
state.imageStrip = null;
|
|
179
|
+
state.thinkingReplayRepairUsed = false;
|
|
180
|
+
state.toolSchemaDropUsed = false;
|
|
167
181
|
for (const key of Object.keys(oldOptions)) delete state.opts[key];
|
|
168
182
|
Object.assign(
|
|
169
183
|
state.opts,
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
* consume a retry verdict, and settle a completed send into the loop state.
|
|
5
5
|
*/
|
|
6
6
|
import { traceCacheBreak } from '../../cache-break-trace.mjs';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
anthropicPrefixChanges,
|
|
9
|
+
latestAnthropicPrefix,
|
|
10
|
+
persistableAnthropicPrefix,
|
|
11
|
+
seedAnthropicPrefix,
|
|
12
|
+
} from '../../providers/lib/anthropic-prefix-trace.mjs';
|
|
8
13
|
import { resolveLiveToolCwd } from './tool-exec.mjs';
|
|
9
14
|
import { notifySkillsApplied, prepareExplicitSkills, recordAppliedSkills } from '../explicit-skills.mjs';
|
|
10
15
|
import { addUsage, usageDeltaEvent } from './usage.mjs';
|
|
@@ -179,6 +184,9 @@ export async function sendProviderRequest(state, round) {
|
|
|
179
184
|
} catch {
|
|
180
185
|
// the send-started observer is advisory
|
|
181
186
|
}
|
|
187
|
+
// Diagnostic only: a restarted process compares its first request with the
|
|
188
|
+
// last prefix fingerprint the session record kept (anthropic-prefix-trace.mjs).
|
|
189
|
+
seedAnthropicPrefix(sessionId, sessionRef?.providerPrefixBaseline);
|
|
182
190
|
// The request a /btw side question forks: kept while it is in flight, with
|
|
183
191
|
// its reply once it proceeds, and dropped again if it fails.
|
|
184
192
|
const sideQuestion = captureSideQuestionRequest({
|
|
@@ -374,6 +382,10 @@ function traceActualCacheMiss(state, sent, response, { previousGuardState, previ
|
|
|
374
382
|
);
|
|
375
383
|
}
|
|
376
384
|
sessionRef.lastProviderCachedPrefixTokens = cachePrefixTokens;
|
|
385
|
+
// The fingerprint of this request survives a restart on the record, so the
|
|
386
|
+
// next process's first miss can still name what moved.
|
|
387
|
+
const fingerprint = persistableAnthropicPrefix(latestAnthropicPrefix(sessionId));
|
|
388
|
+
if (fingerprint) sessionRef.providerPrefixBaseline = fingerprint;
|
|
377
389
|
}
|
|
378
390
|
|
|
379
391
|
/** Fold a completed send into the state: prefix guard, image-strip
|
|
@@ -21,9 +21,20 @@ const isArgsObject = (value) => value && typeof value === 'object' && !Array.isA
|
|
|
21
21
|
|
|
22
22
|
async function askApproval(
|
|
23
23
|
call,
|
|
24
|
-
{
|
|
24
|
+
{
|
|
25
|
+
callerSessionId,
|
|
26
|
+
executeOpts,
|
|
27
|
+
toolApprovalHook,
|
|
28
|
+
decision,
|
|
29
|
+
request = null,
|
|
30
|
+
gate = null,
|
|
31
|
+
onApproved = null,
|
|
32
|
+
account = '',
|
|
33
|
+
}
|
|
25
34
|
) {
|
|
26
35
|
const askReason = String(decision?.reason || 'approval requested by hook').trim();
|
|
36
|
+
// The connector account the call is bound to rides on the card.
|
|
37
|
+
if (account) request = { ...(request || {}), account };
|
|
27
38
|
// While the user decides, the session is waiting on them, not working.
|
|
28
39
|
const releaseApprovalWait = beginSessionApprovalWait(callerSessionId);
|
|
29
40
|
let askOutcome;
|
|
@@ -72,9 +83,13 @@ export const CONNECTOR_APPROVAL_REASON = 'This connector tool is set to ask befo
|
|
|
72
83
|
* remembered outbound grant answered it) is not asked a second time. With the
|
|
73
84
|
* "Allow all actions" developer option on, `needs_approval` is not asked
|
|
74
85
|
* either (a payment or permanent delete was asked by the outbound gate above).
|
|
86
|
+
* `account` is the connector account the call is bound to, for the card.
|
|
75
87
|
* @returns {Promise<{ denial: string } | null>} the denial, or null to run
|
|
76
88
|
*/
|
|
77
|
-
export function applyConnectorApproval(
|
|
89
|
+
export function applyConnectorApproval(
|
|
90
|
+
call,
|
|
91
|
+
{ agentId, callerSessionId, executeOpts, toolApprovalHook, account = '' }
|
|
92
|
+
) {
|
|
78
93
|
if (call.outboundApproved) return null;
|
|
79
94
|
if (!actingBotId(callerSessionId)) return null;
|
|
80
95
|
if (agentMcpToolPermission(agentId, call.name) !== 'needs_approval') return null;
|
|
@@ -89,6 +104,7 @@ export function applyConnectorApproval(call, { agentId, callerSessionId, execute
|
|
|
89
104
|
toolApprovalHook,
|
|
90
105
|
decision: { reason: CONNECTOR_APPROVAL_REASON },
|
|
91
106
|
request: rememberable ? { kind: 'approval', agentId: botId, remember: ['once', 'agent'] } : null,
|
|
107
|
+
account,
|
|
92
108
|
onApproved: async (approval) => {
|
|
93
109
|
if (!rememberable || approval?.remember !== 'agent') return;
|
|
94
110
|
try {
|
|
@@ -130,10 +146,11 @@ export async function applyBeforeToolHook({
|
|
|
130
146
|
beforeToolHook,
|
|
131
147
|
toolApprovalHook,
|
|
132
148
|
mcpScopeId = null,
|
|
149
|
+
account = '',
|
|
133
150
|
}) {
|
|
134
151
|
const call = { name, args, cwd };
|
|
135
|
-
// ask_user
|
|
136
|
-
if (name === 'ask_user') return call;
|
|
152
|
+
// ask_user and handoff_user are themselves the user prompt; they never go through the ordinary approval gate.
|
|
153
|
+
if (name === 'ask_user' || name === 'handoff_user') return call;
|
|
137
154
|
try {
|
|
138
155
|
const hookDecision = beforeToolHook
|
|
139
156
|
? await runAbortable(executeOpts.signal, () =>
|
|
@@ -183,6 +200,8 @@ export async function applyBeforeToolHook({
|
|
|
183
200
|
decision,
|
|
184
201
|
request,
|
|
185
202
|
gate,
|
|
203
|
+
// Only while the call is still the one bound to it.
|
|
204
|
+
account: call.name === name ? account : '',
|
|
186
205
|
});
|
|
187
206
|
if (denied) return denied;
|
|
188
207
|
}
|
|
@@ -67,6 +67,8 @@ function dispatchMcp(name, args, { cwd, callerSessionId, sessionRef, executeOpts
|
|
|
67
67
|
signal: executeOpts.signal || null,
|
|
68
68
|
ownerKey: callerSessionId,
|
|
69
69
|
scopeId: mcpScopeId,
|
|
70
|
+
// A connector account defaults to (and becomes) this conversation's last used.
|
|
71
|
+
conversation: callerSessionId,
|
|
70
72
|
});
|
|
71
73
|
if (!isBuiltinMailRead(name, mcpScopeId)) return call;
|
|
72
74
|
// The runtime's own record of the links in a mail it read for this session:
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// tool-exec/dispatch.mjs — executor per tool family
|
|
6
6
|
// tool-exec/after-hook.mjs — PostToolUse result override
|
|
7
7
|
// tool-exec/read-only-deadline.mjs — bounded read-only I/O with partial-output grace
|
|
8
|
-
import { isMcpTool } from '../../mcp/client.mjs';
|
|
8
|
+
import { isMcpTool, resolveMcpToolAccount } from '../../mcp/client.mjs';
|
|
9
9
|
import { connectorPolicyAgentOf } from '../../mcp/agent-connectors.mjs';
|
|
10
10
|
import { prepareDeferredToolCallThrough } from './deferred-call-through.mjs';
|
|
11
11
|
import { refreshDeferredMcpToolCatalog } from '../../runtime-core/tool-catalog.mjs';
|
|
@@ -58,6 +58,24 @@ async function executeToolOwned(name, args, cwd, callerSessionId, sessionRef, ex
|
|
|
58
58
|
callArgs = guarded.args;
|
|
59
59
|
completionToolOpts.shellGuardNotes = guarded.notes;
|
|
60
60
|
}
|
|
61
|
+
// A connector call is bound to its account before any hook or card sees it,
|
|
62
|
+
// so an approval approves that account, whatever is used last meanwhile.
|
|
63
|
+
// It is bound by its unique name; `account` is its label, for display.
|
|
64
|
+
let bound = '';
|
|
65
|
+
let account = '';
|
|
66
|
+
if (isMcpTool(name)) {
|
|
67
|
+
try {
|
|
68
|
+
const chosen = resolveMcpToolAccount(name, callArgs, {
|
|
69
|
+
scopeId: sessionRef?.mcpScopeId || null,
|
|
70
|
+
conversation: callerSessionId,
|
|
71
|
+
});
|
|
72
|
+
bound = chosen?.name || '';
|
|
73
|
+
account = chosen?.label || '';
|
|
74
|
+
} catch (error) {
|
|
75
|
+
return `Error: ${error?.message || String(error)}`;
|
|
76
|
+
}
|
|
77
|
+
if (bound) callArgs = { ...callArgs, account: bound };
|
|
78
|
+
}
|
|
61
79
|
const hooked = await applyBeforeToolHook({
|
|
62
80
|
name,
|
|
63
81
|
args: callArgs,
|
|
@@ -67,6 +85,7 @@ async function executeToolOwned(name, args, cwd, callerSessionId, sessionRef, ex
|
|
|
67
85
|
beforeToolHook: hookFrom(executeOpts, sessionRef, 'beforeToolHook'),
|
|
68
86
|
toolApprovalHook,
|
|
69
87
|
mcpScopeId: sessionRef?.mcpScopeId || null,
|
|
88
|
+
account,
|
|
70
89
|
});
|
|
71
90
|
if (hooked.denial) return hooked.denial;
|
|
72
91
|
const connectorDenied = await applyConnectorApproval(hooked, {
|
|
@@ -74,8 +93,11 @@ async function executeToolOwned(name, args, cwd, callerSessionId, sessionRef, ex
|
|
|
74
93
|
callerSessionId,
|
|
75
94
|
executeOpts,
|
|
76
95
|
toolApprovalHook,
|
|
96
|
+
account: hooked.name === name ? account : '',
|
|
77
97
|
});
|
|
78
98
|
if (connectorDenied) return connectorDenied.denial;
|
|
99
|
+
// A hook's rewrite of the same tool keeps the bound account.
|
|
100
|
+
if (bound && hooked.name === name) hooked.args = { ...hooked.args, account: bound };
|
|
79
101
|
// A decision can settle after its turn was cancelled. It must never
|
|
80
102
|
// authorize a new mutation, even if the hook ignores the abort signal.
|
|
81
103
|
throwIfAborted(executeOpts.signal);
|
|
@@ -46,12 +46,44 @@ export function markToolSurfaceMigrated(session, intent = TOOL_SURFACE_MIGRATION
|
|
|
46
46
|
session.pendingCacheBreakIntent = intent;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
/**
|
|
50
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Run `apply` with `messages` (the transcript a running turn works on) as the
|
|
51
|
+
* session's messages, so a fixed-guidance rewrite lands there; the canonical
|
|
52
|
+
* transcript takes the rewritten system prefix. Without `messages`, `apply`
|
|
53
|
+
* runs on the session's own. `apply` runs synchronously.
|
|
54
|
+
*/
|
|
55
|
+
function applyOnWorkingMessages(session, messages, apply) {
|
|
56
|
+
const stored = session.messages;
|
|
57
|
+
const working = Array.isArray(messages) ? messages : stored;
|
|
58
|
+
if (Array.isArray(working)) session.messages = working;
|
|
59
|
+
try {
|
|
60
|
+
apply();
|
|
61
|
+
} finally {
|
|
62
|
+
if (Array.isArray(working) && session.messages !== working) {
|
|
63
|
+
// The rewrite may drop an emptied system message: keep the array
|
|
64
|
+
// identity the request loop holds.
|
|
65
|
+
working.splice(0, working.length, ...session.messages);
|
|
66
|
+
}
|
|
67
|
+
session.messages = stored;
|
|
68
|
+
}
|
|
69
|
+
// The rewritten prompt messages are fresh objects; the canonical transcript
|
|
70
|
+
// the save path persists takes them too, so the next save writes the new
|
|
71
|
+
// prompt together with the new exposure.
|
|
72
|
+
if (Array.isArray(stored) && Array.isArray(working) && stored !== working) syncSystemPrefix(stored, working);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Provider switch: rebuild the surface for `provider`, migrating bridge ↔
|
|
77
|
+
* native. `messages`: the running turn's transcript, when a switch happens
|
|
78
|
+
* mid-turn (a route fallback hop).
|
|
79
|
+
*/
|
|
80
|
+
export function rebuildToolSurfaceForProviderWithMigration(session, provider, messages) {
|
|
51
81
|
if (!session) return false;
|
|
52
82
|
const migrating = toolExposureMigrationNeeded(session, provider);
|
|
53
|
-
|
|
54
|
-
|
|
83
|
+
applyOnWorkingMessages(session, messages, () => {
|
|
84
|
+
rebuildDeferredToolSurfaceForProvider(session, provider);
|
|
85
|
+
if (migrating) markToolSurfaceMigrated(session);
|
|
86
|
+
});
|
|
55
87
|
return migrating;
|
|
56
88
|
}
|
|
57
89
|
|
|
@@ -75,26 +107,12 @@ function hasUnansweredToolCalls(messages) {
|
|
|
75
107
|
*/
|
|
76
108
|
export function migrateToolExposureAtBoundary(session, messages) {
|
|
77
109
|
if (!session || !toolExposureMigrationNeeded(session) || hasUnansweredToolCalls(messages)) return false;
|
|
78
|
-
|
|
79
|
-
const working = Array.isArray(messages) ? messages : stored;
|
|
80
|
-
if (Array.isArray(working)) session.messages = working;
|
|
81
|
-
try {
|
|
110
|
+
applyOnWorkingMessages(session, messages, () =>
|
|
82
111
|
applyDeferredToolSurface(session, session.deferredSurfaceMode || 'lead', [], {
|
|
83
112
|
provider: session.provider,
|
|
84
113
|
model: session.model,
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
if (Array.isArray(working) && session.messages !== working) {
|
|
88
|
-
// The rewrite may drop an emptied system message: keep the request
|
|
89
|
-
// transcript array identity the loop holds.
|
|
90
|
-
working.splice(0, working.length, ...session.messages);
|
|
91
|
-
}
|
|
92
|
-
session.messages = stored;
|
|
93
|
-
}
|
|
94
|
-
// The rewritten prompt messages are fresh objects; the canonical transcript
|
|
95
|
-
// the save path persists takes them too, so the next save writes the new
|
|
96
|
-
// prompt together with the new exposure.
|
|
97
|
-
if (Array.isArray(stored) && Array.isArray(working) && stored !== working) syncSystemPrefix(stored, working);
|
|
114
|
+
})
|
|
115
|
+
);
|
|
98
116
|
invalidateForToolSurfaceMigration(session);
|
|
99
117
|
return true;
|
|
100
118
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* turn-limits.mjs — a turn's caps (sendOpts.turnLimits; a heartbeat turn's,
|
|
3
|
-
* manager/ask-turn-loop-options.mjs): `maxToolCalls` tool calls
|
|
4
|
-
* `wrapUpAt` (epoch ms)
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
3
|
+
* manager/ask-turn-loop-options.mjs): `maxToolCalls` tool calls,
|
|
4
|
+
* `wrapUpAt` (epoch ms) and `maxToolRounds` tool-calling responses (an
|
|
5
|
+
* explorer's, runtime/explore/explorer.mjs). A call past the cap, or one made
|
|
6
|
+
* after the wrap-up time, is answered without running. Once a cap is reached
|
|
7
|
+
* the model is told to reply, and every later request of the turn forbids
|
|
8
|
+
* tool use (toolChoice 'none'). A response that still calls tools after that
|
|
9
|
+
* ends the turn with no reply, its calls answered unrun. A turn capped by
|
|
10
|
+
* calls or time runs no call eagerly (eager-dispatch.mjs), so none past the
|
|
11
|
+
* cap starts while streaming; a round cap cuts only between rounds.
|
|
10
12
|
*/
|
|
11
13
|
|
|
12
14
|
const NOTICE =
|
|
@@ -21,6 +23,8 @@ export function turnLimitsOf(opts) {
|
|
|
21
23
|
return {
|
|
22
24
|
maxToolCalls: Number.isInteger(limits.maxToolCalls) && limits.maxToolCalls >= 0 ? limits.maxToolCalls : Infinity,
|
|
23
25
|
wrapUpAt: Number.isFinite(limits.wrapUpAt) ? limits.wrapUpAt : Infinity,
|
|
26
|
+
maxToolRounds:
|
|
27
|
+
Number.isInteger(limits.maxToolRounds) && limits.maxToolRounds >= 0 ? limits.maxToolRounds : Infinity,
|
|
24
28
|
};
|
|
25
29
|
}
|
|
26
30
|
|
|
@@ -49,7 +53,8 @@ export function settleTurnLimits(state, overrun, now = Date.now()) {
|
|
|
49
53
|
}
|
|
50
54
|
const limits = turnLimitsOf(state.opts);
|
|
51
55
|
if (!limits || state.turnLimitNoticed) return;
|
|
52
|
-
if (state.toolCallsTotal < limits.maxToolCalls && now < limits.wrapUpAt)
|
|
56
|
+
if (state.toolCallsTotal < limits.maxToolCalls && now < limits.wrapUpAt && state.iterations < limits.maxToolRounds)
|
|
57
|
+
return;
|
|
53
58
|
state.turnLimitNoticed = true;
|
|
54
59
|
state.messages.push({ role: 'user', content: NOTICE, meta: { source: 'turn-limit' } });
|
|
55
60
|
}
|
|
@@ -19,6 +19,7 @@ import { armTurnDurability, claimTurnRuntime } from './ask-turn-open.mjs';
|
|
|
19
19
|
import { prepareAskTurn, runAskAgentLoop } from './ask-turn-execute.mjs';
|
|
20
20
|
import { commitAskTurn, publishAskTurn } from './ask-turn-settle.mjs';
|
|
21
21
|
import { finalizeAskTurnFailure } from './ask-turn-failure.mjs';
|
|
22
|
+
import { armTurnTimeoutOnProviderError, reapTurnShellJobs } from './turn-reap.mjs';
|
|
22
23
|
import { cacheWarmTurnKind, endCacheWarmTurn, failedTurnProvenance, noteCacheWarmTurn } from '../cache-warm.mjs';
|
|
23
24
|
|
|
24
25
|
export { _api_call_with_interrupt } from './ask-call-interrupt.mjs';
|
|
@@ -125,6 +126,9 @@ async function runAskTurn({ sessionId, opened, input, askOpts, onToolCall, cwdOv
|
|
|
125
126
|
});
|
|
126
127
|
return { result: terminalResultPreview, drained };
|
|
127
128
|
} catch (err) {
|
|
129
|
+
// The turn's terminal error: a provider timeout/stall that ended it (a
|
|
130
|
+
// retry the turn recovered from never reaches here) stops its shell work.
|
|
131
|
+
armTurnTimeoutOnProviderError(sessionId, opened.runtime, opened.turnSignal, err);
|
|
128
132
|
await finalizeAskTurnFailure({
|
|
129
133
|
sessionId,
|
|
130
134
|
err,
|
|
@@ -138,12 +142,49 @@ async function runAskTurn({ sessionId, opened, input, askOpts, onToolCall, cwdOv
|
|
|
138
142
|
transcriptMeta: transcript.raw,
|
|
139
143
|
askStartedAt,
|
|
140
144
|
});
|
|
145
|
+
reapTurnShellJobs(sessionId, opened.runtime);
|
|
141
146
|
throw err;
|
|
142
147
|
} finally {
|
|
143
|
-
|
|
148
|
+
// The result is already published; this only holds the session lock until
|
|
149
|
+
// the reader lease is removed, so the next turn's admission follows it. A
|
|
150
|
+
// failed release (the admission thread stopped) never replaces the turn's
|
|
151
|
+
// own outcome.
|
|
152
|
+
try {
|
|
153
|
+
await releaseWorkspace?.();
|
|
154
|
+
} catch {
|
|
155
|
+
// Intentionally ignored: see the comment above.
|
|
156
|
+
}
|
|
144
157
|
}
|
|
145
158
|
}
|
|
146
159
|
|
|
160
|
+
/** The prompt-cache warmer learns idle gaps from real turns only; a retry is
|
|
161
|
+
* classified by the failed turn's stored provenance. The rebuilt retry
|
|
162
|
+
* message keeps that provenance (ask-turn-execute.mjs). Returns the warmer's
|
|
163
|
+
* turn handle. */
|
|
164
|
+
function noteTurnForCacheWarm(sessionId, claimed, input) {
|
|
165
|
+
const retryProvenance = failedTurnProvenance(claimed.preSession?.messages, input);
|
|
166
|
+
if (retryProvenance) input.retryProvenance = retryProvenance;
|
|
167
|
+
return noteCacheWarmTurn(sessionId, cacheWarmTurnKind(input, claimed.preSession?.messages));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Clear the controller only if it's still ours (closeSession may have
|
|
171
|
+
* swapped it). The rest of the runtime entry stays intact so agent type=list
|
|
172
|
+
* can still surface the final stage (done/error/cancelling). */
|
|
173
|
+
function detachAskRuntime(sessionId, askGeneration) {
|
|
174
|
+
const entry = _getRuntimeEntry(sessionId);
|
|
175
|
+
if (entry && entry.generation === askGeneration) {
|
|
176
|
+
_unlinkParentAbortListener(entry);
|
|
177
|
+
entry.controller = null;
|
|
178
|
+
// Detach the live session reference; ask is over.
|
|
179
|
+
entry.session = null;
|
|
180
|
+
}
|
|
181
|
+
// Final-stage runtime diagnostics are useful only while the turn is
|
|
182
|
+
// unwinding. Once its controller is detached, retaining the full entry
|
|
183
|
+
// (and any accidental references hanging from it) for the host lifetime
|
|
184
|
+
// turns one-shot agent traffic into an unbounded manager Map.
|
|
185
|
+
_evictTerminalSessionRuntime(sessionId);
|
|
186
|
+
}
|
|
187
|
+
|
|
147
188
|
export async function askSession(sessionId, prompt, context, onToolCall, cwdOverride, explicitPrefetch, askOpts = {}) {
|
|
148
189
|
const askStartedAt = Date.now();
|
|
149
190
|
const transcript = createAskTranscriptMeta(askOpts?.transcriptMeta);
|
|
@@ -180,8 +221,9 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
180
221
|
// Hoisted so the outer finally (which runs once after the whole turn loop)
|
|
181
222
|
// can compare against the last turn's generation.
|
|
182
223
|
let askGeneration = 0;
|
|
183
|
-
|
|
184
|
-
|
|
224
|
+
// Crash-checkpoint recovery and the session-start event belong to the first
|
|
225
|
+
// turn of this ask only.
|
|
226
|
+
let firstTurn = true;
|
|
185
227
|
// A failed-turn retry rewinds only the turn it retries, never a drained
|
|
186
228
|
// follow-up turn.
|
|
187
229
|
let retryFailedTurn = askOpts.retryFailedTurn === true;
|
|
@@ -218,17 +260,11 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
218
260
|
const claimed = claimTurnRuntime({
|
|
219
261
|
sessionId,
|
|
220
262
|
askOpts,
|
|
221
|
-
recoverCheckpoint:
|
|
222
|
-
emitStart:
|
|
263
|
+
recoverCheckpoint: firstTurn,
|
|
264
|
+
emitStart: firstTurn,
|
|
223
265
|
});
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
// The rebuilt retry message keeps that provenance (ask-turn-execute.mjs).
|
|
227
|
-
const retryProvenance = failedTurnProvenance(claimed.preSession?.messages, input);
|
|
228
|
-
if (retryProvenance) input.retryProvenance = retryProvenance;
|
|
229
|
-
warmTurn = noteCacheWarmTurn(sessionId, cacheWarmTurnKind(input, claimed.preSession?.messages));
|
|
230
|
-
crashRecoveryChecked = true;
|
|
231
|
-
sessionStartEmitted = true;
|
|
266
|
+
warmTurn = noteTurnForCacheWarm(sessionId, claimed, input);
|
|
267
|
+
firstTurn = false;
|
|
232
268
|
askGeneration = claimed.askGeneration;
|
|
233
269
|
const opened = {
|
|
234
270
|
...claimed,
|
|
@@ -287,21 +323,7 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
287
323
|
queue.releaseUnstarted();
|
|
288
324
|
// A thrown setup/provider path must never leave a delayed checkpoint
|
|
289
325
|
// writer alive after the turn lock is released.
|
|
290
|
-
|
|
291
|
-
// swapped it). Leave the rest of the runtime entry intact so agent type=list
|
|
292
|
-
// can still surface the final stage (done/error/cancelling).
|
|
293
|
-
const entry = _getRuntimeEntry(sessionId);
|
|
294
|
-
if (entry && entry.generation === askGeneration) {
|
|
295
|
-
_unlinkParentAbortListener(entry);
|
|
296
|
-
entry.controller = null;
|
|
297
|
-
// Detach the live session reference; ask is over.
|
|
298
|
-
entry.session = null;
|
|
299
|
-
}
|
|
300
|
-
// Final-stage runtime diagnostics are useful only while the turn is
|
|
301
|
-
// unwinding. Once its controller is detached, retaining the full entry
|
|
302
|
-
// (and any accidental references hanging from it) for the host lifetime
|
|
303
|
-
// turns one-shot agent traffic into an unbounded manager Map.
|
|
304
|
-
_evictTerminalSessionRuntime(sessionId);
|
|
326
|
+
detachAskRuntime(sessionId, askGeneration);
|
|
305
327
|
unlock();
|
|
306
328
|
}
|
|
307
329
|
}
|
|
@@ -231,9 +231,9 @@ export function buildAgentLoopOptions({
|
|
|
231
231
|
},
|
|
232
232
|
onStreamDelta: (kind = 'semantic') => {
|
|
233
233
|
markSessionStreamDelta(sessionId, kind).catch(() => {});
|
|
234
|
-
// Raw transport
|
|
235
|
-
// Preserve the public callback's historical semantic-only contract.
|
|
236
|
-
if (kind !== 'transport') relay(askOpts?.onStreamDelta, kind);
|
|
234
|
+
// Raw transport and keepalives are internal health signals, not model
|
|
235
|
+
// progress. Preserve the public callback's historical semantic-only contract.
|
|
236
|
+
if (kind !== 'transport' && kind !== 'keepalive') relay(askOpts?.onStreamDelta, kind);
|
|
237
237
|
},
|
|
238
238
|
};
|
|
239
239
|
}
|
|
@@ -225,7 +225,9 @@ export function publishAskTurn({ sessionId, opened, terminalResultPreview, askOp
|
|
|
225
225
|
// (which inspects entry.emptyFinal first) classifies the
|
|
226
226
|
// terminal state correctly even if it ticks during unwind.
|
|
227
227
|
const isEmptyFinal =
|
|
228
|
-
!terminalResultPreview.content &&
|
|
228
|
+
!terminalResultPreview.content &&
|
|
229
|
+
!terminalResultPreview.reasoningContent &&
|
|
230
|
+
!terminalResultPreview.reactionCompleted;
|
|
229
231
|
if (isEmptyFinal) {
|
|
230
232
|
markSessionEmptyFinal(sessionId);
|
|
231
233
|
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import { loadConfig } from '../../config.mjs';
|
|
14
14
|
import { findPreset } from '../../runtime-core/config-helpers.mjs';
|
|
15
15
|
import { normalizeWorkflowRoute } from '../../runtime-core/workflow.mjs';
|
|
16
|
-
import { canonicalRouteProvider } from '../../../../shared/model-route-chain.mjs';
|
|
16
|
+
import { canonicalRouteProvider, executionFallbacks } from '../../../../shared/model-route-chain.mjs';
|
|
17
17
|
import { storedBotRoute } from '../../../../shared/agent-store.mjs';
|
|
18
18
|
import { configuredAgentRouteCandidates } from '../../../../shared/agent-route-config.mjs';
|
|
19
19
|
import { CODING_MODE } from '../agent-mode.mjs';
|
|
@@ -48,5 +48,5 @@ export function ownerConfiguredRoute({ sessionMode, agentId, config = null }) {
|
|
|
48
48
|
export function ownerRouteFallbacks({ sessionMode, agentId, provider, model, config = null }) {
|
|
49
49
|
const route = ownerConfiguredRoute({ sessionMode, agentId, config });
|
|
50
50
|
if (!route?.fallbacks?.length) return [];
|
|
51
|
-
return sameRouteModel(route, { provider, model }) ? route
|
|
51
|
+
return sameRouteModel(route, { provider, model }) ? executionFallbacks(route) : [];
|
|
52
52
|
}
|
|
@@ -578,6 +578,7 @@ function isReferenceFilesMessage(message) {
|
|
|
578
578
|
}
|
|
579
579
|
|
|
580
580
|
export { isProtectedContextUserMessage };
|
|
581
|
+
export { BP3_PART_SEPARATOR, bp3SystemMessage, bpEnvSystemMessage, replaceSystemMessageContent };
|
|
581
582
|
|
|
582
583
|
// Compact summary messages (role:'user', content startsWith SUMMARY_PREFIX)
|
|
583
584
|
// are synthetic anchors, not a real human turn — they must not count as
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { findPreset } from '../../runtime-core/config-helpers.mjs';
|
|
13
13
|
import { normalizeWorkflowRoute } from '../../runtime-core/workflow.mjs';
|
|
14
14
|
import { configuredAgentRouteCandidates } from '../../../../shared/agent-route-config.mjs';
|
|
15
|
+
import { executionFallbacks } from '../../../../shared/model-route-chain.mjs';
|
|
15
16
|
import { CODING_MODE, resolveSessionMode } from '../agent-mode.mjs';
|
|
16
17
|
import { _liveSessions } from '../store/live-state.mjs';
|
|
17
18
|
import { ownerConfiguredRoute, sameRouteModel } from './owner-route-fallbacks.mjs';
|
|
@@ -64,7 +65,7 @@ export function liveRouteFallbacks(session, config) {
|
|
|
64
65
|
if (!source)
|
|
65
66
|
return { chain: Array.isArray(session?.routeFallbacks) ? session.routeFallbacks : [], fromSettings: false };
|
|
66
67
|
const onSourcePrimary = sameRouteModel(source, sessionRoutePrimary(session));
|
|
67
|
-
return { chain: onSourcePrimary ? source
|
|
68
|
+
return { chain: onSourcePrimary ? executionFallbacks(source) : [], fromSettings: true };
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
/** Index in `chain` of the next route to try: the first after the session's
|