mixdog 1.2.3 → 1.2.5
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 +1 -1
- package/scripts/gate-local.mjs +6 -4
- package/scripts/lib/gate-scheduler.mjs +29 -11
- package/scripts/mobile-release.mjs +5 -4
- package/scripts/probe-provider-catalog.mjs +31 -0
- package/scripts/provider-pingpong-live.mjs +128 -38
- package/scripts/session-sweep.mjs +5 -25
- package/src/agents/maintainer/AGENT.md +1 -1
- package/src/agents/maintainer/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +2 -4
- package/src/agents/security/AGENT.md +1 -2
- package/src/agents/writer/AGENT.md +2 -3
- package/src/defaults/shipped-history.json +7 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/output-styles/common.md +2 -1
- package/src/rules/agent/AGENT.md +7 -5
- package/src/rules/lead/LEAD.md +13 -13
- package/src/rules/shared/45-destructive.md +4 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -5
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +81 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
- package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +41 -11
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -11
- package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -4
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -27
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +21 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
- package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
- package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +29 -8
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +32 -14
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
- package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
- package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
- package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +5 -11
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
- package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -32
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +160 -212
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +50 -116
- package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
- package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +7 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
- package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
- package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +204 -10
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
- package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
- package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +200 -17
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
- package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
- package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
- package/src/runtime/attachments/store.d.mts +9 -0
- package/src/runtime/attachments/store.mjs +80 -9
- package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
- package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
- package/src/runtime/computer-bridge/action-schema.mjs +178 -178
- package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
- package/src/runtime/effort-judge/judge-client.mjs +21 -4
- package/src/runtime/effort-judge/judge-worker.mjs +4 -1
- package/src/runtime/github/tool.mjs +118 -17
- package/src/runtime/media/adapters/codex-image.mjs +140 -21
- package/src/runtime/media/catalog.mjs +4 -4
- package/src/runtime/media/chatgpt-usage.mjs +55 -0
- package/src/runtime/media/defaults.mjs +37 -0
- package/src/runtime/media/jobs.mjs +12 -2
- package/src/runtime/media/lanes.mjs +12 -0
- package/src/runtime/media/tool-defs.mjs +15 -4
- package/src/runtime/media/tool.mjs +41 -12
- package/src/runtime/media/upstream-error.mjs +72 -6
- package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
- package/src/runtime/memory/lib/pg/process.mjs +5 -7
- package/src/runtime/memory/lib/pg/supervisor.mjs +4 -1
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/html-browser.mjs +18 -8
- package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/core/office-write-ledger.mjs +1 -5
- package/src/runtime/office/index.mjs +2 -3
- package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
- package/src/runtime/session-search/session-search-ingest.mjs +1 -1
- package/src/runtime/shared/agent-reap-state.mjs +13 -0
- package/src/runtime/shared/atomic-file.d.mts +1 -1
- package/src/runtime/shared/background-tasks.mjs +6 -1
- package/src/runtime/shared/bounded-line-diff.mjs +11 -2
- package/src/runtime/shared/browser-launch.mjs +15 -0
- package/src/runtime/shared/err-text.mjs +42 -4
- package/src/runtime/shared/file-lock.mjs +6 -5
- package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
- package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
- package/src/runtime/shared/model-route-chain.d.mts +8 -0
- package/src/runtime/shared/model-route-chain.mjs +48 -0
- package/src/runtime/shared/model-route-fallback.mjs +22 -0
- package/src/runtime/shared/pid-liveness.mjs +12 -0
- package/src/runtime/shared/provider-api-key.mjs +6 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
- package/src/runtime/shared/quiet-progress.d.mts +35 -0
- package/src/runtime/shared/quiet-progress.mjs +101 -0
- package/src/runtime/shared/quota-resume-store.mjs +32 -1
- package/src/runtime/shared/read-row-numbers.mjs +44 -0
- package/src/runtime/shared/remote-intent.mjs +2 -42
- package/src/runtime/shared/slow-span.mjs +8 -1
- package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
- package/src/runtime/shared/tool-output-budget.mjs +2 -0
- package/src/runtime/shared/tool-result-summary.mjs +16 -2
- package/src/runtime/shared/tool-status.mjs +3 -2
- package/src/runtime/shared/tool-surface.mjs +2 -3
- package/src/runtime/shared/tool-work-units.mjs +22 -15
- package/src/runtime/shared/transcript-metadata.mjs +49 -1
- package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
- package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
- package/src/runtime/shared/transcript-writer.mjs +14 -4
- package/src/runtime/shared/turn-changes.mjs +2 -1
- package/src/runtime/shared/turn-snapshot.mjs +11 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
- package/src/runtime/shared/worktrees/carry.mjs +6 -4
- package/src/runtime/shared/worktrees/contract.mjs +27 -1
- package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
- package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
- package/src/runtime/shared/worktrees/git-head.mjs +22 -13
- package/src/runtime/shared/worktrees/include.mjs +125 -7
- package/src/runtime/shared/worktrees/lock.mjs +1 -1
- package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
- package/src/runtime/shared/worktrees/manager.mjs +378 -32
- package/src/runtime/shared/worktrees/owner.mjs +2 -1
- package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
- package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
- package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
- package/src/runtime/terminal-bridge/client.mjs +14 -10
- package/src/session-runtime/boot/apis.mjs +7 -1
- package/src/session-runtime/boot/config.mjs +2 -0
- package/src/session-runtime/boot/facade.mjs +3 -0
- package/src/session-runtime/boot/session.mjs +3 -2
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/conversation-import/service.mjs +1 -1
- package/src/session-runtime/goal-facade-api.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
- package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
- package/src/session-runtime/lifecycle/shared.mjs +5 -6
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
- package/src/session-runtime/lifecycle/teardown.mjs +7 -16
- package/src/session-runtime/media-api.mjs +8 -0
- package/src/session-runtime/model-route/route-ownership.mjs +60 -0
- package/src/session-runtime/model-route/route-persist.mjs +3 -2
- package/src/session-runtime/model-route/set-route.mjs +114 -34
- package/src/session-runtime/model-route/web-search-route.mjs +7 -2
- package/src/session-runtime/model-route-api.mjs +4 -2
- package/src/session-runtime/native-web-search/routes.mjs +37 -24
- package/src/session-runtime/native-web-search.mjs +9 -8
- package/src/session-runtime/provider-auth/setup.mjs +4 -0
- package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
- package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
- package/src/session-runtime/provider-models.mjs +1 -0
- package/src/session-runtime/provider-usage.mjs +4 -0
- package/src/session-runtime/route-resolution.mjs +3 -1
- package/src/session-runtime/runtime-core.mjs +4 -0
- package/src/session-runtime/runtime-facade.mjs +6 -0
- package/src/session-runtime/services/agent-task-status.mjs +2 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
- package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
- package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
- package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
- package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
- package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +9 -6
- package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
- package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -9
- package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
- package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
- package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
- package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +28 -8
- package/src/session-runtime/services/agent-tool.mjs +4 -0
- package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
- package/src/session-runtime/services/provider-admin.mjs +77 -0
- package/src/session-runtime/session-create/session-options.mjs +7 -5
- package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
- package/src/session-runtime/session-transcript.mjs +4 -5
- package/src/session-runtime/session-turn-api.mjs +3 -9
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
- package/src/session-runtime/setup-tool/executor.mjs +23 -5
- package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
- package/src/session-runtime/tool-policy-refresh.mjs +83 -32
- package/src/session-runtime/turn/agent-ops.mjs +49 -2
- package/src/session-runtime/turn/side-question-ops.mjs +1 -4
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
- package/src/session-runtime/turn/turn-run.mjs +1 -36
- package/src/session-runtime/usage-stats-api.mjs +4 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
- package/src/session-runtime/workspace/admission-gate.mjs +44 -15
- package/src/session-runtime/workspace/project-branches.mjs +28 -36
- package/src/session-runtime/workspace/transition-steps.mjs +96 -95
- package/src/session-runtime/workspace/transitions.mjs +248 -68
- package/src/standalone/channel-transport.mjs +3 -4
- package/src/standalone/daemon-desktop-runtime.mjs +32 -1
- package/src/standalone/daemon-pg-stop.mjs +1 -3
- package/src/standalone/daemon-session-control.mjs +88 -0
- package/src/standalone/daemon-stored-session-views.mjs +23 -3
- package/src/standalone/daemon.mjs +2 -0
- package/src/standalone/desktop-service-registry.mjs +32 -5
- package/src/standalone/local-session-runtime.mjs +11 -12
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-runtime-inline-host.mjs +2 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
- package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
- package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
- package/src/standalone/session-service/agent-tree.mjs +28 -2
- package/src/standalone/session-service/entries/session-loads.mjs +16 -5
- package/src/standalone/session-service/entries.mjs +1 -0
- package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
- package/src/standalone/session-service/quota-resume.mjs +28 -13
- package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
- package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
- package/src/standalone/session-tool-output.mjs +82 -0
- package/src/tui/app/app-view.jsx +2 -1
- package/src/tui/app/provider-setup/provider-items.mjs +8 -0
- package/src/tui/app/provider-setup-picker.mjs +15 -3
- package/src/tui/app/slash-commands.mjs +6 -0
- package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
- package/src/tui/components/Spinner.jsx +4 -0
- package/src/tui/components/SpinnerByline.jsx +21 -2
- package/src/tui/components/status-line/local-line.mjs +10 -2
- package/src/tui/dist/index.mjs +529 -270
- package/src/tui/session/active-tool-summary.mjs +1 -1
- package/src/tui/session/context-state.mjs +0 -3
- package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
- package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
- package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
- package/src/tui/session/quota-resume.mjs +140 -61
- package/src/tui/session/session-api/commands.mjs +4 -10
- package/src/tui/session/session-api/controls.mjs +12 -0
- package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
- package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
- package/src/tui/session/session-api/lifecycle.mjs +13 -11
- package/src/tui/session/session-api/media.mjs +2 -0
- package/src/tui/session/session-api/routes.mjs +81 -57
- package/src/tui/session/session-api/settings.mjs +3 -3
- package/src/tui/session/session-api/worktree.mjs +3 -2
- package/src/tui/session/session-flow/auto-clear.mjs +1 -3
- package/src/tui/session/session-flow/drain.mjs +6 -4
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
- package/src/tui/session/session-flow/queue.mjs +1 -1
- package/src/tui/session/tool-approval.mjs +17 -8
- package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
- package/src/tui/session/tui-steering-persist.mjs +3 -5
- package/src/tui/session/turn-quiet.mjs +53 -0
- package/src/tui/session/turn-stream.mjs +5 -1
- package/src/tui/session/turn.mjs +38 -31
- package/src/tui/session/worktree-setup-notice.mjs +38 -0
- package/src/tui/spinner-meta.mjs +10 -0
- package/src/tui/spinner-verbs.mjs +3 -0
- package/src/ui/statusline.mjs +13 -3
- package/src/ui/streaming-markdown-heal.mjs +70 -18
- package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
- package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
- package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -302
- package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
- package/src/session-runtime/turn/share-ops.mjs +0 -77
- package/src/tui/session/cross-surface-share.mjs +0 -406
- package/src/tui/session/live-share/delta.mjs +0 -153
- package/src/tui/session/live-share/mirror.mjs +0 -106
- package/src/tui/session/live-share/owner.mjs +0 -254
- package/src/tui/session/live-share/retry.mjs +0 -54
- package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
- package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
- package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
- package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
- package/src/tui/session/live-share/viewer.mjs +0 -99
- package/src/tui/session/live-share/wire.mjs +0 -44
- package/src/tui/session/live-share.mjs +0 -154
- package/src/tui/session/shared-dir-watch.mjs +0 -69
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* set-route.mjs — select the
|
|
3
|
-
* adopt it
|
|
2
|
+
* set-route.mjs — select the runtime's route: resolve and validate the
|
|
3
|
+
* request, adopt it as the live route (its per-model settings saved; the main
|
|
4
|
+
* model only on an explicit main-model choice, keepMainModel: false), then
|
|
5
|
+
* decide when the current session follows it
|
|
4
6
|
* (untouched, tuned, recreated, updated in place when empty, or switched in
|
|
5
7
|
* place when the selection is addressed to an established conversation).
|
|
6
8
|
*/
|
|
@@ -21,6 +23,7 @@ import {
|
|
|
21
23
|
shouldRecreateEmptySessionForRouteChange,
|
|
22
24
|
} from '../../runtime/agent/orchestrator/runtime-core/session-route-policy.mjs';
|
|
23
25
|
import { rebuildToolSurfaceForProviderWithMigration } from '../../runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs';
|
|
26
|
+
import { UNOWNED_LEASE, openRouteLease } from './route-ownership.mjs';
|
|
24
27
|
|
|
25
28
|
/** The request, completed from the live route where the caller left gaps. */
|
|
26
29
|
function completeRequest(deps, next) {
|
|
@@ -80,20 +83,26 @@ async function resolveSelectedRoute(deps, next) {
|
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
/** Close the empty session and materialize a fresh one for the new provider. */
|
|
83
|
-
async function recreateEmptySession(deps) {
|
|
86
|
+
async function recreateEmptySession(deps, lease) {
|
|
84
87
|
const { getSession, setSession, mgr, statusRoutes, createCurrentSession, invalidatePreSessionToolSurface } = deps;
|
|
85
88
|
// If the boot create is still finishing SessionStart/deferred-surface
|
|
86
89
|
// work, drain that promise first. Otherwise createCurrentSession()
|
|
87
90
|
// would return the old in-flight promise after we tombstone/null the
|
|
88
91
|
// session, racing the intended rebuild for the new provider.
|
|
89
92
|
await createCurrentSession('model-switch-empty-drain');
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
93
|
+
const closed = lease.run(
|
|
94
|
+
() => {
|
|
95
|
+
const emptySession = getSession();
|
|
96
|
+
if (!emptySession?.id || sessionHasRouteHistory(emptySession)) return false;
|
|
97
|
+
statusRoutes?.clearGatewaySessionRoute?.(emptySession.id);
|
|
98
|
+
mgr.closeSession?.(emptySession.id, 'cli-model-switch-empty', { tombstone: true });
|
|
99
|
+
setSession(null);
|
|
100
|
+
invalidatePreSessionToolSurface?.();
|
|
101
|
+
return true;
|
|
102
|
+
},
|
|
103
|
+
() => false
|
|
104
|
+
);
|
|
105
|
+
if (closed) await createCurrentSession('model-switch-empty');
|
|
97
106
|
}
|
|
98
107
|
|
|
99
108
|
/** Rewrite the addressed empty session to the route it was asked to run on. */
|
|
@@ -164,7 +173,7 @@ function switchSessionInPlace(deps, session) {
|
|
|
164
173
|
}
|
|
165
174
|
|
|
166
175
|
/** Validate, persist and adopt the requested route as the runtime's route. */
|
|
167
|
-
async function adoptRoute(deps, persist, next, options) {
|
|
176
|
+
async function adoptRoute(deps, persist, next, options, lease) {
|
|
168
177
|
const {
|
|
169
178
|
getConfig,
|
|
170
179
|
getRoute,
|
|
@@ -175,15 +184,40 @@ async function adoptRoute(deps, persist, next, options) {
|
|
|
175
184
|
scheduleStatuslineUsageRefresh,
|
|
176
185
|
} = deps;
|
|
177
186
|
const { selectedRoute, fastCapable, modelMeta } = await resolveSelectedRoute(deps, next);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
+
// Provider readiness may outlast the session the selection was made for.
|
|
188
|
+
const adopted = lease.run(
|
|
189
|
+
() => {
|
|
190
|
+
if (options?.sessionOnly === true) {
|
|
191
|
+
// An agent child's route belongs to that session alone: the shared
|
|
192
|
+
// modelSettings bucket (saved effort/Fast per model) and the main
|
|
193
|
+
// model (lead preset / default model) are never written.
|
|
194
|
+
setRouteState(resolveRoute(getConfig(), selectedRoute));
|
|
195
|
+
} else {
|
|
196
|
+
persist.saveRouteModelSettings(selectedRoute, fastCapable);
|
|
197
|
+
// The main model changes only on an explicit main-model choice
|
|
198
|
+
// (keepMainModel: false, e.g. the setup tool); every other selection
|
|
199
|
+
// — the session surface's model pick, an heir — keeps it.
|
|
200
|
+
const leadRoute = persist.persistAdoptedModelSettings(selectedRoute, {
|
|
201
|
+
keepMainModel: options?.keepMainModel !== false,
|
|
202
|
+
});
|
|
203
|
+
setRouteState(resolveRoute(getConfig(), leadRoute ? { model: workflowPresetId('lead') } : selectedRoute));
|
|
204
|
+
}
|
|
205
|
+
return true;
|
|
206
|
+
},
|
|
207
|
+
() => false
|
|
208
|
+
);
|
|
209
|
+
if (!adopted) return false;
|
|
210
|
+
// The refresh completes against the route just adopted and only while the
|
|
211
|
+
// selection still owns it.
|
|
212
|
+
await refreshRouteEffort(modelMeta, getRoute(), null, lease);
|
|
213
|
+
return lease.run(
|
|
214
|
+
() => {
|
|
215
|
+
refreshStatuslineUsageSnapshot(getRoute());
|
|
216
|
+
scheduleStatuslineUsageRefresh();
|
|
217
|
+
return true;
|
|
218
|
+
},
|
|
219
|
+
() => false
|
|
220
|
+
);
|
|
187
221
|
}
|
|
188
222
|
|
|
189
223
|
/**
|
|
@@ -194,17 +228,25 @@ async function adoptRoute(deps, persist, next, options) {
|
|
|
194
228
|
* `{ modelSwitch }` with the recorded boundary (as setRoute does) so the
|
|
195
229
|
* session surface shows the same live divider, or true when nothing switched.
|
|
196
230
|
*/
|
|
197
|
-
export function createContinueSessionInModel(deps, persist) {
|
|
198
|
-
const { getSession, invalidateContextStatusCache } = deps;
|
|
231
|
+
export function createContinueSessionInModel(deps, persist, clearPendingRoute) {
|
|
232
|
+
const { getSession, getSessionGeneration, invalidateContextStatusCache } = deps;
|
|
199
233
|
return async function continueSessionInModel(sessionId, next) {
|
|
200
234
|
const session = getSession();
|
|
201
235
|
if (!sessionId || !session?.id || session.id !== sessionId) {
|
|
202
236
|
throw new Error(`session ${sessionId || ''} is not the active session`);
|
|
203
237
|
}
|
|
204
|
-
|
|
205
|
-
const
|
|
206
|
-
|
|
207
|
-
|
|
238
|
+
const lease = openRouteLease(getSessionGeneration);
|
|
239
|
+
const adopted = await adoptRoute(deps, persist, next, {}, lease);
|
|
240
|
+
return lease.run(
|
|
241
|
+
() => {
|
|
242
|
+
if (!adopted) return true;
|
|
243
|
+
const modelSwitch = switchSessionInPlace(deps, session);
|
|
244
|
+
invalidateContextStatusCache();
|
|
245
|
+
clearPendingRoute?.();
|
|
246
|
+
return modelSwitch ? { modelSwitch } : true;
|
|
247
|
+
},
|
|
248
|
+
() => true
|
|
249
|
+
);
|
|
208
250
|
};
|
|
209
251
|
}
|
|
210
252
|
|
|
@@ -215,9 +257,10 @@ async function validateSelectedRoute(deps, next) {
|
|
|
215
257
|
}
|
|
216
258
|
|
|
217
259
|
export function createSetRoute(deps, persist) {
|
|
218
|
-
const { getRoute, getSession, invalidateContextStatusCache, createCurrentSession } = deps;
|
|
260
|
+
const { getRoute, getSession, getSessionGeneration, invalidateContextStatusCache, createCurrentSession } = deps;
|
|
261
|
+
let pending = null;
|
|
219
262
|
|
|
220
|
-
|
|
263
|
+
async function setRoute(next, options = {}) {
|
|
221
264
|
// Without an explicit durable address a selection is for a new/inherited
|
|
222
265
|
// session and never rewrites an existing conversation's model, unless it
|
|
223
266
|
// is the user's model choice for this conversation (`switchEstablished`,
|
|
@@ -225,11 +268,28 @@ export function createSetRoute(deps, persist) {
|
|
|
225
268
|
// place while an empty one follows the unaddressed rules below.
|
|
226
269
|
const applyToCurrentSession = options?.applyToCurrentSession === true;
|
|
227
270
|
const switchEstablished = applyToCurrentSession || options?.switchEstablished === true;
|
|
228
|
-
//
|
|
229
|
-
// irreversible work (compaction) ahead of the switch; changes nothing.
|
|
271
|
+
// Validate without persisting the selection or changing the session.
|
|
230
272
|
if (options?.validateOnly === true) return validateSelectedRoute(deps, next);
|
|
231
|
-
|
|
273
|
+
// A selection addressed to a conversation belongs to the session
|
|
274
|
+
// generation it was enqueued under (the surface's enqueue boundary names
|
|
275
|
+
// it; a direct call is enqueued now). Once that generation has moved, every
|
|
276
|
+
// route or session effect is skipped by the lease and the current route
|
|
277
|
+
// stands.
|
|
278
|
+
const addressed = switchEstablished || options?.deferUntilNextTurn === true;
|
|
279
|
+
const lease = addressed ? openRouteLease(getSessionGeneration, options?.originGeneration) : UNOWNED_LEASE;
|
|
280
|
+
const adopted = await adoptRoute(deps, persist, next, options, lease);
|
|
281
|
+
if (!adopted) return getRoute();
|
|
282
|
+
return lease.run(() => followSession(options, lease, { switchEstablished, applyToCurrentSession }), getRoute);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/** What the adopted route does to the session it was selected for. */
|
|
286
|
+
async function followSession(options, lease, { switchEstablished, applyToCurrentSession }) {
|
|
232
287
|
const session = getSession();
|
|
288
|
+
if (options.deferUntilNextTurn === true) {
|
|
289
|
+
pending = session?.id ? { generation: lease.token } : null;
|
|
290
|
+
return getRoute();
|
|
291
|
+
}
|
|
292
|
+
pending = null;
|
|
233
293
|
// A session the user has already talked in or compacted keeps its route
|
|
234
294
|
// unless the selection was addressed to it. A current session with no
|
|
235
295
|
// model reply, no compaction summary and no in-flight first turn — empty,
|
|
@@ -240,8 +300,8 @@ export function createSetRoute(deps, persist) {
|
|
|
240
300
|
if (!switchEstablished) return getRoute();
|
|
241
301
|
const route = getRoute();
|
|
242
302
|
// An addressed selection of another model switches the conversation
|
|
243
|
-
// itself in place; the
|
|
244
|
-
//
|
|
303
|
+
// itself in place; the session surface defers it to the next turn
|
|
304
|
+
// instead. A same-model update (effort/Fast) only tunes the session
|
|
245
305
|
// from its next turn.
|
|
246
306
|
if (session && (route.provider !== session.provider || route.model !== session.model)) {
|
|
247
307
|
const modelSwitch = switchSessionInPlace(deps, session);
|
|
@@ -259,7 +319,9 @@ export function createSetRoute(deps, persist) {
|
|
|
259
319
|
session?.id &&
|
|
260
320
|
typeof createCurrentSession === 'function'
|
|
261
321
|
) {
|
|
262
|
-
|
|
322
|
+
// The recreation installs a new session itself, so nothing after it
|
|
323
|
+
// acts for the selection beyond dropping the stale gauge.
|
|
324
|
+
await recreateEmptySession(deps, lease);
|
|
263
325
|
invalidateContextStatusCache();
|
|
264
326
|
return getRoute();
|
|
265
327
|
}
|
|
@@ -272,5 +334,23 @@ export function createSetRoute(deps, persist) {
|
|
|
272
334
|
invalidateContextStatusCache();
|
|
273
335
|
}
|
|
274
336
|
return getRoute();
|
|
337
|
+
}
|
|
338
|
+
setRoute.applyPendingRoute = () => {
|
|
339
|
+
if (!pending) return null;
|
|
340
|
+
const selection = pending;
|
|
341
|
+
if (selection.generation !== getSessionGeneration()) {
|
|
342
|
+
pending = null;
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
// The live route is the latest selection: effort/Fast tuned after the
|
|
346
|
+
// deferred model choice replace it, so no snapshot is kept.
|
|
347
|
+
const modelSwitch = switchSessionInPlace(deps, getSession());
|
|
348
|
+
invalidateContextStatusCache();
|
|
349
|
+
pending = null;
|
|
350
|
+
return modelSwitch;
|
|
351
|
+
};
|
|
352
|
+
setRoute.clearPendingRoute = () => {
|
|
353
|
+
pending = null;
|
|
275
354
|
};
|
|
355
|
+
return setRoute;
|
|
276
356
|
}
|
|
@@ -6,6 +6,7 @@ import { clean, hasOwn } from '../../runtime/agent/orchestrator/runtime-core/ses
|
|
|
6
6
|
import { coerceEffortFor } from '../../runtime/agent/orchestrator/runtime-core/effort.mjs';
|
|
7
7
|
import { ensureProviderEnabled } from '../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
8
8
|
import { selectionFastCapable } from '../route-state.mjs';
|
|
9
|
+
import { routeChain } from '../../runtime/shared/model-route-chain.mjs';
|
|
9
10
|
import {
|
|
10
11
|
isDefaultWebSearchRouteConfig,
|
|
11
12
|
isWebSearchCapableProvider,
|
|
@@ -93,9 +94,13 @@ export function createWebSearchRouteApi(deps) {
|
|
|
93
94
|
if (isDefaultWebSearchRouteConfig(selectedRoute)) {
|
|
94
95
|
await awaitKeychainPrewarm();
|
|
95
96
|
ensureFullConfig();
|
|
96
|
-
return saveWebSearchRoute(defaultWebSearchRoute(selectedRoute.toolType));
|
|
97
97
|
}
|
|
98
|
-
|
|
98
|
+
const resolved = [];
|
|
99
|
+
for (const entry of routeChain(selectedRoute)) {
|
|
100
|
+
resolved.push(isDefaultWebSearchRouteConfig(entry) ? entry : await resolveExplicitRoute(entry));
|
|
101
|
+
}
|
|
102
|
+
const [primary, ...fallbacks] = resolved;
|
|
103
|
+
return saveWebSearchRoute(normalizeWebSearchRouteConfig({ ...primary, fallbacks }));
|
|
99
104
|
},
|
|
100
105
|
};
|
|
101
106
|
}
|
|
@@ -19,10 +19,12 @@ export { shouldRecreateEmptySessionForRouteChange } from '../runtime/agent/orche
|
|
|
19
19
|
|
|
20
20
|
export function createModelRouteApi(deps) {
|
|
21
21
|
const persist = createRoutePersistence(deps);
|
|
22
|
+
const setRoute = createSetRoute(deps, persist);
|
|
22
23
|
return {
|
|
23
24
|
...createWebSearchRouteApi(deps),
|
|
24
|
-
setRoute
|
|
25
|
-
|
|
25
|
+
setRoute,
|
|
26
|
+
applyPendingRoute: setRoute.applyPendingRoute,
|
|
27
|
+
continueSessionInModel: createContinueSessionInModel(deps, persist, setRoute.clearPendingRoute),
|
|
26
28
|
...createRouteTuning(deps, persist),
|
|
27
29
|
};
|
|
28
30
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* follow-Main default.
|
|
5
5
|
*/
|
|
6
6
|
import { webSearchRouteOrDefault } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
7
|
+
import { routeChain, canonicalRouteProvider } from '../../runtime/shared/model-route-chain.mjs';
|
|
7
8
|
|
|
8
9
|
export function createWebSearchRouteCandidates({
|
|
9
10
|
getRoute,
|
|
@@ -50,35 +51,47 @@ export function createWebSearchRouteCandidates({
|
|
|
50
51
|
// before the Main Model was ever consulted.
|
|
51
52
|
const webSearchRoute = webSearchRouteOrDefault(cfg.webSearchRoute, getWebSearchRoute());
|
|
52
53
|
setWebSearchRoute(webSearchRoute);
|
|
54
|
+
const candidates = [];
|
|
55
|
+
const seen = new Set();
|
|
56
|
+
for (const selected of routeChain(webSearchRoute)) {
|
|
57
|
+
const candidate = await resolveCandidate(selected, cfg, route);
|
|
58
|
+
if (!candidate) continue;
|
|
59
|
+
const provider = canonicalRouteProvider(candidate.provider);
|
|
60
|
+
if (seen.has(provider)) continue;
|
|
61
|
+
seen.add(provider);
|
|
62
|
+
candidates.push({ ...candidate, provider });
|
|
63
|
+
}
|
|
64
|
+
return candidates;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function resolveCandidate(webSearchRoute, cfg, route) {
|
|
53
68
|
if (isDefaultWebSearchRouteConfig(webSearchRoute)) {
|
|
54
69
|
const loadedRow = route?.provider && route?.model ? await loadMainCatalogRow(cfg, route) : null;
|
|
55
70
|
const mainModel = currentMainWebSearchModelMeta(loadedRow);
|
|
56
|
-
if (!mainModel || !webSearchCapableFor(route.provider, mainModel)) return
|
|
57
|
-
return
|
|
58
|
-
{
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
];
|
|
71
|
+
if (!mainModel || !webSearchCapableFor(route.provider, mainModel)) return null;
|
|
72
|
+
return {
|
|
73
|
+
key: `default\n${route.provider}\n${route.model}`,
|
|
74
|
+
provider: normalizeWebSearchProviderId(route.provider),
|
|
75
|
+
model: route.model,
|
|
76
|
+
source: 'default-web-search-route',
|
|
77
|
+
effort: route.effectiveEffort || route.effort || null,
|
|
78
|
+
fast: route.fast === true,
|
|
79
|
+
modelParameters: route.modelParameters || {},
|
|
80
|
+
toolType: webSearchRoute.toolType || null,
|
|
81
|
+
};
|
|
68
82
|
}
|
|
69
83
|
const providerName = normalizeWebSearchProviderId(webSearchRoute.provider);
|
|
70
|
-
if (!isWebSearchCapableProvider(providerName)) return
|
|
71
|
-
return
|
|
72
|
-
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
];
|
|
84
|
+
if (!isWebSearchCapableProvider(providerName)) return null;
|
|
85
|
+
return {
|
|
86
|
+
key: `${providerName}\n${webSearchRoute.model}`,
|
|
87
|
+
provider: providerName,
|
|
88
|
+
model: webSearchRoute.model,
|
|
89
|
+
source: 'web-search-route',
|
|
90
|
+
effort: webSearchRoute.effort || null,
|
|
91
|
+
fast: webSearchRoute.fast === true,
|
|
92
|
+
modelParameters: webSearchRoute.modelParameters || {},
|
|
93
|
+
toolType: webSearchRoute.toolType || null,
|
|
94
|
+
};
|
|
82
95
|
}
|
|
83
96
|
|
|
84
97
|
return { currentMainWebSearchModelMeta, nativeWebSearchRoutes };
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
} from './native-web-search/tool-shape.mjs';
|
|
15
15
|
import { createWebSearchRouteCandidates } from './native-web-search/routes.mjs';
|
|
16
16
|
import { reportNativeWebSearchUsage } from './native-web-search-usage.mjs';
|
|
17
|
+
import { canFallbackRoute } from '../runtime/shared/model-route-fallback.mjs';
|
|
17
18
|
|
|
18
19
|
export function createNativeWebSearch(deps) {
|
|
19
20
|
const {
|
|
@@ -98,14 +99,14 @@ export function createNativeWebSearch(deps) {
|
|
|
98
99
|
if (!candidates.length) throw noCandidateError();
|
|
99
100
|
const errors = [];
|
|
100
101
|
for (const candidate of candidates) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
)
|
|
108
|
-
|
|
102
|
+
const [toolType] = toolTypesFor(candidate);
|
|
103
|
+
try {
|
|
104
|
+
return await sendCandidate(candidate, toolType, webSearchArgs, signal);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
if (!canFallbackRoute(err, { signal })) throw err;
|
|
107
|
+
errors.push(
|
|
108
|
+
`${candidate.provider}${candidate.model ? `/${candidate.model}` : ''}/${toolType}: ${err?.message || String(err)}`
|
|
109
|
+
);
|
|
109
110
|
}
|
|
110
111
|
}
|
|
111
112
|
throw new Error(`native web search failed: ${errors.join(' | ')}`);
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// the model catalog.
|
|
4
4
|
import { refreshKeychainStatus, retryKeychain } from '../../runtime/shared/config.mjs';
|
|
5
5
|
import { keychainIssueFor } from '../services/provider-admin.mjs';
|
|
6
|
+
import { modelProxyClientMode } from '../../runtime/shared/model-proxy-mode.mjs';
|
|
6
7
|
|
|
7
8
|
// The keyring alert must reflect the live state (it can lock or unlock while a
|
|
8
9
|
// cached setup is served), so overlay it on every ready read.
|
|
@@ -26,6 +27,9 @@ export function createSetupApi({
|
|
|
26
27
|
return {
|
|
27
28
|
async getProviderSetup(options = {}) {
|
|
28
29
|
const force = options?.force === true || options?.refresh === true;
|
|
30
|
+
if (modelProxyClientMode()) {
|
|
31
|
+
return cachedProviderSetup({ force: force || options?.recheckKeychain === true });
|
|
32
|
+
}
|
|
29
33
|
// An unforced read never blocks: the authoritative setup waits on the OS
|
|
30
34
|
// keychain, which can take seconds on a cold start and used to stall the
|
|
31
35
|
// whole settings sweep behind it. Serve
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// One authoritative provider catalog load: secrets and providers ready, the
|
|
3
3
|
// daemon-wide startup refresh joined (or a forced refresh run), then the shared
|
|
4
4
|
// catalog flattened into deduplicated rows with per-provider profiling.
|
|
5
|
+
import { modelProxyClientMode } from '../../runtime/shared/model-proxy-mode.mjs';
|
|
5
6
|
import { isSelectableLlmModel } from '../model-recency.mjs';
|
|
6
7
|
import { sharedProviderCatalog } from '../provider-catalog-cache.mjs';
|
|
7
8
|
import { NO_ENABLED_PROVIDERS } from '../../runtime/agent/orchestrator/providers/registry-errors.mjs';
|
|
@@ -49,6 +50,14 @@ export function createCatalogLoader({
|
|
|
49
50
|
}
|
|
50
51
|
const providersStartedAt = performance.now();
|
|
51
52
|
try {
|
|
53
|
+
if (forceRefresh && modelProxyClientMode()) {
|
|
54
|
+
const { loadModelProxyProviderConfig } = await import(
|
|
55
|
+
'../../runtime/agent/orchestrator/providers/model-proxy-provider.mjs'
|
|
56
|
+
);
|
|
57
|
+
await loadModelProxyProviderConfig({ force: true });
|
|
58
|
+
// Rebuild even when daemon readiness already settled on the old PC set.
|
|
59
|
+
await reg().initProviders({});
|
|
60
|
+
}
|
|
52
61
|
await ensureProvidersReady(config().providers || {});
|
|
53
62
|
} catch (error) {
|
|
54
63
|
if (error?.code === NO_ENABLED_PROVIDERS) return false;
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
// the already-loaded provider rows over a provider round-trip.
|
|
5
5
|
import { isSelectableLlmModel } from '../model-recency.mjs';
|
|
6
6
|
import { catalogRevision } from '../provider-catalog-cache.mjs';
|
|
7
|
+
import { modelProxyClientMode } from '../../runtime/shared/model-proxy-mode.mjs';
|
|
8
|
+
import { loadModelProxyProviderConfig } from '../../runtime/agent/orchestrator/providers/model-proxy-provider.mjs';
|
|
7
9
|
|
|
8
10
|
export function createWebSearchCatalog({
|
|
9
11
|
caches,
|
|
@@ -14,15 +16,22 @@ export function createWebSearchCatalog({
|
|
|
14
16
|
quickHelpers,
|
|
15
17
|
normalizeWebSearchProviderId,
|
|
16
18
|
isWebSearchCapableProvider,
|
|
19
|
+
collectProviderModels,
|
|
17
20
|
ensureFullConfig,
|
|
18
21
|
awaitKeychainPrewarm,
|
|
19
22
|
ensureProvidersReady,
|
|
20
23
|
}) {
|
|
21
24
|
async function enabledWebSearchProviderConfig() {
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
let providers;
|
|
26
|
+
if (modelProxyClientMode()) {
|
|
27
|
+
providers = await loadModelProxyProviderConfig();
|
|
28
|
+
} else {
|
|
29
|
+
await awaitKeychainPrewarm();
|
|
30
|
+
ensureFullConfig();
|
|
31
|
+
providers = config().providers;
|
|
32
|
+
}
|
|
24
33
|
const out = {};
|
|
25
|
-
for (const [name, providerConfig] of Object.entries(
|
|
34
|
+
for (const [name, providerConfig] of Object.entries(providers || {})) {
|
|
26
35
|
const providerName = normalizeWebSearchProviderId(name);
|
|
27
36
|
if (!providerConfig?.enabled || !isWebSearchCapableProvider(providerName)) continue;
|
|
28
37
|
out[providerName] = { ...providerConfig, enabled: true };
|
|
@@ -66,6 +75,12 @@ export function createWebSearchCatalog({
|
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
async function loadWebSearchProviderModelsFresh({ forceRefresh = false } = {}) {
|
|
78
|
+
if (modelProxyClientMode()) {
|
|
79
|
+
// Share the desktop-backed catalog's readiness, force refresh and retry
|
|
80
|
+
// semantics. Server-local quick rows cannot describe desktop accounts.
|
|
81
|
+
const models = await collectProviderModels({ force: forceRefresh });
|
|
82
|
+
return quickHelpers.webSearchRowsWithDefault(quickHelpers.webSearchModelsFromRows(models));
|
|
83
|
+
}
|
|
69
84
|
const webSearchProviders = await enabledWebSearchProviderConfig();
|
|
70
85
|
const providerNames = Object.keys(webSearchProviders);
|
|
71
86
|
if (!providerNames.length) return [];
|
|
@@ -89,6 +104,11 @@ export function createWebSearchCatalog({
|
|
|
89
104
|
}
|
|
90
105
|
|
|
91
106
|
async function collectWebSearchProviderModels({ force = false } = {}) {
|
|
107
|
+
if (modelProxyClientMode()) {
|
|
108
|
+
// The main catalog owns caching in client mode, including incomplete
|
|
109
|
+
// loads; do not pin an empty/offline projection in a second cache.
|
|
110
|
+
return rows.providerModelsFromCacheRows(await loadWebSearchProviderModelsFresh({ forceRefresh: force }));
|
|
111
|
+
}
|
|
92
112
|
const revision = meta.syncCatalogRevision();
|
|
93
113
|
if (force) {
|
|
94
114
|
const models = await loadWebSearchProviderModelsFresh({ forceRefresh: true });
|
|
@@ -63,6 +63,7 @@ export function createProviderModels({
|
|
|
63
63
|
quickHelpers,
|
|
64
64
|
normalizeWebSearchProviderId,
|
|
65
65
|
isWebSearchCapableProvider,
|
|
66
|
+
collectProviderModels,
|
|
66
67
|
...readiness,
|
|
67
68
|
});
|
|
68
69
|
const loadProviderModelsFresh = createCatalogLoader({ caches, config, reg, meta, rows, profile, ...readiness });
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// references) and all config/registry reads flow through supplied accessors so
|
|
6
6
|
// live-binding is preserved.
|
|
7
7
|
import { clean } from '../runtime/agent/orchestrator/runtime-core/session-text.mjs';
|
|
8
|
+
import { modelProxyClientMode } from '../runtime/shared/model-proxy-mode.mjs';
|
|
8
9
|
|
|
9
10
|
// A post-redeem dashboard rebuild is best effort: past this budget the caller
|
|
10
11
|
// gets its confirmed outcome and the surface revalidates on its own cadence.
|
|
@@ -70,6 +71,9 @@ export function createProviderUsage({
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
async function cachedProviderSetup({ force = false, quick = false } = {}) {
|
|
74
|
+
// The proxy owns a short, connection-generation-aware cache. A session's
|
|
75
|
+
// indefinite local cache would hide PC sign-ins, sign-outs and reconnects.
|
|
76
|
+
if (modelProxyClientMode()) return providerSetup(displayConfig(), { force });
|
|
73
77
|
if (!force && caches.providerSetupCache.setup) {
|
|
74
78
|
return caches.providerSetupCache.setup;
|
|
75
79
|
}
|
|
@@ -35,7 +35,7 @@ export function createRouteResolution({ rt, collectProviderModels, ensureProvide
|
|
|
35
35
|
return rt.route;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
async function refreshRouteEffort(modelMetaOverride = null, expectedRoute = null, signal = null) {
|
|
38
|
+
async function refreshRouteEffort(modelMetaOverride = null, expectedRoute = null, signal = null, lease = null) {
|
|
39
39
|
const targetRoute = expectedRoute || rt.route;
|
|
40
40
|
await runAbortable(signal, () => ensureProvidersReady(ensureProviderEnabled(rt.config, targetRoute.provider)));
|
|
41
41
|
const modelMeta =
|
|
@@ -43,7 +43,9 @@ export function createRouteResolution({ rt, collectProviderModels, ensureProvide
|
|
|
43
43
|
throwIfAborted(signal);
|
|
44
44
|
// A rapid second resume/model change can replace the route while provider
|
|
45
45
|
// metadata is loading. Never let the older completion overwrite it.
|
|
46
|
+
// A selection whose session was replaced while this loaded owns nothing.
|
|
46
47
|
if (expectedRoute && rt.route !== expectedRoute) return null;
|
|
48
|
+
if (lease && !lease.valid()) return null;
|
|
47
49
|
const { effectiveEffort, fastCapable } = resolveRouteEffortState(targetRoute, modelMeta);
|
|
48
50
|
const contextState = resolveRouteContextState(targetRoute, modelMeta);
|
|
49
51
|
const contextValue = clean(targetRoute.modelParameters?.context);
|
|
@@ -18,6 +18,7 @@ function bootParams({
|
|
|
18
18
|
model,
|
|
19
19
|
effort,
|
|
20
20
|
fast,
|
|
21
|
+
autoEffort,
|
|
21
22
|
modelParameters,
|
|
22
23
|
contextPercent,
|
|
23
24
|
contextTokens,
|
|
@@ -33,12 +34,14 @@ function bootParams({
|
|
|
33
34
|
sessionProfile = null,
|
|
34
35
|
worktree = null,
|
|
35
36
|
executeAgentControl = null,
|
|
37
|
+
executeSessionControl = null,
|
|
36
38
|
} = {}) {
|
|
37
39
|
return {
|
|
38
40
|
provider,
|
|
39
41
|
model,
|
|
40
42
|
effort,
|
|
41
43
|
fast,
|
|
44
|
+
autoEffort,
|
|
42
45
|
modelParameters,
|
|
43
46
|
contextPercent,
|
|
44
47
|
contextTokens,
|
|
@@ -55,6 +58,7 @@ function bootParams({
|
|
|
55
58
|
// Creation-time worktree intent (workspace/transitions.mjs creationIntent).
|
|
56
59
|
worktree,
|
|
57
60
|
executeAgentControl,
|
|
61
|
+
executeSessionControl,
|
|
58
62
|
};
|
|
59
63
|
}
|
|
60
64
|
|
|
@@ -31,6 +31,7 @@ export function createRuntimeFacade({
|
|
|
31
31
|
const currentSessionId = () => state.session?.id || state.reservedSessionId || state.addressedSessionId || null;
|
|
32
32
|
return {
|
|
33
33
|
...leadingApi,
|
|
34
|
+
isSessionTerminal: () => state.admission === 'terminal',
|
|
34
35
|
/** Bind the durable address to the conversation this runtime just
|
|
35
36
|
* loaded (resume / load-on-demand). Idempotent for the same id. */
|
|
36
37
|
bindSessionAddress(sessionId) {
|
|
@@ -135,6 +136,11 @@ export function createRuntimeFacade({
|
|
|
135
136
|
get session() {
|
|
136
137
|
return state.session;
|
|
137
138
|
},
|
|
139
|
+
/** Advances whenever another conversation (or none) is installed; a route
|
|
140
|
+
* selection captures it when enqueued (see model-route/route-ownership). */
|
|
141
|
+
get sessionGeneration() {
|
|
142
|
+
return state.sessionGeneration;
|
|
143
|
+
},
|
|
138
144
|
contextStatus(options) {
|
|
139
145
|
return getContextStatus(options);
|
|
140
146
|
},
|
|
@@ -111,6 +111,7 @@ function cleanStage(value) {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
function describeLastProgress({ stage, snapshot, runtime, silentFor, lastToolCall, now }) {
|
|
114
|
+
if (snapshot?.awaitingModelResponse) return 'model thinking (request sent; awaiting response headers)';
|
|
114
115
|
if (snapshot?.waitingForTransport) return 'awaiting model transport';
|
|
115
116
|
if (snapshot?.waitingForFirstSemantic) {
|
|
116
117
|
return 'transport active; awaiting first model event';
|
|
@@ -169,6 +170,7 @@ function describeAgentDiagnostic({ taskStatus, sessionStatus, stage, snapshot, s
|
|
|
169
170
|
if (abortErr) return `stale: ${abortErr.message.replace(/^agent /i, '')}`;
|
|
170
171
|
}
|
|
171
172
|
|
|
173
|
+
if (snapshot?.awaitingModelResponse) return 'model thinking; request sent, response headers pending';
|
|
172
174
|
if (snapshot?.waitingForTransport) return 'waiting for model transport';
|
|
173
175
|
if (snapshot?.waitingForFirstSemantic) {
|
|
174
176
|
return 'transport healthy; waiting for first semantic model event';
|
|
@@ -10,9 +10,6 @@ export function createCloseAll({ registry, close }) {
|
|
|
10
10
|
const { tags, tagAgents, tagCwds } = registry;
|
|
11
11
|
|
|
12
12
|
function resetLocalTagState() {
|
|
13
|
-
for (const timer of registry.reapTimers.values()) clearTimeout(timer);
|
|
14
|
-
registry.reapTimers.clear();
|
|
15
|
-
registry.clearScheduledReaps();
|
|
16
13
|
tags.clear();
|
|
17
14
|
tagAgents.clear();
|
|
18
15
|
tagCwds.clear();
|
|
@@ -58,21 +58,20 @@ export function createCloseFlow({ mgr, registry, views }) {
|
|
|
58
58
|
if (isLeadPoolAgent(registry.getLiveSession(sessionId)?.agent)) {
|
|
59
59
|
throw new Error(`agent close: target "${target}" is a Lead session`);
|
|
60
60
|
}
|
|
61
|
-
registry.cancelReap(sessionId);
|
|
62
61
|
const descendantSessionIds =
|
|
63
62
|
typeof mgr.descendantSessionIds === 'function' ? mgr.descendantSessionIds(sessionId) : [];
|
|
64
63
|
const tag = registry.tagForSession(sessionId);
|
|
65
64
|
clearAgentStatuslineRoute(sessionId);
|
|
66
65
|
cancelSessionTasks(sessionId, target, scopedContext);
|
|
67
|
-
// Close (and stamp cancelStatus) BEFORE dropping the worker row
|
|
68
|
-
//
|
|
69
|
-
// which republished the session as `running`. The explicit task_id cancel
|
|
66
|
+
// Close (and stamp cancelStatus) BEFORE dropping the worker row, so the
|
|
67
|
+
// row never outlives an unrecorded cancel. The explicit task_id cancel
|
|
70
68
|
// below is an idempotent no-op fallback once terminal.
|
|
71
|
-
|
|
69
|
+
// Closing a runtime cancels its work; only explicit session deletion
|
|
70
|
+
// may tombstone the conversation.
|
|
71
|
+
const ok = await mgr.closeSession(sessionId, 'cli-agent-close', { tombstone: false });
|
|
72
72
|
if (task?.taskId) cancelBackgroundTask(task.taskId, CLOSE_REASON);
|
|
73
73
|
// Drop the row only once the cancellation is DURABLY recorded: a failed
|
|
74
|
-
// close that still forgot the row
|
|
75
|
-
// state — the exact lingering row this path exists to prevent.
|
|
74
|
+
// close that still forgot the row would leave no cancelled state behind.
|
|
76
75
|
if (ok) {
|
|
77
76
|
registry.forgetTerminalSession(tag, sessionId);
|
|
78
77
|
for (const descendantSessionId of descendantSessionIds) {
|