mixdog 1.3.5 → 1.4.1
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/NOTICE.md +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/check-voice-runtime-inputs.mjs +25 -0
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +16 -5
- package/scripts/latest-guard.mjs +21 -9
- package/scripts/lib/isolated-test-env.mjs +10 -5
- package/scripts/lib/run-node-tests.mjs +37 -37
- package/scripts/lib/scoped-temp.d.mts +16 -0
- package/scripts/lib/scoped-temp.mjs +123 -0
- package/scripts/lib/stale-temp.mjs +44 -0
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/post-release-check.mjs +1 -6
- package/scripts/pptx-kit-index.mjs +17 -4
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +20 -2
- package/scripts/test-data-dir.mjs +10 -7
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/app.mjs +4 -0
- package/src/defaults/shipped-history.json +22 -1
- package/src/defaults/skills/browser-use/SKILL.md +62 -12
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +35 -9
- package/src/defaults/skills/setup/SKILL.md +22 -0
- package/src/defaults/skills/setup/references/actions.md +39 -5
- package/src/defaults/skills/setup/references/surfaces.md +11 -2
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/rules-builder.cjs +39 -20
- package/src/output-styles/common.md +2 -2
- package/src/output-styles/simple.md +1 -1
- package/src/rules/agent/AGENT.md +11 -10
- package/src/rules/lead/LEAD.md +23 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +4 -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 +7 -5
- package/src/rules/shared/70-delivery.md +7 -9
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/config.mjs +17 -1
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +73 -68
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
- package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- 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 +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
- 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-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
- 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 +136 -5
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +49 -16
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
- 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 +280 -45
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
- 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 +90 -22
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +51 -25
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
- 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 +31 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +49 -21
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- 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/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +24 -14
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +130 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +79 -3
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
- package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
- 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/shell-runtime.mjs +7 -1
- 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/shell-warm-standby.mjs +26 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/scheduler.mjs +33 -147
- package/src/runtime/channels/lib/schedules-db.mjs +34 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
- package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/whisper-port.mjs +10 -1
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +10 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +28 -2
- 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/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- 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/lib/embedding-worker.mjs +6 -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/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- 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 +3 -1
- 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/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bot-owned-work.mjs +56 -0
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +2 -13
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +29 -0
- package/src/runtime/shared/connector-catalog.mjs +150 -0
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -17
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- 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-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
- package/src/runtime/shared/handoff-artifacts.mjs +18 -8
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +126 -0
- package/src/runtime/shared/llm/cost.mjs +5 -1
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/loopback-listener.mjs +25 -2
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- 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/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +7 -1
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +10 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +48 -1
- package/src/runtime/shared/session-scratch.mjs +37 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- 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 +2 -15
- package/src/runtime/shared/tool-surface.mjs +3 -0
- package/src/runtime/shared/tool-work-units.mjs +2 -0
- package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
- package/src/runtime/shared/worktrees/contract.mjs +4 -1
- package/src/runtime/shared/worktrees/git.mjs +15 -0
- package/src/runtime/shared/worktrees/manager.mjs +87 -38
- package/src/runtime/shared/worktrees/test-support.mjs +14 -13
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +29 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +489 -185
- package/src/session-runtime/agent-task-sessions.mjs +467 -229
- package/src/session-runtime/agent-tool-routing.mjs +8 -41
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +11 -2
- package/src/session-runtime/bot-status.mjs +12 -6
- package/src/session-runtime/bot-target.mjs +38 -0
- package/src/session-runtime/channel-config-api.mjs +6 -1
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
- package/src/session-runtime/conversation-import/discovery.mjs +271 -25
- package/src/session-runtime/conversation-import/service.mjs +26 -5
- package/src/session-runtime/handoff-attachments.mjs +82 -31
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +153 -33
- package/src/session-runtime/model-route/set-route.mjs +11 -2
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +2 -1
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- 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 +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/resource-recall-api.mjs +6 -1
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/runtime-feature-gates.mjs +5 -1
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- 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/spawn-preset.mjs +13 -4
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +7 -13
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/provider-admin.mjs +2 -1
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +13 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +145 -22
- package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +17 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/session-runtime/workspace/transitions.mjs +25 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +142 -190
- package/src/standalone/daemon.mjs +26 -3
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +30 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
- package/src/tui/app/app-view/floating-panel.jsx +7 -4
- package/src/tui/app/model-options.mjs +3 -28
- 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/provider-setup/oauth-actions.mjs +38 -20
- package/src/tui/app/provider-setup/provider-items.mjs +8 -2
- package/src/tui/app/provider-setup-picker.mjs +9 -5
- package/src/tui/components/QuestionPanel.jsx +13 -4
- package/src/tui/dist/index.mjs +133 -92
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +7 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +17 -1
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +16 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +19 -2
- package/src/tui/session/turn.mjs +1 -0
- package/src/ui/statusline-agents.mjs +1 -3
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
|
@@ -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;
|
|
@@ -6,11 +6,19 @@ import { getProvider, initProviders } from '../../providers/registry.mjs';
|
|
|
6
6
|
import { loadConfig } from '../../config.mjs';
|
|
7
7
|
import { ensureProviderEnabled } from '../../runtime-core/config-helpers.mjs';
|
|
8
8
|
import { updateSessionRoute } from '../manager/session-lifecycle.mjs';
|
|
9
|
+
import {
|
|
10
|
+
liveRouteFallbacks,
|
|
11
|
+
nextRouteFallbackIndex,
|
|
12
|
+
routeFallbackHopped,
|
|
13
|
+
routeLeaf,
|
|
14
|
+
} from '../manager/route-fallback-chain.mjs';
|
|
9
15
|
import { pinSessionWireRoute } from '../../providers/wire-route.mjs';
|
|
10
16
|
import { buildRequestSendOptions } from '../manager/ask-turn-loop-options.mjs';
|
|
11
17
|
import { prepareTurnEffortConfiguration } from '../../providers/effort-configuration.mjs';
|
|
12
18
|
import { resolveSessionContextMeta } from '../manager/context-meta.mjs';
|
|
13
19
|
import { stripProviderReplayMessages } from '../manager/provider-replay.mjs';
|
|
20
|
+
import { isAgentOwner } from '../../agent-owner.mjs';
|
|
21
|
+
import { rebuildToolSurfaceForProviderWithMigration } from './tool-exposure-migration.mjs';
|
|
14
22
|
|
|
15
23
|
// The short reason a notice gives for leaving a model, by provider kind.
|
|
16
24
|
const HOP_REASONS = {
|
|
@@ -78,9 +86,13 @@ async function nextContextGrows(state, next) {
|
|
|
78
86
|
|
|
79
87
|
export async function advanceAgentRoute(state, error) {
|
|
80
88
|
const session = state.sessionRef;
|
|
81
|
-
if (!session?.agent
|
|
82
|
-
|
|
83
|
-
|
|
89
|
+
if (!session?.agent) return false;
|
|
90
|
+
// Read from the session's settings at this hop: a chain edited while it runs
|
|
91
|
+
// applies now, and one cleared to [] leaves the provider's own error.
|
|
92
|
+
const { chain } = liveRouteFallbacks(session, loadConfig({ secrets: false }));
|
|
93
|
+
if (!chain.length) return false;
|
|
94
|
+
const index = nextRouteFallbackIndex(session, chain);
|
|
95
|
+
const next = chain[index];
|
|
84
96
|
// Only THIS request must have produced nothing (its stream outcome says so):
|
|
85
97
|
// earlier requests of the turn may have run tools. Their calls and results
|
|
86
98
|
// are already in the live turn, which the next model continues from, so no
|
|
@@ -97,6 +109,8 @@ export async function advanceAgentRoute(state, error) {
|
|
|
97
109
|
const provider = getProvider(next.provider);
|
|
98
110
|
if (!provider) throw new Error(`Provider "${next.provider}" not available`);
|
|
99
111
|
const failed = routeFailure(session, error);
|
|
112
|
+
// The route a reset returns to (setup reset_route_fallback), kept from the first hop.
|
|
113
|
+
const primary = routeFallbackHopped(session) ? session.routeFallbackPrimary : routeLeaf(session);
|
|
100
114
|
// The left model's share of the turn ends here: the running total at the
|
|
101
115
|
// switch bounds it, so each model's tokens are booked at its own rates.
|
|
102
116
|
state.routeUsageHops = [
|
|
@@ -131,10 +145,17 @@ export async function advanceAgentRoute(state, error) {
|
|
|
131
145
|
{ crossProvider: true, session }
|
|
132
146
|
);
|
|
133
147
|
if (!updated) throw new Error('agent session closed during model fallback');
|
|
148
|
+
updated.routeFallbacks = chain;
|
|
149
|
+
if (primary) updated.routeFallbackPrimary = primary;
|
|
134
150
|
updated.routeFallbackIndex = index + 1;
|
|
135
151
|
updated.routeFallbackFailures = [...(session.routeFallbackFailures || []), failed];
|
|
136
152
|
await pinSessionWireRoute(updated, provider);
|
|
137
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);
|
|
138
159
|
// The live turn (prompt, assistant tool calls, tool results) carries on;
|
|
139
160
|
// only the previous provider's native replay state is dropped from it.
|
|
140
161
|
state.messages.splice(0, state.messages.length, ...stripProviderReplayMessages(state.messages));
|
|
@@ -150,6 +171,13 @@ export async function advanceAgentRoute(state, error) {
|
|
|
150
171
|
state.cacheBreakTraceKeys.clear();
|
|
151
172
|
state.transportRetriesUsed = 0;
|
|
152
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;
|
|
153
181
|
for (const key of Object.keys(oldOptions)) delete state.opts[key];
|
|
154
182
|
Object.assign(
|
|
155
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';
|
|
@@ -126,13 +131,16 @@ export async function beginIteration(state) {
|
|
|
126
131
|
getIterations: () => state.iterations,
|
|
127
132
|
getNextIteration: () => nextIteration,
|
|
128
133
|
repeatFailLimit: REPEAT_FAIL_LIMIT,
|
|
134
|
+
isTurnLimitNoticed: () => state.turnLimitNoticed === true,
|
|
129
135
|
});
|
|
130
136
|
const resolveToolCallId = createToolCallIdResolver(messages);
|
|
131
137
|
opts.onToolCall = (call) => {
|
|
132
138
|
resolveToolCallId(call);
|
|
133
139
|
try {
|
|
134
140
|
opts.onAssistantToolCallObserved?.(call, { eagerStarted: false });
|
|
135
|
-
} catch {
|
|
141
|
+
} catch {
|
|
142
|
+
// the tool-call observer is advisory
|
|
143
|
+
}
|
|
136
144
|
return eager.onToolCall(call);
|
|
137
145
|
};
|
|
138
146
|
return {
|
|
@@ -173,7 +181,12 @@ export async function sendProviderRequest(state, round) {
|
|
|
173
181
|
});
|
|
174
182
|
try {
|
|
175
183
|
opts.onProviderSendStarted?.();
|
|
176
|
-
} catch {
|
|
184
|
+
} catch {
|
|
185
|
+
// the send-started observer is advisory
|
|
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);
|
|
177
190
|
// The request a /btw side question forks: kept while it is in flight, with
|
|
178
191
|
// its reply once it proceeds, and dropped again if it fails.
|
|
179
192
|
const sideQuestion = captureSideQuestionRequest({
|
|
@@ -369,6 +382,10 @@ function traceActualCacheMiss(state, sent, response, { previousGuardState, previ
|
|
|
369
382
|
);
|
|
370
383
|
}
|
|
371
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;
|
|
372
389
|
}
|
|
373
390
|
|
|
374
391
|
/** Fold a completed send into the state: prefix guard, image-strip
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { normalizeToolEnvelope, makeToolEnvelope } from '../../tool-envelope.mjs';
|
|
6
6
|
import { resolveToolResultAfterHook } from '../tool-helpers.mjs';
|
|
7
|
+
import { effectiveToolCwd } from '../../../tools/builtin/bash-tool/shell-cwd.mjs';
|
|
7
8
|
|
|
8
9
|
export async function applyAfterToolHook(result, afterToolHook, { name, args, cwd, callerSessionId, toolCallId }) {
|
|
9
10
|
if (typeof afterToolHook !== 'function') return result;
|
|
@@ -15,7 +16,7 @@ export async function applyAfterToolHook(result, afterToolHook, { name, args, cw
|
|
|
15
16
|
const hookResult = await afterToolHook({
|
|
16
17
|
name,
|
|
17
18
|
args,
|
|
18
|
-
cwd,
|
|
19
|
+
cwd: effectiveToolCwd(name, args, cwd),
|
|
19
20
|
sessionId: callerSessionId,
|
|
20
21
|
toolCallId,
|
|
21
22
|
result: visible,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
recordHumanDecision,
|
|
16
16
|
} from '../../human-gate/gate.mjs';
|
|
17
17
|
import { applyEditedArgs } from '../../human-gate/requests.mjs';
|
|
18
|
+
import { effectiveToolCwd } from '../../../tools/builtin/bash-tool/shell-cwd.mjs';
|
|
18
19
|
|
|
19
20
|
const isArgsObject = (value) => value && typeof value === 'object' && !Array.isArray(value);
|
|
20
21
|
|
|
@@ -31,7 +32,7 @@ async function askApproval(
|
|
|
31
32
|
resolvePreToolAskApproval({
|
|
32
33
|
toolName: call.name,
|
|
33
34
|
args: call.args,
|
|
34
|
-
cwd: call.cwd,
|
|
35
|
+
cwd: effectiveToolCwd(call.name, call.args, call.cwd),
|
|
35
36
|
sessionId: callerSessionId,
|
|
36
37
|
toolCallId: executeOpts.toolCallId || null,
|
|
37
38
|
askReason,
|
|
@@ -131,8 +132,8 @@ export async function applyBeforeToolHook({
|
|
|
131
132
|
mcpScopeId = null,
|
|
132
133
|
}) {
|
|
133
134
|
const call = { name, args, cwd };
|
|
134
|
-
// ask_user
|
|
135
|
-
if (name === 'ask_user') return call;
|
|
135
|
+
// ask_user and handoff_user are themselves the user prompt; they never go through the ordinary approval gate.
|
|
136
|
+
if (name === 'ask_user' || name === 'handoff_user') return call;
|
|
136
137
|
try {
|
|
137
138
|
const hookDecision = beforeToolHook
|
|
138
139
|
? await runAbortable(executeOpts.signal, () =>
|
|
@@ -140,7 +141,7 @@ export async function applyBeforeToolHook({
|
|
|
140
141
|
{
|
|
141
142
|
name,
|
|
142
143
|
args,
|
|
143
|
-
cwd,
|
|
144
|
+
cwd: effectiveToolCwd(name, args, cwd),
|
|
144
145
|
sessionId: callerSessionId,
|
|
145
146
|
toolCallId: executeOpts.toolCallId || null,
|
|
146
147
|
},
|
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
* MCP, code graph, internal tools, shell, apply_patch, built-ins and foreign
|
|
4
4
|
* CLI adapters.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
executeMcpTool,
|
|
8
|
+
isBuiltinMailRead,
|
|
9
|
+
isMcpTool,
|
|
10
|
+
isRegisteredMcpTool,
|
|
11
|
+
mcpToolHasField,
|
|
12
|
+
} from '../../../mcp/client.mjs';
|
|
13
|
+
import { recordMailLinks } from '../../../../../browser-bridge/mail-links.mjs';
|
|
7
14
|
import {
|
|
8
15
|
executeBuiltinTool,
|
|
9
16
|
formatUnknownBuiltinToolMessage,
|
|
@@ -56,11 +63,18 @@ function dispatchMcp(name, args, { cwd, callerSessionId, sessionRef, executeOpts
|
|
|
56
63
|
// an unknown argument.
|
|
57
64
|
const needsCwdInjection = cwd && mcpToolHasField(name, 'cwd', mcpScopeId) && (args == null || args.cwd == null);
|
|
58
65
|
const finalArgs = needsCwdInjection ? { ...(args || {}), cwd } : args;
|
|
59
|
-
|
|
66
|
+
const call = executeMcpTool(name, finalArgs, {
|
|
60
67
|
signal: executeOpts.signal || null,
|
|
61
68
|
ownerKey: callerSessionId,
|
|
62
69
|
scopeId: mcpScopeId,
|
|
63
70
|
});
|
|
71
|
+
if (!isBuiltinMailRead(name, mcpScopeId)) return call;
|
|
72
|
+
// The runtime's own record of the links in a mail it read for this session:
|
|
73
|
+
// the only way Browser Use may open a link carrying a token.
|
|
74
|
+
return call.then((result) => {
|
|
75
|
+
recordMailLinks(callerSessionId, result);
|
|
76
|
+
return result;
|
|
77
|
+
});
|
|
64
78
|
}
|
|
65
79
|
|
|
66
80
|
function dispatchInternal(
|
|
@@ -19,6 +19,7 @@ import { applyBeforeToolHook, applyConnectorApproval, applyShellElevationGate }
|
|
|
19
19
|
import { dispatchToolCall } from './tool-exec/dispatch.mjs';
|
|
20
20
|
import { applyAfterToolHook } from './tool-exec/after-hook.mjs';
|
|
21
21
|
import { runReadOnlyIoWithDeadline } from './tool-exec/read-only-deadline.mjs';
|
|
22
|
+
import { guardShellCall, requestedShellType } from '../../tools/builtin/bash-tool/misuse-guard.mjs';
|
|
22
23
|
|
|
23
24
|
export { runReadOnlyIoWithDeadline as _runReadOnlyIoWithDeadlineForTest };
|
|
24
25
|
export {
|
|
@@ -43,9 +44,23 @@ async function executeToolOwned(name, args, cwd, callerSessionId, sessionRef, ex
|
|
|
43
44
|
const prepared = prepareToolCall(name, args, cwd, callerSessionId, sessionRef, executeOpts);
|
|
44
45
|
const { toolOpts, notifyFn, completionToolOpts } = prepared;
|
|
45
46
|
const toolApprovalHook = hookFrom(executeOpts, sessionRef, 'toolApprovalHook');
|
|
47
|
+
// Shell misuse is judged before any hook or approval sees the call, so they
|
|
48
|
+
// read the command that will run and the directory it runs in.
|
|
49
|
+
let callArgs = prepared.args;
|
|
50
|
+
if (name === 'shell') {
|
|
51
|
+
const guarded = guardShellCall(callArgs, {
|
|
52
|
+
shellType: requestedShellType(callArgs),
|
|
53
|
+
agent: sessionRef?.agent || null,
|
|
54
|
+
sessionId: callerSessionId,
|
|
55
|
+
telemetry: executeOpts.resultTelemetry,
|
|
56
|
+
});
|
|
57
|
+
if (guarded.failure) return guarded.failure;
|
|
58
|
+
callArgs = guarded.args;
|
|
59
|
+
completionToolOpts.shellGuardNotes = guarded.notes;
|
|
60
|
+
}
|
|
46
61
|
const hooked = await applyBeforeToolHook({
|
|
47
62
|
name,
|
|
48
|
-
args:
|
|
63
|
+
args: callArgs,
|
|
49
64
|
cwd: prepared.cwd,
|
|
50
65
|
callerSessionId,
|
|
51
66
|
executeOpts,
|
|
@@ -18,6 +18,7 @@ import { isAgentOwner } from '../../agent-owner.mjs';
|
|
|
18
18
|
import { honoredSchemaAllowlist } from '../manager/session-tool-surface.mjs';
|
|
19
19
|
import { syncSystemPrefix } from '../manager/prompt-utils.mjs';
|
|
20
20
|
import { invalidateProviderContextBaseline } from './compact-policy.mjs';
|
|
21
|
+
import { rebindToChangedPrefix } from '../thinking-binding.mjs';
|
|
21
22
|
|
|
22
23
|
/** Drop everything measured against the previous tool surface. */
|
|
23
24
|
function invalidateForToolSurfaceMigration(session) {
|
|
@@ -34,15 +35,55 @@ function invalidateForToolSurfaceMigration(session) {
|
|
|
34
35
|
*/
|
|
35
36
|
export function markToolSurfaceMigrated(session, intent = TOOL_SURFACE_MIGRATION_INTENT) {
|
|
36
37
|
invalidateForToolSurfaceMigration(session);
|
|
38
|
+
// The stored thinking was bound to the previous prefix and can never be
|
|
39
|
+
// replayed again (../thinking-binding.mjs); an open tool round a stopped
|
|
40
|
+
// turn left behind is ended first. Outside a turn only: a running turn sends
|
|
41
|
+
// from its own working transcript, whose latest tool round must keep its
|
|
42
|
+
// thinking.
|
|
43
|
+
if (Array.isArray(session.messages) && !Array.isArray(session.liveTurnMessages)) {
|
|
44
|
+
session.messages = rebindToChangedPrefix(session.messages);
|
|
45
|
+
}
|
|
37
46
|
session.pendingCacheBreakIntent = intent;
|
|
38
47
|
}
|
|
39
48
|
|
|
40
|
-
/**
|
|
41
|
-
|
|
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) {
|
|
42
81
|
if (!session) return false;
|
|
43
82
|
const migrating = toolExposureMigrationNeeded(session, provider);
|
|
44
|
-
|
|
45
|
-
|
|
83
|
+
applyOnWorkingMessages(session, messages, () => {
|
|
84
|
+
rebuildDeferredToolSurfaceForProvider(session, provider);
|
|
85
|
+
if (migrating) markToolSurfaceMigrated(session);
|
|
86
|
+
});
|
|
46
87
|
return migrating;
|
|
47
88
|
}
|
|
48
89
|
|
|
@@ -66,26 +107,12 @@ function hasUnansweredToolCalls(messages) {
|
|
|
66
107
|
*/
|
|
67
108
|
export function migrateToolExposureAtBoundary(session, messages) {
|
|
68
109
|
if (!session || !toolExposureMigrationNeeded(session) || hasUnansweredToolCalls(messages)) return false;
|
|
69
|
-
|
|
70
|
-
const working = Array.isArray(messages) ? messages : stored;
|
|
71
|
-
if (Array.isArray(working)) session.messages = working;
|
|
72
|
-
try {
|
|
110
|
+
applyOnWorkingMessages(session, messages, () =>
|
|
73
111
|
applyDeferredToolSurface(session, session.deferredSurfaceMode || 'lead', [], {
|
|
74
112
|
provider: session.provider,
|
|
75
113
|
model: session.model,
|
|
76
|
-
})
|
|
77
|
-
|
|
78
|
-
if (Array.isArray(working) && session.messages !== working) {
|
|
79
|
-
// The rewrite may drop an emptied system message: keep the request
|
|
80
|
-
// transcript array identity the loop holds.
|
|
81
|
-
working.splice(0, working.length, ...session.messages);
|
|
82
|
-
}
|
|
83
|
-
session.messages = stored;
|
|
84
|
-
}
|
|
85
|
-
// The rewritten prompt messages are fresh objects; the canonical transcript
|
|
86
|
-
// the save path persists takes them too, so the next save writes the new
|
|
87
|
-
// prompt together with the new exposure.
|
|
88
|
-
if (Array.isArray(stored) && Array.isArray(working) && stored !== working) syncSystemPrefix(stored, working);
|
|
114
|
+
})
|
|
115
|
+
);
|
|
89
116
|
invalidateForToolSurfaceMigration(session);
|
|
90
117
|
return true;
|
|
91
118
|
}
|
|
@@ -105,6 +132,7 @@ const AGENT_BRIDGE_FIELDS = [
|
|
|
105
132
|
'deferredToolDeltaRevision',
|
|
106
133
|
'nativeDeferredDiscovery',
|
|
107
134
|
'mcpServerInstructions',
|
|
135
|
+
'mcpInstructionsAnnounced',
|
|
108
136
|
];
|
|
109
137
|
|
|
110
138
|
/**
|
|
@@ -12,10 +12,7 @@ import {
|
|
|
12
12
|
loadSkillResource,
|
|
13
13
|
buildSkillToolEnvelope,
|
|
14
14
|
filterSkillsExcludingDisabled,
|
|
15
|
-
|
|
16
|
-
skillMissingFeature,
|
|
17
|
-
skillOutsideScope,
|
|
18
|
-
skillOutsideScopeError,
|
|
15
|
+
skillLoadRefusal,
|
|
19
16
|
} from '../../context/collect.mjs';
|
|
20
17
|
|
|
21
18
|
// Eager-dispatch: tools with readOnlyHint:true in their declaration are safe
|
|
@@ -95,12 +92,8 @@ export function buildSkillsListResponse(cwd) {
|
|
|
95
92
|
export function viewSkill(cwd, name, session = null) {
|
|
96
93
|
const skillName = String(name || '').trim();
|
|
97
94
|
if (!skillName) return 'Error: skill name is required';
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
100
|
-
return `Error: skill "${skillName}" needs the ${missingFeature} built-in feature, which is not installed or is switched off in Extensions → Plugin → Built-in`;
|
|
101
|
-
}
|
|
102
|
-
if (isSkillDisabled(skillName)) return `Error: skill "${skillName}" is disabled`;
|
|
103
|
-
if (skillOutsideScope(skillName, cwd)) return skillOutsideScopeError(skillName);
|
|
95
|
+
const refusal = skillLoadRefusal(skillName, cwd);
|
|
96
|
+
if (refusal) return refusal;
|
|
104
97
|
const res = loadSkillResource(skillName, cwd);
|
|
105
98
|
if (!res) return `Error: skill "${skillName}" not found`;
|
|
106
99
|
// Return the general tool envelope: the model-visible tool_result is the
|
|
@@ -9,6 +9,7 @@ import { processToolBatch } from '../tool-batch.mjs';
|
|
|
9
9
|
import { CROSS_TURN_CAP, REPEAT_FAIL_LIMIT } from './loop-state.mjs';
|
|
10
10
|
import { markStepEffort } from './step-auto-effort.mjs';
|
|
11
11
|
import { resolveExecutionToolCalls } from './tool-call-resolution.mjs';
|
|
12
|
+
import { rememberSensitiveValues } from '../sensitive-values.mjs';
|
|
12
13
|
import { callsAllowed, settleTurnLimits, turnLimitsOf } from './turn-limits.mjs';
|
|
13
14
|
|
|
14
15
|
function isSleepLikeToolCall(call) {
|
|
@@ -41,13 +42,19 @@ export async function runToolPhase(state, round, sent, onToolCall) {
|
|
|
41
42
|
// derive the multi-tool adoption ratio without scanning message bodies.
|
|
42
43
|
// Audit records what runs: a bridged call_tool is recorded as its target.
|
|
43
44
|
// The wire calls stay the transcript identity (assistant turn below).
|
|
44
|
-
const
|
|
45
|
+
const executionCalls = resolveExecutionToolCalls(calls, sessionRef);
|
|
46
|
+
const toolBatchId = recordToolBatch(sessionId, executionCalls, state.iterations);
|
|
47
|
+
// A sensitive fill (a verification code): every stored copy of the
|
|
48
|
+
// transcript keeps a marker instead of the value; the call runs as is.
|
|
49
|
+
rememberSensitiveValues(sessionId, executionCalls);
|
|
45
50
|
await Promise.resolve(onToolCall?.(state.iterations, calls));
|
|
46
51
|
const assistantTurnMsg = buildToolCallAssistantMessage(response, { calls, opts });
|
|
47
52
|
commitAssistantMessage(messages, assistantTurnMsg, opts);
|
|
48
53
|
try {
|
|
49
54
|
opts.onToolPhaseStarted?.();
|
|
50
|
-
} catch {
|
|
55
|
+
} catch {
|
|
56
|
+
// the tool-phase-started observer is advisory
|
|
57
|
+
}
|
|
51
58
|
const toolsT0 = Date.now();
|
|
52
59
|
const resultsFrom = messages.length;
|
|
53
60
|
({ dedupStubTotal: state.dedupStubTotal, editCount: state.editCount } = await processToolBatch({
|
|
@@ -90,7 +97,9 @@ export async function runToolPhase(state, round, sent, onToolCall) {
|
|
|
90
97
|
calls: calls.length,
|
|
91
98
|
elapsedMs: toolsEndedAt - toolsT0,
|
|
92
99
|
});
|
|
93
|
-
} catch {
|
|
100
|
+
} catch {
|
|
101
|
+
// the tool-phase-completed observer is advisory
|
|
102
|
+
}
|
|
94
103
|
traceLoopPhaseTiming({
|
|
95
104
|
iteration: round.nextIteration,
|
|
96
105
|
preSendMs: sent.preSendMs,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
drainPendingMessages,
|
|
10
10
|
releasePendingMessages,
|
|
11
11
|
} from './pending-messages.mjs';
|
|
12
|
+
import { promptOriginOf } from '../../../../shared/prompt-origin.mjs';
|
|
12
13
|
|
|
13
14
|
const SYNTHETIC_PROMPT_SOURCES = ['goal-continuation', 'goal-closeout'];
|
|
14
15
|
|
|
@@ -35,6 +36,7 @@ const tailTurnFor = (group) => ({
|
|
|
35
36
|
content: group.content,
|
|
36
37
|
entries: group.entries,
|
|
37
38
|
...(group.hop ? { hop: group.hop } : {}),
|
|
39
|
+
...(group.origin ? { origin: group.origin } : {}),
|
|
38
40
|
...(group.mode === PENDING_MODE_TASK_NOTIFICATION
|
|
39
41
|
? promptSourceFields(PENDING_MODE_TASK_NOTIFICATION, group.execution)
|
|
40
42
|
: {}),
|
|
@@ -49,13 +51,19 @@ const queuedTurnInput = (tailTurn) => ({
|
|
|
49
51
|
pendingEntries: tailTurn.entries,
|
|
50
52
|
...(tailTurn.hop ? { hop: tailTurn.hop } : {}),
|
|
51
53
|
promptSource: promptSourceFields(tailTurn.source, tailTurn.execution),
|
|
54
|
+
...(tailTurn.origin ? { promptOrigin: tailTurn.origin } : {}),
|
|
52
55
|
});
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
// The caller's provenance of its initial prompt, apart from its presentation
|
|
58
|
+
// source: an inbound channel message or an agent report (shared/prompt-origin.mjs).
|
|
59
|
+
const initialPromptOriginFor = (promptOrigin) => promptOriginOf(promptOrigin);
|
|
60
|
+
|
|
61
|
+
export function createAskPromptQueue({ sessionId, promptSource, promptOrigin }) {
|
|
55
62
|
// Local FIFO of follow-up prompts drained from the pending-message queue
|
|
56
63
|
// after each turn — keeps queued `agent type=send` messages in order.
|
|
57
64
|
const tail = [];
|
|
58
65
|
let initialPromptSource = initialPromptSourceFor(promptSource);
|
|
66
|
+
let initialPromptOrigin = initialPromptOriginFor(promptOrigin);
|
|
59
67
|
// Queue entries of the input nextTurn handed out that no turn owns yet.
|
|
60
68
|
// Once a turn starts, its failure path acks or releases them instead.
|
|
61
69
|
let unstartedEntries = [];
|
|
@@ -67,13 +75,15 @@ export function createAskPromptQueue({ sessionId, promptSource }) {
|
|
|
67
75
|
* and provenance — or null when nothing model-visible is left to run. */
|
|
68
76
|
const nextTurn = (original) => {
|
|
69
77
|
const source = initialPromptSource;
|
|
78
|
+
const origin = initialPromptOrigin;
|
|
70
79
|
initialPromptSource = null;
|
|
80
|
+
initialPromptOrigin = null;
|
|
71
81
|
let input;
|
|
72
82
|
if (tail.length > 0) {
|
|
73
83
|
// After the first turn, the next prompt comes from the drained queue.
|
|
74
84
|
input = queuedTurnInput(tail.shift());
|
|
75
85
|
} else if (hasModelVisiblePromptContent(original.prompt)) {
|
|
76
|
-
input = { ...original, pendingEntries: [], promptSource: source };
|
|
86
|
+
input = { ...original, pendingEntries: [], promptSource: source, ...(origin ? { promptOrigin: origin } : {}) };
|
|
77
87
|
} else {
|
|
78
88
|
// Idle resume: TUI kicks an empty ask() after execution completions
|
|
79
89
|
// mirror model-visible bodies into session pending. Drain that queue
|
|
@@ -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 { cacheWarmTurnKind, endCacheWarmTurn, failedTurnProvenance, noteCacheWarmTurn } from '../cache-warm.mjs';
|
|
22
23
|
|
|
23
24
|
export { _api_call_with_interrupt } from './ask-call-interrupt.mjs';
|
|
24
25
|
export {
|
|
@@ -168,7 +169,14 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
168
169
|
// return value (the queued tail turns supersede the original prompt's
|
|
169
170
|
// result, mirroring how a live chat returns the latest turn).
|
|
170
171
|
let result;
|
|
171
|
-
const queue = createAskPromptQueue({
|
|
172
|
+
const queue = createAskPromptQueue({
|
|
173
|
+
sessionId,
|
|
174
|
+
promptSource: askOpts.promptSource,
|
|
175
|
+
promptOrigin: askOpts.promptOrigin,
|
|
176
|
+
});
|
|
177
|
+
// The turn the prompt-cache warmer is told about last; it forgets it when
|
|
178
|
+
// the turn ends (endCacheWarmTurn), whatever way the ask unwinds.
|
|
179
|
+
let warmTurn = null;
|
|
172
180
|
// Hoisted so the outer finally (which runs once after the whole turn loop)
|
|
173
181
|
// can compare against the last turn's generation.
|
|
174
182
|
let askGeneration = 0;
|
|
@@ -213,6 +221,12 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
213
221
|
recoverCheckpoint: !crashRecoveryChecked,
|
|
214
222
|
emitStart: !sessionStartEmitted,
|
|
215
223
|
});
|
|
224
|
+
// The prompt-cache warmer learns idle gaps from real turns only; a
|
|
225
|
+
// retry is classified by the failed turn's stored provenance.
|
|
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));
|
|
216
230
|
crashRecoveryChecked = true;
|
|
217
231
|
sessionStartEmitted = true;
|
|
218
232
|
askGeneration = claimed.askGeneration;
|
|
@@ -234,6 +248,7 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
234
248
|
askStartedAt,
|
|
235
249
|
});
|
|
236
250
|
result = turn.result;
|
|
251
|
+
endCacheWarmTurn(sessionId, warmTurn);
|
|
237
252
|
// Turn complete. Drain the pending-message queue: any `agent type=send`
|
|
238
253
|
// that arrived while this turn was in flight runs next, in order, as a
|
|
239
254
|
// follow-up user turn. The mutex is still held, so a send racing this
|
|
@@ -264,6 +279,9 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
264
279
|
return result;
|
|
265
280
|
}
|
|
266
281
|
} finally {
|
|
282
|
+
// A failed/cancelled turn ends here too: its warmer turn entry goes (a
|
|
283
|
+
// later ask's own turn is never removed by this one).
|
|
284
|
+
endCacheWarmTurn(sessionId, warmTurn);
|
|
267
285
|
// A failed/cancelled turn ends the ask: the follow-up turns drained
|
|
268
286
|
// behind it never ran, so their entries go back to the pending queue.
|
|
269
287
|
queue.releaseUnstarted();
|