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
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// manager/runtime-state.mjs
|
|
2
|
+
// The process-global runtime liveness map and its turn-activity reads.
|
|
3
|
+
// runtime-liveness.mjs owns every entry and mutation; this leaf has no
|
|
4
|
+
// imports, so a cold reader (the daemon's session catalog) can ask which turns
|
|
5
|
+
// are in flight without loading the session manager graph. Every session runs
|
|
6
|
+
// inline in the daemon, so this map is the whole answer to "is this session's
|
|
7
|
+
// turn running".
|
|
8
|
+
|
|
9
|
+
export const runtimeState = new Map();
|
|
10
|
+
|
|
11
|
+
// Stages that still own live provider/tool work: compaction, idle cleanup and
|
|
12
|
+
// runtime unload all stay away from an entry in one of them.
|
|
13
|
+
export const IN_FLIGHT_STAGES = new Set(['connecting', 'requesting', 'streaming', 'tool_running', 'cancelling']);
|
|
14
|
+
|
|
15
|
+
/** Whether a runtime entry's turn (provider or tool work) is running now. */
|
|
16
|
+
export function isTurnInFlight(entry) {
|
|
17
|
+
if (!entry || entry.closed === true) return false;
|
|
18
|
+
if (entry.controller && !entry.controller.signal?.aborted) return true;
|
|
19
|
+
return IN_FLIGHT_STAGES.has(entry.stage);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const cleanLower = (value) =>
|
|
23
|
+
String(value || '')
|
|
24
|
+
.trim()
|
|
25
|
+
.toLowerCase();
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Turn activity of every session this process runs: `working` holds the ids
|
|
29
|
+
* whose turn is in flight, `agentWorking` the root owner (Lead) ids of every
|
|
30
|
+
* in-flight Agent session.
|
|
31
|
+
*/
|
|
32
|
+
export function inFlightSessionActivity() {
|
|
33
|
+
const working = new Set();
|
|
34
|
+
const agentWorking = new Set();
|
|
35
|
+
for (const [id, entry] of runtimeState) {
|
|
36
|
+
if (!isTurnInFlight(entry)) continue;
|
|
37
|
+
working.add(id);
|
|
38
|
+
const session = entry.session;
|
|
39
|
+
const ownerSessionId = String(session?.ownerSessionId || session?.parentSessionId || '').trim();
|
|
40
|
+
const agent = cleanLower(session?.agent);
|
|
41
|
+
if (
|
|
42
|
+
ownerSessionId &&
|
|
43
|
+
ownerSessionId !== id &&
|
|
44
|
+
(cleanLower(session?.owner) === 'agent' || (agent && agent !== 'lead'))
|
|
45
|
+
) {
|
|
46
|
+
agentWorking.add(ownerSessionId);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { working, agentWorking };
|
|
50
|
+
}
|
|
@@ -17,7 +17,8 @@ import { clearTurnCheckpoint } from './turn-checkpoint.mjs';
|
|
|
17
17
|
import { forgetSessionSaveBaseline } from '../store/save-worker.mjs';
|
|
18
18
|
import { forgetSessionLoadCache } from '../store/load-cache.mjs';
|
|
19
19
|
import { releaseReadSnapshotScope } from '../../tools/builtin/snapshot-store.mjs';
|
|
20
|
-
import {
|
|
20
|
+
import { cancelOwnedShellTrees } from '../../tools/lib/owned-shell-trees.mjs';
|
|
21
|
+
import { noteShellOwnerSessionClosed } from '../../tools/builtin/lib/shell-job-records.mjs';
|
|
21
22
|
import { forgetSideQuestion } from '../side-question-store.mjs';
|
|
22
23
|
|
|
23
24
|
/**
|
|
@@ -47,15 +48,17 @@ export function closeSession(id, reason = 'manual', opts = {}) {
|
|
|
47
48
|
const entry = _getRuntimeEntry(id);
|
|
48
49
|
// askSession owns the interruption tracker that can merge committed
|
|
49
50
|
// iterations, the current partial response, and observed tool results into
|
|
50
|
-
// one canonical transcript.
|
|
51
|
+
// one canonical transcript. Stage that in-memory snapshot synchronously
|
|
51
52
|
// BEFORE the lifecycle generation changes; once generation is bumped, the
|
|
52
|
-
// normal cancellation cleanup save is intentionally rejected as stale.
|
|
53
|
+
// normal cancellation cleanup save is intentionally rejected as stale. It
|
|
54
|
+
// is only staged: a refused barrier rolls it back so the turn keeps running
|
|
55
|
+
// and checkpointing as if no close had been attempted.
|
|
56
|
+
let closeSnapshot = null;
|
|
53
57
|
try {
|
|
54
|
-
entry?.prepareCloseSnapshot?.(reason);
|
|
58
|
+
closeSnapshot = entry?.prepareCloseSnapshot?.tentative?.(reason) ?? null;
|
|
55
59
|
} catch {
|
|
56
60
|
/* best-effort */
|
|
57
61
|
}
|
|
58
|
-
_stopToolActivityHeartbeat(id);
|
|
59
62
|
// 1. Tombstone first — this wins the race against saveSession().
|
|
60
63
|
// Skipped when tombstone=false: no closed:true marker is planted, so
|
|
61
64
|
// the session file stays intact and resumeSession() will accept it.
|
|
@@ -87,12 +90,16 @@ export function closeSession(id, reason = 'manual', opts = {}) {
|
|
|
87
90
|
// a late save could clobber and nothing left open to resume. That close
|
|
88
91
|
// succeeds and tears the runtime down normally.
|
|
89
92
|
if (typeof newGen !== 'number' && outcome.absent !== true) {
|
|
93
|
+
closeSnapshot?.rollback();
|
|
90
94
|
reportCloseBarrierFailure({ id, reason, tombstone, entry });
|
|
91
95
|
return false;
|
|
92
96
|
}
|
|
97
|
+
// The staged snapshot was folded into the synchronous generation write
|
|
98
|
+
// above; committing it stops the turn's checkpoint writer. Only now is it
|
|
99
|
+
// safe to remove the crash fallback.
|
|
100
|
+
closeSnapshot?.commit();
|
|
101
|
+
_stopToolActivityHeartbeat(id);
|
|
93
102
|
cancelOwnedShellProcesses({ id, reason, tombstone });
|
|
94
|
-
// prepareCloseSnapshot was folded into the synchronous generation write
|
|
95
|
-
// above. Only now is it safe to remove the crash fallback.
|
|
96
103
|
clearTurnCheckpoint(id);
|
|
97
104
|
teardownSessionRuntime({ id, entry, reason, tombstone, newGen });
|
|
98
105
|
return true;
|
|
@@ -138,16 +145,27 @@ function reportCloseBarrierFailure({ id, reason, tombstone, entry }) {
|
|
|
138
145
|
* with the unconfirmed outcome. The re-stamp is idempotent: markSessionClosed
|
|
139
146
|
* keeps the original close time and generation and only upgrades the cancel
|
|
140
147
|
* scalars (unconfirmed never downgrades back to cancelled).
|
|
148
|
+
*
|
|
149
|
+
* Every tree records its process identities before the kill (the kill may
|
|
150
|
+
* break the parent chain). When a snapshot is still pending the cancel is
|
|
151
|
+
* sent once it lands or after PROCESS_TABLE_READ_BOUND_MS, whichever first;
|
|
152
|
+
* the close itself does not wait. Holds this session leaves behind become
|
|
153
|
+
* releasable from any session that sees their workspace.
|
|
141
154
|
*/
|
|
142
155
|
function cancelOwnedShellProcesses({ id, reason, tombstone }) {
|
|
143
|
-
|
|
156
|
+
const record = (result) => {
|
|
157
|
+
if (tombstone && result?.confirmed === false) markSessionClosed(id, reason, { cancelStatus: 'cancel-unconfirmed' });
|
|
158
|
+
};
|
|
159
|
+
// A cancel that threw proved nothing either.
|
|
160
|
+
const unconfirmed = () => record({ confirmed: false });
|
|
144
161
|
try {
|
|
145
|
-
|
|
162
|
+
const result = cancelOwnedShellTrees(id);
|
|
163
|
+
if (typeof result?.then === 'function') result.then(record, unconfirmed);
|
|
164
|
+
else record(result);
|
|
146
165
|
} catch {
|
|
147
|
-
|
|
148
|
-
cancelConfirmed = false;
|
|
166
|
+
unconfirmed();
|
|
149
167
|
}
|
|
150
|
-
|
|
168
|
+
noteShellOwnerSessionClosed(id);
|
|
151
169
|
}
|
|
152
170
|
|
|
153
171
|
/**
|
|
@@ -275,8 +293,8 @@ export function abortSessionTurn(id, reason = 'turn-abort') {
|
|
|
275
293
|
* what a settled turn left behind;
|
|
276
294
|
* - offload sidecars, the turn checkpoint and persisted pending messages
|
|
277
295
|
* are left intact — they are the follow-up turn's context, not runtime.
|
|
278
|
-
*
|
|
279
|
-
*
|
|
296
|
+
* A terminal session is never closed here; it stays open until it is
|
|
297
|
+
* explicitly cancelled or deleted.
|
|
280
298
|
*
|
|
281
299
|
* Returns false (changing nothing) when the session is still in flight.
|
|
282
300
|
*/
|
|
@@ -29,7 +29,7 @@ import { hideCompactionArchive } from '../compaction-archive-capture.mjs';
|
|
|
29
29
|
import { writeStderrBestEffort } from '../../../../shared/best-effort-stderr.mjs';
|
|
30
30
|
import { forgetSideQuestion } from '../side-question-store.mjs';
|
|
31
31
|
|
|
32
|
-
/** Force-flush session metrics to disk.
|
|
32
|
+
/** Force-flush session metrics to disk. */
|
|
33
33
|
export async function flushSessionMetrics(sessionId) {
|
|
34
34
|
if (!sessionId) return;
|
|
35
35
|
const session = loadSession(sessionId);
|
|
@@ -7,7 +7,7 @@ import { getProvider } from '../../providers/registry.mjs';
|
|
|
7
7
|
import { invalidateContextUsageSnapshot, invalidateProviderContextBaseline } from '../loop/compact-policy.mjs';
|
|
8
8
|
import { saveSession, saveSessionAsync, saveSessionAsyncDeferred, loadSession, setLiveSession } from '../store.mjs';
|
|
9
9
|
import { _liveSessions } from '../store/live-state.mjs';
|
|
10
|
-
import {
|
|
10
|
+
import { _recoverTurnCheckpointDurably } from './turn-checkpoint-recovery.mjs';
|
|
11
11
|
import { isAgentOwner } from '../../agent-owner.mjs';
|
|
12
12
|
import { getHiddenAgent } from '../../internal-agents.mjs';
|
|
13
13
|
import { loadConfig } from '../../config.mjs';
|
|
@@ -37,14 +37,15 @@ import { getAgentRuntimeSync, warnAgentRuntimeResolveFailureOnce } from './agent
|
|
|
37
37
|
import { ensureCodexWireSessionId, mintSessionId } from './session-id.mjs';
|
|
38
38
|
import { providerCacheKey } from './provider-cache-key.mjs';
|
|
39
39
|
import { buildSessionRecord, normalizeDesktopSessionMetadata, sessionOriginFields } from './session-record.mjs';
|
|
40
|
+
import { normalizeWorkflowRoute } from '../../runtime-core/workflow.mjs';
|
|
40
41
|
import { applyPendingWorkspaceReroot, refreshSessionBp3Environment } from './prompt-utils.mjs';
|
|
41
42
|
import { isWorktreeBound } from '../../../../shared/worktrees/contract.mjs';
|
|
42
43
|
import { applyAgentToolExposure } from '../loop/tool-exposure-migration.mjs';
|
|
44
|
+
import { prewarmSessionAutoEffort } from './ask-turn-auto-effort.mjs';
|
|
43
45
|
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
export { isSessionOwnerGone, recoverSessionAfterProcessRestart } from './session-owner-liveness.mjs';
|
|
46
|
+
// Durable turn-checkpoint recovery; re-exported so prior importers of this
|
|
47
|
+
// module stay unchanged.
|
|
48
|
+
export { recoverSessionAfterProcessRestart } from './turn-checkpoint-recovery.mjs';
|
|
48
49
|
// Prepared-surface cache warmers (desktop hover prefetch, pane projection);
|
|
49
50
|
// re-exported so prior importers of this module stay unchanged.
|
|
50
51
|
export { prefetchSession, prepareSessionProjection } from './prepared-resume-cache.mjs';
|
|
@@ -211,6 +212,11 @@ export function createSession(opts) {
|
|
|
211
212
|
const { profile } = resolved;
|
|
212
213
|
const route = resolveSessionRoute(opts, presetObj, profile);
|
|
213
214
|
const { providerName, modelName, provider, toolPreset, id } = route;
|
|
215
|
+
const routeFallbacks = normalizeWorkflowRoute({
|
|
216
|
+
provider: providerName,
|
|
217
|
+
model: modelName,
|
|
218
|
+
fallbacks: Object.hasOwn(opts, 'routeFallbacks') ? opts.routeFallbacks : presetObj?.fallbacks,
|
|
219
|
+
})?.fallbacks;
|
|
214
220
|
// Provider cache strategy — agentRuntime.resolveSync() above is a
|
|
215
221
|
// best-effort injection point (setAgentRuntime() has no live caller
|
|
216
222
|
// today, so that branch never fires); build it directly here so every
|
|
@@ -218,11 +224,7 @@ export function createSession(opts) {
|
|
|
218
224
|
// 'lead', or no agent at all — raw/CLI callers) get their BP4 message
|
|
219
225
|
// tail TTL linked to the user's autoClear idle-sweep config; hidden and
|
|
220
226
|
// public agents keep the flat 5m default (see cache-strategy.mjs docs).
|
|
221
|
-
// Scoped to explicit-breakpoint (Anthropic-family) providers only
|
|
222
|
-
// non-Anthropic branches of buildProviderCacheOpts (e.g. the 'openai'
|
|
223
|
-
// cacheRetention:'24h' shape) were never exercised by createSession
|
|
224
|
-
// before this change, and are left untouched to avoid altering live
|
|
225
|
-
// OpenAI/other-provider request shape as a side effect of this fix.
|
|
227
|
+
// Scoped to explicit-breakpoint (Anthropic-family) providers only.
|
|
226
228
|
const providerCacheOpts = resolved.providerCacheOpts || buildSessionProviderCacheOpts(providerName, id, opts.agent);
|
|
227
229
|
const surface = resolveSessionToolSurface(opts, { profile, toolPreset, modelName });
|
|
228
230
|
const prompt = composeSessionSystem(opts, { profile, providerName, modelName, surface });
|
|
@@ -244,6 +246,7 @@ export function createSession(opts) {
|
|
|
244
246
|
origin: sessionOriginFields(opts, { profile, presetObj, providerCacheOpts, surface }),
|
|
245
247
|
});
|
|
246
248
|
session.providerCacheOptsOverride = Boolean(resolved.providerCacheOpts);
|
|
249
|
+
if (routeFallbacks?.length) session.routeFallbacks = routeFallbacks;
|
|
247
250
|
// A non-native agent sends core + bridge, built from its filtered tools.
|
|
248
251
|
applyAgentToolExposure(session);
|
|
249
252
|
refreshSessionBp3Environment(session, opts.cwd);
|
|
@@ -251,6 +254,7 @@ export function createSession(opts) {
|
|
|
251
254
|
// reads live memory; disk flush is for cross-process / restart durability.
|
|
252
255
|
setLiveSession(session);
|
|
253
256
|
saveSession(session);
|
|
257
|
+
prewarmSessionAutoEffort(session, provider);
|
|
254
258
|
return session;
|
|
255
259
|
}
|
|
256
260
|
|
|
@@ -460,9 +464,8 @@ export function updateSessionRoute(id, route = {}, options = {}) {
|
|
|
460
464
|
}
|
|
461
465
|
|
|
462
466
|
// --- resume (reload tools for a stored session) ---
|
|
463
|
-
//
|
|
464
|
-
//
|
|
465
|
-
// the prepared tool surface it consumes is cached in prepared-resume-cache.mjs.
|
|
467
|
+
// Interrupted-turn recovery lives in turn-checkpoint-recovery.mjs; the
|
|
468
|
+
// prepared tool surface it consumes is cached in prepared-resume-cache.mjs.
|
|
466
469
|
|
|
467
470
|
// Desktop callers pass their selected durable classification as a
|
|
468
471
|
// capability check. Refuse a stale/tampered cross-class resume before any
|
|
@@ -496,25 +499,6 @@ function _applyDesktopResumeScope(session, options) {
|
|
|
496
499
|
return true;
|
|
497
500
|
}
|
|
498
501
|
|
|
499
|
-
// ATTACH (viewer mode, zero ownership): hand back the live transcript
|
|
500
|
-
// under the SAME id, flagged remoteAttached. No tool refresh, no save,
|
|
501
|
-
// no generation claim — the session file remains exclusively the
|
|
502
|
-
// owner's. session-turn-api routes this surface's submits into the
|
|
503
|
-
// shared pending spool instead of running a local turn.
|
|
504
|
-
function _attachViewerSession(session, sessionId) {
|
|
505
|
-
const attached = { ...session, remoteAttached: true };
|
|
506
|
-
delete attached.liveTurnMessages;
|
|
507
|
-
delete attached.toolApprovalHook;
|
|
508
|
-
if (process.env.MIXDOG_DEBUG_SESSION_LOG) {
|
|
509
|
-
try {
|
|
510
|
-
process.stderr.write(`[session] attach-on-resume: ${sessionId} is live elsewhere → viewer attach\n`);
|
|
511
|
-
} catch {
|
|
512
|
-
/* best-effort */
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
return attached;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
502
|
// Refreshes the session's tool surface from the prepared resume when it still
|
|
519
503
|
// matches, warning about tools the preset no longer offers.
|
|
520
504
|
function _refreshResumedTools(session, sessionId, preset) {
|
|
@@ -551,7 +535,6 @@ export async function resumeSession(sessionId, preset, options = {}) {
|
|
|
551
535
|
if (Object.hasOwn(options, 'mcpScopeId')) {
|
|
552
536
|
session.mcpScopeId = String(options.mcpScopeId || '').trim() || null;
|
|
553
537
|
}
|
|
554
|
-
if (_isActivelyOwnedElsewhere(session, sessionId)) return _attachViewerSession(session, sessionId);
|
|
555
538
|
_recoverTurnCheckpointDurably(session, sessionId);
|
|
556
539
|
_refreshResumedTools(session, sessionId, preset);
|
|
557
540
|
refreshSessionProviderCacheOpts(session);
|
|
@@ -563,5 +546,6 @@ export async function resumeSession(sessionId, preset, options = {}) {
|
|
|
563
546
|
process.stderr.write(`[session] resume save failed: ${err?.message || err}\n`);
|
|
564
547
|
} catch {}
|
|
565
548
|
});
|
|
549
|
+
prewarmSessionAutoEffort(session, session.provider ? getProvider(session.provider) : null);
|
|
566
550
|
return session;
|
|
567
551
|
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
} from '../../tools/builtin/runtime-capabilities.mjs';
|
|
19
19
|
import { captureOriginalUserCwd } from '../../../../shared/user-cwd.mjs';
|
|
20
20
|
import { delegationDisabled } from './session-tool-surface.mjs';
|
|
21
|
+
import { contextAckMessage } from '../compact/user-message-kind.mjs';
|
|
21
22
|
|
|
22
23
|
// Preserve the exact pre-layout environment payload: Lead carried the
|
|
23
24
|
// shell preference in Profile Preferences, while any routing surface with
|
|
@@ -89,6 +90,23 @@ export function buildWorkspacePromptContext(session, cwd) {
|
|
|
89
90
|
|
|
90
91
|
// BP1/BP2/BP3 rule blocks plus the volatile environment, composed into the
|
|
91
92
|
// four system blocks; environmentTailContext is the persisted env tail.
|
|
93
|
+
export function sessionRolePromptFields(identity, { ownerIsAgent, toolFreeRole, delegationFree }) {
|
|
94
|
+
const skipRules = identity.skipAgentRules || toolFreeRole;
|
|
95
|
+
let roleRules = '';
|
|
96
|
+
if (!skipRules) {
|
|
97
|
+
roleRules = ownerIsAgent
|
|
98
|
+
? _buildAgentRules(identity.agentRulesProfile)
|
|
99
|
+
: _buildLeadRules({ includeLeadBrief: !delegationFree });
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
roleRules,
|
|
103
|
+
userPrompt: identity.systemPrompt,
|
|
104
|
+
skipRoleCatalog: !ownerIsAgent,
|
|
105
|
+
agent: identity.agent,
|
|
106
|
+
profile: { skip: identity.profileSkip },
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
92
110
|
export function composeSessionSystem(opts, { profile, providerName, modelName, surface }) {
|
|
93
111
|
const { ownerIsAgent, resolvedAgent, skills } = surface;
|
|
94
112
|
// A tool-free hidden role (a one-shot classifier or title writer) carries
|
|
@@ -105,12 +123,14 @@ export function composeSessionSystem(opts, { profile, providerName, modelName, s
|
|
|
105
123
|
model: modelName,
|
|
106
124
|
});
|
|
107
125
|
const delegationFree = delegationDisabled(opts, ownerIsAgent);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
126
|
+
const promptIdentity = {
|
|
127
|
+
systemPrompt: opts.systemPrompt || '',
|
|
128
|
+
skipAgentRules: opts.skipAgentRules === true,
|
|
129
|
+
profileSkip: { ...profile?.skip },
|
|
130
|
+
agent: resolvedAgent,
|
|
131
|
+
agentRulesProfile: surface.agentRulesProfile,
|
|
132
|
+
};
|
|
133
|
+
const roleFields = sessionRolePromptFields(promptIdentity, { ownerIsAgent, toolFreeRole, delegationFree });
|
|
114
134
|
const leadOnly = !skipAgentRules && !ownerIsAgent;
|
|
115
135
|
const metaContext = leadOnly ? _buildLeadMetaContext() : '';
|
|
116
136
|
// Lead-only response language; closes the environment block so no English
|
|
@@ -132,14 +152,10 @@ export function composeSessionSystem(opts, { profile, providerName, modelName, s
|
|
|
132
152
|
? ''
|
|
133
153
|
: loadInstructionFilesContext({ mode: configuredInstructionFilesMode(), cwd: opts.cwd });
|
|
134
154
|
const composed = composeSystemPrompt({
|
|
135
|
-
|
|
155
|
+
...roleFields,
|
|
136
156
|
agentRules: injectedRules || undefined,
|
|
137
|
-
roleRules: roleRules || undefined,
|
|
138
157
|
metaContext: metaContext || undefined,
|
|
139
158
|
languageContext: languageContext || undefined,
|
|
140
|
-
skipRoleCatalog: !ownerIsAgent,
|
|
141
|
-
profile: profile || undefined,
|
|
142
|
-
agent: resolvedAgent,
|
|
143
159
|
workflowContext: opts.workflowContext || null,
|
|
144
160
|
coreMemoryContext: opts.coreMemoryContext || null,
|
|
145
161
|
instructionFilesContext: instructionFilesContext || null,
|
|
@@ -147,7 +163,7 @@ export function composeSessionSystem(opts, { profile, providerName, modelName, s
|
|
|
147
163
|
environmentContext: shellEnvironmentContext,
|
|
148
164
|
provider: providerName || null,
|
|
149
165
|
});
|
|
150
|
-
return { ...composed, environmentTailContext };
|
|
166
|
+
return { ...composed, environmentTailContext, promptIdentity };
|
|
151
167
|
}
|
|
152
168
|
|
|
153
169
|
// 4-BP layout (see composeSystemPrompt docs):
|
|
@@ -188,7 +204,7 @@ export function seedSessionMessages({ baseRules, stableSystemContext, sessionMar
|
|
|
188
204
|
if (files?.length) {
|
|
189
205
|
const fileContext = files.map((f) => `### ${f.path}\n\`\`\`\n${f.content}\n\`\`\``).join('\n\n');
|
|
190
206
|
messages.push({ role: 'user', content: `Reference files:\n\n${fileContext}` });
|
|
191
|
-
messages.push(
|
|
207
|
+
messages.push(contextAckMessage());
|
|
192
208
|
}
|
|
193
209
|
return messages;
|
|
194
210
|
}
|
|
@@ -138,6 +138,8 @@ export function buildSessionRecord({ opts, route, presetObj, surface, prompt, me
|
|
|
138
138
|
agent: opts.agent,
|
|
139
139
|
owner: opts.owner || 'user',
|
|
140
140
|
bp3CoreContext: prompt.sessionMarkerCore,
|
|
141
|
+
promptIdentity: prompt.promptIdentity,
|
|
142
|
+
callerDisallowedTools: [...(opts.callerDisallowedTools ?? opts.disallowedTools ?? [])],
|
|
141
143
|
bp3EnvironmentContext: prompt.environmentTailContext,
|
|
142
144
|
// BP3 core and the volatile environment live in SEPARATE system
|
|
143
145
|
// blocks (cacheTier 'tier3' vs 'env'). Legacy persisted sessions
|
|
@@ -162,9 +164,7 @@ export function buildSessionRecord({ opts, route, presetObj, surface, prompt, me
|
|
|
162
164
|
totalInputTokens: 0,
|
|
163
165
|
totalOutputTokens: 0,
|
|
164
166
|
totalToolCalls: 0,
|
|
165
|
-
// Refreshed on each completed ask() — surfaced by agent type=list
|
|
166
|
-
// debugging + consumed by store.mjs's idle-sweep to reclaim stalled
|
|
167
|
-
// agent sessions past RUNNING_STALL_MS.
|
|
167
|
+
// Refreshed on each completed ask() — surfaced by agent type=list.
|
|
168
168
|
lastUsedAt: Date.now(),
|
|
169
169
|
tokensCumulative: 0,
|
|
170
170
|
...origin,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// manager/turn-checkpoint-recovery.mjs
|
|
2
|
+
// Durable recovery of a turn interrupted by a process restart: an interrupted
|
|
3
|
+
// turn checkpoint is committed as interrupted on resume. Every session runs in
|
|
4
|
+
// the daemon, so a turn is live while this process runs it or while another
|
|
5
|
+
// live process owns the daemon; reads never recover a live turn.
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
import { readSingletonOwner } from '../../../../shared/singleton-owner.mjs';
|
|
8
|
+
import { loadSession, saveSession } from '../store.mjs';
|
|
9
|
+
import { dataDir } from '../store-summary-locations.mjs';
|
|
10
|
+
import { runtimeState, isTurnInFlight } from './runtime-state.mjs';
|
|
11
|
+
import { clearTurnCheckpoint, recoverTurnCheckpoint } from './turn-checkpoint.mjs';
|
|
12
|
+
|
|
13
|
+
/** Whether this session's turn may still be running: in flight in this
|
|
14
|
+
* process, or owned by another live process holding the daemon record. */
|
|
15
|
+
export function isSessionTurnLive(sessionId) {
|
|
16
|
+
if (isTurnInFlight(runtimeState.get(sessionId))) return true;
|
|
17
|
+
const { owner, alive } = readSingletonOwner(join(dataDir(), 'daemon-owner.json'));
|
|
18
|
+
return alive && Number(owner.pid) !== process.pid;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function _recoverTurnCheckpointDurably(session, sessionId) {
|
|
22
|
+
const recovery = recoverTurnCheckpoint(session);
|
|
23
|
+
if (!recovery.changed) return recovery;
|
|
24
|
+
// Recovery is a durable reconnect boundary, not a renderer-only view.
|
|
25
|
+
// Persist before removing the checkpoint so a second crash leaves at
|
|
26
|
+
// least one complete copy of the interrupted turn.
|
|
27
|
+
saveSession(session, {
|
|
28
|
+
sync: true,
|
|
29
|
+
expectedGeneration: session.generation,
|
|
30
|
+
});
|
|
31
|
+
if (recovery.turnToken) {
|
|
32
|
+
clearTurnCheckpoint(sessionId, recovery.turnToken);
|
|
33
|
+
}
|
|
34
|
+
return recovery;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Reconnect-safe historical read used by desktop pane peeks. Unlike a normal
|
|
38
|
+
// read-only load, it resolves a dead owner's durable turn checkpoint before
|
|
39
|
+
// returning the transcript; a live turn is returned untouched.
|
|
40
|
+
export function recoverSessionAfterProcessRestart(sessionId) {
|
|
41
|
+
const session = loadSession(sessionId);
|
|
42
|
+
if (!session || session.closed === true || isSessionTurnLive(sessionId)) return session || null;
|
|
43
|
+
_recoverTurnCheckpointDurably(session, sessionId);
|
|
44
|
+
return session;
|
|
45
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Thin facade over the split session-manager modules in ./manager/.
|
|
3
3
|
//
|
|
4
4
|
// Module map:
|
|
5
|
-
// manager/runtime-liveness.mjs — in-memory stage/
|
|
5
|
+
// manager/runtime-liveness.mjs — in-memory stage/progress + accessors
|
|
6
6
|
// manager/tool-resolution.mjs — tool policy resolution/narrowing
|
|
7
7
|
// manager/context-meta.mjs — context-window / compact-trigger meta
|
|
8
8
|
// manager/prompt-utils.mjs — prompt content shaping helpers
|
|
@@ -45,6 +45,7 @@ export {
|
|
|
45
45
|
markSessionError,
|
|
46
46
|
markSessionCancelled,
|
|
47
47
|
getSessionRuntime,
|
|
48
|
+
isSessionTurnInFlight,
|
|
48
49
|
isSessionCompactionBlocked,
|
|
49
50
|
getSessionProgressSnapshot,
|
|
50
51
|
forEachSessionRuntime,
|
|
@@ -59,19 +60,12 @@ export { previewSessionTools } from './manager/tool-resolution.mjs';
|
|
|
59
60
|
export {
|
|
60
61
|
_mergePendingMessageEntries,
|
|
61
62
|
enqueuePendingMessage,
|
|
62
|
-
enqueueRemotePendingMessage,
|
|
63
|
-
drainForeignUserInjections,
|
|
64
63
|
drainPendingMessages,
|
|
65
64
|
// Shutdown drain so buffered/in-flight spool writes are never abandoned.
|
|
66
65
|
settlePendingMessageWrites,
|
|
67
66
|
markCompletionEntry,
|
|
68
67
|
COMPLETION_NOTIFICATION_KIND,
|
|
69
|
-
pendingMessagesSpoolPath,
|
|
70
68
|
} from './manager/pending-messages.mjs';
|
|
71
|
-
// Interactive-presence sidecar (idle-open ownership signal for the
|
|
72
|
-
// attach-on-resume guard) — resolved through the manager facade so the
|
|
73
|
-
// session-runtime turn API reaches it as mgr.publishSessionPresence.
|
|
74
|
-
export { publishSessionPresence, deleteSessionPresence } from './store.mjs';
|
|
75
69
|
|
|
76
70
|
// ── Usage-metrics surface — re-exported unchanged so loop.mjs / smoke scripts
|
|
77
71
|
// keep resolving these through the facade. ────────────────────────────────
|
|
@@ -105,7 +99,6 @@ export {
|
|
|
105
99
|
prefetchSession,
|
|
106
100
|
prepareSessionProjection,
|
|
107
101
|
resumeSession,
|
|
108
|
-
isSessionOwnerGone,
|
|
109
102
|
recoverSessionAfterProcessRestart,
|
|
110
103
|
} from './manager/session-lifecycle.mjs';
|
|
111
104
|
export { askSession, _api_call_with_interrupt } from './manager/ask-session.mjs';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// wrappers are installed on the caller's opts in place for ONE send, and the
|
|
4
4
|
// returned restore unwinds only our own wrappers.
|
|
5
5
|
import { isVisibleStreamProgress } from '../../../shared/stream-progress.mjs';
|
|
6
|
+
import { MODEL_THINKING_STAGE } from '../../../shared/quiet-progress.mjs';
|
|
6
7
|
|
|
7
8
|
// Bench-only turn timing (MIXDOG_TURN_TIMING=1): one stderr line per
|
|
8
9
|
// provider request — TTFT (first visible model progress) and total stream
|
|
@@ -61,7 +62,7 @@ function retryVisibilityWrappers(opts, timedOpts, retryAttemptNumber, retryMaxFo
|
|
|
61
62
|
if (!(retryAttemptNumber > 0 && prevOnStageChange)) return wrappers;
|
|
62
63
|
let progressObserved = false;
|
|
63
64
|
wrappers.onStageChange = (stage, detail) => {
|
|
64
|
-
if (!progressObserved && (stage === 'requesting' || stage === 'streaming')) {
|
|
65
|
+
if (!progressObserved && (stage === 'requesting' || stage === 'streaming' || stage === MODEL_THINKING_STAGE)) {
|
|
65
66
|
return prevOnStageChange('reconnecting', {
|
|
66
67
|
...(detail && typeof detail === 'object' ? detail : {}),
|
|
67
68
|
attempt: retryAttemptNumber,
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
isThinkingReplayRejection,
|
|
38
38
|
repairThinkingReplayInPlace,
|
|
39
39
|
} from './thinking-replay-recovery.mjs';
|
|
40
|
-
import { readStreamOutcome } from '../providers/lib/stream-outcome.mjs';
|
|
40
|
+
import { readStreamOutcome, stampStreamOutcome } from '../providers/lib/stream-outcome.mjs';
|
|
41
41
|
import { cloneProviderReplay } from '../providers/lib/provider-replay.mjs';
|
|
42
42
|
import { resolveWorkerCompactPolicy } from './loop/compact-policy.mjs';
|
|
43
43
|
import { agentContextOverflowError } from './loop/context-overflow.mjs';
|
|
@@ -260,6 +260,7 @@ export async function sendWithRecovery(ctx) {
|
|
|
260
260
|
hooks.logTurnTiming('ok');
|
|
261
261
|
} catch (sendErr) {
|
|
262
262
|
hooks.logTurnTiming(`err:${sendErr?.code || sendErr?.name || 'unknown'}`);
|
|
263
|
+
stampStreamOutcome(sendErr, hooks.relayWitness);
|
|
263
264
|
return await recoverFromSendError(sendErr, { ...ctx, relayWitness: hooks.relayWitness });
|
|
264
265
|
}
|
|
265
266
|
return { action: 'proceed', response };
|
|
@@ -454,7 +455,9 @@ async function recoverFromSendError(sendErr, state) {
|
|
|
454
455
|
if (toolSchemaDropUsed !== true) {
|
|
455
456
|
const exclusion = rejectedToolSchema(sendErr, state);
|
|
456
457
|
if (exclusion) {
|
|
457
|
-
logLoop(
|
|
458
|
+
logLoop(
|
|
459
|
+
`[loop] provider rejected tool schema "${exclusion.name}" (${loopTag(state)}); dropping it and replaying once`
|
|
460
|
+
);
|
|
458
461
|
traceLoop(state, 'tool_schema_drop', { tool: exclusion.name });
|
|
459
462
|
return { action: 'retry_tool_schema_drop', exclusion };
|
|
460
463
|
}
|
|
@@ -54,7 +54,7 @@ function sideQuestionPrompt(question) {
|
|
|
54
54
|
function replyMessages(response) {
|
|
55
55
|
if (!response) return [];
|
|
56
56
|
const reply = response.toolCalls?.length
|
|
57
|
-
? buildToolCallAssistantMessage(response, { calls: response.toolCalls,
|
|
57
|
+
? buildToolCallAssistantMessage(response, { calls: response.toolCalls, opts: {} })
|
|
58
58
|
: buildIntermediateAssistantMessage(response, {});
|
|
59
59
|
if (!reply) return [];
|
|
60
60
|
const stubs = collectAssistantToolCallIds(reply).map((id) => ({
|
|
@@ -165,12 +165,17 @@ export async function askSideQuestion(sessionId, question) {
|
|
|
165
165
|
const { messages, opts } = buildSideQuestionRequest(request, text);
|
|
166
166
|
let response;
|
|
167
167
|
try {
|
|
168
|
-
response = await request.provider.send(
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
168
|
+
response = await request.provider.send(
|
|
169
|
+
messages,
|
|
170
|
+
request.model,
|
|
171
|
+
request.tools.length ? request.tools : undefined,
|
|
172
|
+
{
|
|
173
|
+
...opts,
|
|
174
|
+
transportScope,
|
|
175
|
+
admissionOwner: sessionId,
|
|
176
|
+
signal: run.signal,
|
|
177
|
+
}
|
|
178
|
+
);
|
|
174
179
|
} catch (error) {
|
|
175
180
|
throw run.signal.aborted ? run.signal.reason : error;
|
|
176
181
|
}
|
|
@@ -11,7 +11,7 @@ import { join } from 'node:path';
|
|
|
11
11
|
import { getPluginData } from '../../config.mjs';
|
|
12
12
|
import { PLUGIN_LOG_MAX_BYTES, PLUGIN_LOG_KEEP_BYTES } from '../../../../../lib/mixdog-debug.cjs';
|
|
13
13
|
import { createAsyncLogAppender } from '../../../../shared/async-log-appender.mjs';
|
|
14
|
-
import { sessionPath
|
|
14
|
+
import { sessionPath } from './session-paths.mjs';
|
|
15
15
|
import {
|
|
16
16
|
readCanonicalSessionRecord as _readCanonicalRecord,
|
|
17
17
|
CANONICAL_RECORD_UNREADABLE as LIFECYCLE_AMBIGUOUS,
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
} from './live-state.mjs';
|
|
37
37
|
import { _uncacheSessionSummary, _queueSessionSummaryUpsert } from './summary-cache.mjs';
|
|
38
38
|
import { _savePending, _clearDebounce } from './pending-saves.mjs';
|
|
39
|
-
import { _runtimeLivenessVeto
|
|
39
|
+
import { _runtimeLivenessVeto } from './liveness-veto.mjs';
|
|
40
40
|
import { loadSession } from './load-session.mjs';
|
|
41
41
|
|
|
42
42
|
// Cancellation truth, single rule: an UNCONFIRMED stop outranks a confirmed
|
|
@@ -185,15 +185,11 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
185
185
|
// Caller-provided probes may re-enter the store, so evaluate them before
|
|
186
186
|
// taking the non-reentrant Atomics commit lock. A veto must also precede
|
|
187
187
|
// pending-save cancellation so debounce durability remains intact.
|
|
188
|
-
if (_runtimeLivenessVeto(id, options)
|
|
188
|
+
if (_runtimeLivenessVeto(id, options)) return null;
|
|
189
189
|
const closeGuard = _guardedSaveOptions(id);
|
|
190
190
|
const commitControl = _acquireWriteCommit(closeGuard);
|
|
191
191
|
if (commitControl === false) return null;
|
|
192
192
|
try {
|
|
193
|
-
// Cross-process heartbeat revival after full-TTL silence is accepted as a
|
|
194
|
-
// best-effort race: the tombstone resurrection guard is the authoritative
|
|
195
|
-
// post-race arbiter. Re-stat here, but never invoke caller code under lock.
|
|
196
|
-
if (_heartbeatLivenessVeto(id, options)) return null;
|
|
197
193
|
const authority = _readLifecycleAuthority(id, reason, 'close');
|
|
198
194
|
if (authority === LIFECYCLE_AMBIGUOUS) return null;
|
|
199
195
|
// Only a committed close may disrupt pending persistence.
|
|
@@ -230,7 +226,7 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
230
226
|
const tombstone = {
|
|
231
227
|
...base,
|
|
232
228
|
closed: true,
|
|
233
|
-
closedReason: alreadyClosed ? base.closedReason || reason : reason,
|
|
229
|
+
closedReason: alreadyClosed && reason !== 'desktop-session-delete' ? base.closedReason || reason : reason,
|
|
234
230
|
status: 'closed',
|
|
235
231
|
generation: newGen,
|
|
236
232
|
updatedAt: closeTime,
|
|
@@ -240,8 +236,6 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
240
236
|
_savePending.delete(id);
|
|
241
237
|
clearSessionSaveError(id);
|
|
242
238
|
_clearLiveSession(id);
|
|
243
|
-
// Preserve a sidecar published strictly after the sweep's scan snapshot.
|
|
244
|
-
_deleteHeartbeatUnlessNewer(id, options);
|
|
245
239
|
_queueSessionSummaryUpsert(tombstone);
|
|
246
240
|
_droppedSaveIds.delete(id);
|
|
247
241
|
// Emit the close metric only on the FIRST close — a re-close of an
|
|
@@ -257,7 +251,7 @@ export function markSessionClosed(id, reason = 'manual', options = {}) {
|
|
|
257
251
|
/**
|
|
258
252
|
* Bump a session's generation WITHOUT planting a closed:true tombstone.
|
|
259
253
|
* Used by closeSession(id, reason, { tombstone: false }) — the runtime side
|
|
260
|
-
* (
|
|
254
|
+
* (bash shells, controller, in-memory entry) is detached, but the
|
|
261
255
|
* session file itself stays valid/resumable. The generation bump alone is
|
|
262
256
|
* what protects it from a late save race: any saveSession() still in flight
|
|
263
257
|
* from the detached turn was issued with the OLD generation as its
|
|
@@ -299,7 +293,6 @@ export function bumpSessionGeneration(id, reason = 'detach', options = {}) {
|
|
|
299
293
|
_savePending.delete(id);
|
|
300
294
|
clearSessionSaveError(id);
|
|
301
295
|
_clearLiveSession(id);
|
|
302
|
-
deleteHeartbeat(id);
|
|
303
296
|
_queueSessionSummaryUpsert(detached);
|
|
304
297
|
_droppedSaveIds.delete(id);
|
|
305
298
|
return newGen;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* path and of the in-memory snapshot caches.
|
|
7
7
|
*/
|
|
8
8
|
import { readCanonicalSessionRecord, CANONICAL_RECORD_UNREADABLE } from './canonical-reader.mjs';
|
|
9
|
-
import { sessionPath } from './paths
|
|
9
|
+
import { sessionPath } from './session-paths.mjs';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Cheap authoritative lifecycle read straight from disk (no live/pending
|