mixdog 1.2.3 → 1.2.4
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/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 +6 -1
- package/src/defaults/skills/image/SKILL.md +21 -23
- package/src/lib/keychain-cjs.cjs +13 -11
- package/src/rules/agent/AGENT.md +7 -5
- package/src/rules/lead/LEAD.md +7 -9
- 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 +136 -196
- 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/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 +478 -251
- 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/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
|
@@ -41,6 +41,9 @@ export function resolveAgentSpawnPreset(config, args = {}) {
|
|
|
41
41
|
type: 'agent',
|
|
42
42
|
provider: agentRoute.provider,
|
|
43
43
|
model: agentRoute.model,
|
|
44
|
+
...(config.agents?.[agentName]?.fallbacks?.length
|
|
45
|
+
? { fallbacks: config.agents[agentName].fallbacks.map(normalizeAgentRoute) }
|
|
46
|
+
: {}),
|
|
44
47
|
effort: agentRoute.effort,
|
|
45
48
|
fast: agentRoute.fast === true,
|
|
46
49
|
...(agentRoute.autoEffort === false ? { autoEffort: false } : {}),
|
|
@@ -61,15 +61,13 @@ export function createTagLookup({ tags, mgr, readWorkerRows, reaper, getLiveSess
|
|
|
61
61
|
};
|
|
62
62
|
for (const row of readWorkerRows(context)) addIndexRow(row);
|
|
63
63
|
if (scanSessions) {
|
|
64
|
-
const pendingTerminal = [];
|
|
65
64
|
for (const session of mgr.listSessions({ includeClosed: false }) || []) {
|
|
66
65
|
if (session?.closed === true) continue;
|
|
67
66
|
const tag = agentTagOf(session);
|
|
68
67
|
if (tag && reaper.tombstoneBlocksScan(session, tag, tombstones)) continue;
|
|
69
68
|
add(session, tag);
|
|
70
|
-
if (tag) reaper.scanUpsertSession(session, tag, tombstones
|
|
69
|
+
if (tag) reaper.scanUpsertSession(session, tag, tombstones);
|
|
71
70
|
}
|
|
72
|
-
reaper.settleScannedTerminalRows(pendingTerminal);
|
|
73
71
|
}
|
|
74
72
|
for (const [tag, sessionId] of tags.entries()) {
|
|
75
73
|
const session = getLiveSession(sessionId);
|
|
@@ -18,7 +18,6 @@ export function createTagRefresh({ tags, tagMaps, mgr, reaper, refreshTagsFromIn
|
|
|
18
18
|
// Tags missing from the index are exactly the ones a reap just removed, so
|
|
19
19
|
// the tombstone (not the still-open session record) decides whether this
|
|
20
20
|
// scan may re-bind them.
|
|
21
|
-
const pendingTerminal = [];
|
|
22
21
|
for (const session of mgr.listSessions({ includeClosed: false }) || []) {
|
|
23
22
|
if (isLeadPoolAgent(session?.agent)) continue;
|
|
24
23
|
if (session?.closed === true) continue;
|
|
@@ -27,8 +26,7 @@ export function createTagRefresh({ tags, tagMaps, mgr, reaper, refreshTagsFromIn
|
|
|
27
26
|
if (!sessionMatchesContext(session, context)) continue;
|
|
28
27
|
if (reaper.tombstoneBlocksScan(session, tag, tombstones)) continue;
|
|
29
28
|
tagMaps.bind(tag, session);
|
|
30
|
-
reaper.scanUpsertSession(session, tag, tombstones
|
|
29
|
+
reaper.scanUpsertSession(session, tag, tombstones);
|
|
31
30
|
}
|
|
32
|
-
reaper.settleScannedTerminalRows(pendingTerminal);
|
|
33
31
|
};
|
|
34
32
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Tag registry: owns the tag maps (tag -> sessionId/agent/cwd) and every
|
|
2
2
|
// resolution/mutation path — resolve/next/bind/forget and the session-index
|
|
3
3
|
// refresh. Worker-index persistence lives in worker-index.mjs and terminal
|
|
4
|
-
// tombstones
|
|
4
|
+
// tombstones in terminal-reaper.mjs; the tag maps are shared by
|
|
5
5
|
// reference so all three sides see the same live state.
|
|
6
6
|
import { agentTagOf } from './helpers.mjs';
|
|
7
7
|
import { createLeadWorkerIndex } from './lead-worker-index.mjs';
|
|
@@ -27,6 +27,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
27
27
|
dataDir,
|
|
28
28
|
cfgMod,
|
|
29
29
|
workerRowFromSession: index.workerRowFromSession,
|
|
30
|
+
isSessionRunning: (sessionId) => mgr.isSessionTurnInFlight?.(sessionId) === true,
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
const { upsertLeadSession, updateLeadWorkerCwd, forgetLeadSession } = leadIndex;
|
|
@@ -66,7 +67,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
66
67
|
return null;
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
const reaper = createTerminalReaper({ cfgMod, mgr, tagMaps, index, getLiveSession
|
|
70
|
+
const reaper = createTerminalReaper({ cfgMod, mgr, tagMaps, index, getLiveSession });
|
|
70
71
|
|
|
71
72
|
function wantsSessionScan(args = {}) {
|
|
72
73
|
return args.recover === true || args.scanSessions === true || args.scan_sessions === true;
|
|
@@ -102,8 +103,6 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
102
103
|
removeWorkerRow({ tag, sessionId });
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
reaper.recoverTerminalReaps();
|
|
106
|
-
|
|
107
106
|
return {
|
|
108
107
|
dispose,
|
|
109
108
|
disposeAsync,
|
|
@@ -123,7 +122,6 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
123
122
|
tags,
|
|
124
123
|
tagAgents: tagMaps.tagAgents,
|
|
125
124
|
tagCwds: tagMaps.tagCwds,
|
|
126
|
-
reapTimers: reaper.reapTimers,
|
|
127
125
|
wantsSessionScan,
|
|
128
126
|
resolveTag,
|
|
129
127
|
getLiveSession,
|
|
@@ -138,10 +136,6 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
138
136
|
tombstoneTerminalSession: reaper.tombstoneTerminalSession,
|
|
139
137
|
tagTombstoneForTag: reaper.tagTombstoneForTag,
|
|
140
138
|
consumeTagTombstone: reaper.consumeTagTombstone,
|
|
141
|
-
cancelReap: reaper.cancelReap,
|
|
142
|
-
clearScheduledReaps: reaper.clearScheduledReaps,
|
|
143
|
-
scheduleReap: reaper.scheduleReap,
|
|
144
|
-
recoverTerminalReaps: reaper.recoverTerminalReaps,
|
|
145
139
|
transitionStaleNonterminalRows: reaper.transitionStaleNonterminalRows,
|
|
146
140
|
};
|
|
147
141
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
// Session-scan admission: whether a scan may (re)index a session, and how a
|
|
2
|
-
// terminal session's frozen stamps
|
|
3
|
-
|
|
4
|
-
import { agentTagOf, clean, stampMs } from '../helpers.mjs';
|
|
2
|
+
// terminal session's frozen stamps are re-emitted onto its row.
|
|
3
|
+
import { clean, stampMs } from '../helpers.mjs';
|
|
5
4
|
import { isTerminalWorkerStatus } from '../worker-rows.mjs';
|
|
6
5
|
import { ACTIVE_STAGES } from '../tool-def.mjs';
|
|
7
|
-
import { resolveAgentTerminalReapMs } from '../../../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
8
6
|
import { sessionActivityAt } from './row-helpers.mjs';
|
|
9
7
|
|
|
10
|
-
export function createScanAdmission({
|
|
8
|
+
export function createScanAdmission({ mgr, index, tombstoneBlocksScan }) {
|
|
11
9
|
const { readWorkerRows, upsertWorkerSessionDeferred } = index;
|
|
12
10
|
|
|
13
11
|
function scanSessionIsTerminal(session) {
|
|
@@ -23,7 +21,7 @@ export function createScanAdmission({ cfgMod, mgr, index, tombstoneBlocksScan, t
|
|
|
23
21
|
/** Extra fields for a scan/rebind upsert of an already-terminal session. The
|
|
24
22
|
* default row build stamps updatedAt = now and clears reapAt, which restarts
|
|
25
23
|
* the lease from the read instead of from the work: a terminal session owns
|
|
26
|
-
* its frozen stamps,
|
|
24
|
+
* its frozen stamps, which are kept as-is with no reap deadline. Returns null for
|
|
27
25
|
* running/active sessions so they keep the normal (now-based) behavior. */
|
|
28
26
|
function terminalScanExtra(session) {
|
|
29
27
|
if (!scanSessionIsTerminal(session)) return null;
|
|
@@ -34,56 +32,25 @@ export function createScanAdmission({ cfgMod, mgr, index, tombstoneBlocksScan, t
|
|
|
34
32
|
const stamp = new Date(terminalAtMs).toISOString();
|
|
35
33
|
const sessionId = clean(session?.id);
|
|
36
34
|
const existing = readWorkerRows().find((row) => clean(row.sessionId) === sessionId) || null;
|
|
37
|
-
const reapMs = resolveAgentTerminalReapMs(
|
|
38
|
-
cfgMod.loadConfig(),
|
|
39
|
-
clean(existing?.provider) || clean(session?.provider)
|
|
40
|
-
);
|
|
41
|
-
// An existing lease is authoritative: a read must never extend or reset it.
|
|
42
|
-
const existingReapMs = stampMs(existing?.reapAt);
|
|
43
|
-
let reapAt = null;
|
|
44
|
-
if (existingReapMs > 0) reapAt = new Date(existingReapMs).toISOString();
|
|
45
|
-
else if (reapMs != null) reapAt = new Date(terminalAtMs + reapMs).toISOString();
|
|
46
35
|
const finishedMs = stampMs(session?.finishedAt) || stampMs(existing?.finishedAt);
|
|
47
36
|
return {
|
|
48
37
|
// Stamps are re-emitted as ISO so a numeric session stamp cannot leak an
|
|
49
38
|
// unparseable value into the row store.
|
|
50
39
|
updatedAt: stamp,
|
|
51
40
|
finishedAt: finishedMs > 0 ? new Date(finishedMs).toISOString() : stamp,
|
|
52
|
-
reapAt,
|
|
41
|
+
reapAt: null,
|
|
53
42
|
};
|
|
54
43
|
}
|
|
55
44
|
|
|
56
45
|
// Shared session-scan admission: returns false when the scan must not
|
|
57
46
|
// resurrect this session, otherwise indexes it (terminal sessions with their
|
|
58
|
-
// own stamps)
|
|
59
|
-
function scanUpsertSession(session, tag, tombstones
|
|
47
|
+
// own stamps).
|
|
48
|
+
function scanUpsertSession(session, tag, tombstones) {
|
|
60
49
|
if (tombstoneBlocksScan(session, tag, tombstones)) return false;
|
|
61
50
|
const extra = terminalScanExtra(session);
|
|
62
51
|
upsertWorkerSessionDeferred(session, tag, extra || {});
|
|
63
|
-
if (extra?.reapAt) {
|
|
64
|
-
pendingTerminal.push({
|
|
65
|
-
tag: agentTagOf(session) || clean(tag),
|
|
66
|
-
sessionId: clean(session.id),
|
|
67
|
-
reapAt: extra.reapAt,
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
52
|
return true;
|
|
71
53
|
}
|
|
72
54
|
|
|
73
|
-
|
|
74
|
-
* already-elapsed deadline is reaped now instead of buying a new window. */
|
|
75
|
-
function settleScannedTerminalRows(pendingTerminal) {
|
|
76
|
-
if (!pendingTerminal.length) return;
|
|
77
|
-
const now = Date.now();
|
|
78
|
-
for (const row of pendingTerminal) {
|
|
79
|
-
const deadline = stampMs(row.reapAt);
|
|
80
|
-
if (!deadline) continue;
|
|
81
|
-
// reapTerminalRow -> tombstoneTerminalSession flushes the deferred upsert
|
|
82
|
-
// first, so the row it matches on is the one this scan just wrote.
|
|
83
|
-
if (deadline <= now) timers.reapTerminalRow(row);
|
|
84
|
-
else if (!timers.isArmedFor(row.sessionId, row.reapAt)) timers.schedulePersistedReap(row);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return { scanUpsertSession, settleScannedTerminalRows };
|
|
55
|
+
return { scanUpsertSession };
|
|
89
56
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Stale non-terminal rows: an index row whose session is gone and whose
|
|
2
|
-
//
|
|
2
|
+
// last row stamp is older than the reap window becomes a tombstone so its tag is
|
|
3
3
|
// freed instead of blocking spawn forever.
|
|
4
4
|
import { clean, positiveInt } from '../helpers.mjs';
|
|
5
5
|
import { TAG_TOMBSTONE_TTL_MS, isLeadPoolAgent, workerRowTime } from '../worker-rows.mjs';
|
|
@@ -16,9 +16,9 @@ export function createStaleRowTransition({ cfgMod, tagMaps, index, getLiveSessio
|
|
|
16
16
|
if (getLiveSession(clean(row.sessionId))) return false;
|
|
17
17
|
const rowTime = workerRowTime(row);
|
|
18
18
|
const reapMs = resolveAgentTerminalReapMs(cfgMod.loadConfig(), row.provider);
|
|
19
|
-
// A row with no timestamp has no usable
|
|
19
|
+
// A row with no timestamp has no usable stamp at all. Explicitly
|
|
20
20
|
// disabled terminal reaping still gets the tombstone TTL as a finite
|
|
21
|
-
//
|
|
21
|
+
// staleness bound, so malformed/running index rows cannot block a
|
|
22
22
|
// tag forever.
|
|
23
23
|
return rowTime <= 0 || Date.now() - rowTime >= (reapMs ?? TAG_TOMBSTONE_TTL_MS);
|
|
24
24
|
});
|
|
@@ -1,46 +1,29 @@
|
|
|
1
|
-
// Terminal-session
|
|
2
|
-
// scan admission guard they impose
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
1
|
+
// Terminal-session bookkeeping for the agent tag registry: tag tombstones, the
|
|
2
|
+
// scan admission guard they impose and stale worker-row transitions. Terminal
|
|
3
|
+
// sessions are never closed on a timer — the session record stays open so the
|
|
4
|
+
// transcript remains visible from the parent task. Each concern lives under
|
|
5
|
+
// ./terminal-reaper/; this file wires them.
|
|
6
6
|
import { createTagTombstones } from './terminal-reaper/tombstones.mjs';
|
|
7
|
-
import { createReapTimers } from './terminal-reaper/reap-timers.mjs';
|
|
8
7
|
import { createScanAdmission } from './terminal-reaper/scan-admission.mjs';
|
|
9
8
|
import { createStaleRowTransition } from './terminal-reaper/stale-rows.mjs';
|
|
10
9
|
|
|
11
|
-
export function createTerminalReaper({ cfgMod, mgr, tagMaps, index, getLiveSession
|
|
10
|
+
export function createTerminalReaper({ cfgMod, mgr, tagMaps, index, getLiveSession }) {
|
|
12
11
|
const tombstones = createTagTombstones({ tagMaps, index });
|
|
13
|
-
const timers = createReapTimers({
|
|
14
|
-
cfgMod,
|
|
15
|
-
mgr,
|
|
16
|
-
index,
|
|
17
|
-
getLiveSession,
|
|
18
|
-
tagForSession,
|
|
19
|
-
tombstoneTerminalSession: tombstones.tombstoneTerminalSession,
|
|
20
|
-
});
|
|
21
12
|
const scan = createScanAdmission({
|
|
22
|
-
cfgMod,
|
|
23
13
|
mgr,
|
|
24
14
|
index,
|
|
25
15
|
tombstoneBlocksScan: tombstones.tombstoneBlocksScan,
|
|
26
|
-
timers,
|
|
27
16
|
});
|
|
28
17
|
const { transitionStaleNonterminalRows } = createStaleRowTransition({ cfgMod, tagMaps, index, getLiveSession });
|
|
29
18
|
|
|
30
19
|
return {
|
|
31
|
-
reapTimers: timers.reapTimers,
|
|
32
20
|
tagTombstoneIndex: tombstones.tagTombstoneIndex,
|
|
33
21
|
tombstoneBlocksScan: tombstones.tombstoneBlocksScan,
|
|
34
22
|
scanUpsertSession: scan.scanUpsertSession,
|
|
35
|
-
settleScannedTerminalRows: scan.settleScannedTerminalRows,
|
|
36
23
|
forgetTerminalSession: tombstones.forgetTerminalSession,
|
|
37
24
|
tombstoneTerminalSession: tombstones.tombstoneTerminalSession,
|
|
38
25
|
tagTombstoneForTag: tombstones.tagTombstoneForTag,
|
|
39
26
|
consumeTagTombstone: tombstones.consumeTagTombstone,
|
|
40
|
-
clearScheduledReaps: timers.clearScheduledReaps,
|
|
41
|
-
cancelReap: timers.cancelReap,
|
|
42
|
-
scheduleReap: timers.scheduleReap,
|
|
43
|
-
recoverTerminalReaps: timers.recoverTerminalReaps,
|
|
44
27
|
transitionStaleNonterminalRows,
|
|
45
28
|
};
|
|
46
29
|
}
|
|
@@ -31,7 +31,6 @@ export function createTerminalTrace({ registry }) {
|
|
|
31
31
|
if (!row) return false;
|
|
32
32
|
registry.refreshTagsFromSessions({ context });
|
|
33
33
|
const sessionId = clean(row.sessionId);
|
|
34
|
-
if (sessionId) registry.cancelReap(sessionId);
|
|
35
34
|
registry.forgetTerminalSession(value, sessionId);
|
|
36
35
|
return true;
|
|
37
36
|
}
|
|
@@ -53,6 +53,13 @@ export const AGENT_TOOL = {
|
|
|
53
53
|
file: { type: 'string', description: 'Path to task text; alternative to prompt/message for spawn/send.' },
|
|
54
54
|
cwd: { type: 'string', description: 'Project directory for a new or respawned agent.' },
|
|
55
55
|
context: { type: 'string', description: 'Extra context for the spawn/send turn.' },
|
|
56
|
+
model: {
|
|
57
|
+
type: 'string',
|
|
58
|
+
description:
|
|
59
|
+
"Spawn only, and only when the user explicitly names a model: runs this one spawn on it instead of the agent's preset route, which stays the default (omit otherwise). Id, display name, or words of it; ambiguous or unknown names fail with candidates. The agent still supplies role and permissions.",
|
|
60
|
+
},
|
|
61
|
+
provider: { type: 'string', description: 'Narrows model to one provider; requires model.' },
|
|
62
|
+
effort: { type: 'string', description: 'Reasoning effort for an explicit model.' },
|
|
56
63
|
},
|
|
57
64
|
required: ['type'],
|
|
58
65
|
additionalProperties: false,
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
// worker-index/row-liveness.mjs
|
|
2
2
|
// Whether an active-looking row still has a live worker behind it, and how a
|
|
3
|
-
// row settles
|
|
4
|
-
import { statSync } from 'node:fs';
|
|
5
|
-
import { resolve } from 'node:path';
|
|
6
|
-
|
|
3
|
+
// row settles (idle, or failed when its runtime died) when it does not.
|
|
7
4
|
import { resolveAgentTerminalReapMs } from '../../../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
8
5
|
import { clean, positiveInt, runtimeAlive } from '../helpers.mjs';
|
|
9
6
|
|
|
@@ -25,24 +22,33 @@ export const isActiveWorkerRow = (row) =>
|
|
|
25
22
|
* with that process (daemon restart), so the flag must not stick. */
|
|
26
23
|
export const isStaleApprovalWait = (row) => Boolean(row?.awaitingUser) && !runtimeAlive(row.runtimePid);
|
|
27
24
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const mtimeMs = statSync(resolve(dataDir, 'sessions', `${id}.hb`)).mtimeMs || 0;
|
|
34
|
-
return mtimeMs > 0 && now - mtimeMs <= WORKER_POOL_FRESH_MS;
|
|
35
|
-
} catch {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
25
|
+
/** The process that ran the row's turn is gone (a restart or crash ended it). */
|
|
26
|
+
export const runtimeDied = (row) => Boolean(positiveInt(row?.runtimePid)) && !runtimeAlive(row.runtimePid);
|
|
27
|
+
|
|
28
|
+
/** The row's turn ended because the process running it went away. */
|
|
29
|
+
export const PROCESS_RESTART_FAILURE = 'process-restart';
|
|
39
30
|
|
|
40
|
-
|
|
41
|
-
|
|
31
|
+
/** The row's turn was stopped by the progress (stall) watchdog. */
|
|
32
|
+
export const WATCHDOG_STALL_FAILURE = 'stalled';
|
|
33
|
+
|
|
34
|
+
/** A turn's settled row status and failure reason: a watchdog stop is a
|
|
35
|
+
* failure whatever partial output it handed back (`finalStatus` may still
|
|
36
|
+
* read `idle` for the job's sake); everything else keeps `finalStatus`. */
|
|
37
|
+
export function settledWorkerStatus(finalStatus, stalled) {
|
|
38
|
+
return stalled
|
|
39
|
+
? { status: 'failed', stage: 'failed', failureReason: WATCHDOG_STALL_FAILURE }
|
|
40
|
+
: { status: finalStatus, stage: finalStatus };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** `isSessionRunning(sessionId)`: the daemon's in-memory answer to whether
|
|
44
|
+
* that session's turn is in flight (every session runs in this process). */
|
|
45
|
+
export function createRowLiveness({ cfgMod, isSessionRunning = () => false }) {
|
|
46
|
+
/** Active status, but its runtime pid is dead, or its turn is not running
|
|
47
|
+
* here and its own update stamp is not fresh either. */
|
|
42
48
|
function isStaleActive(row, now) {
|
|
43
49
|
if (!isActiveWorkerRow(row)) return false;
|
|
44
|
-
if (
|
|
45
|
-
if (
|
|
50
|
+
if (runtimeDied(row)) return true;
|
|
51
|
+
if (isSessionRunning(clean(row.sessionId))) return false;
|
|
46
52
|
const updated = Date.parse(clean(row.updatedAt)) || 0;
|
|
47
53
|
return !(updated > 0 && now - updated <= WORKER_POOL_FRESH_MS);
|
|
48
54
|
}
|
|
@@ -74,5 +80,11 @@ export function createRowLiveness({ dataDir, cfgMod }) {
|
|
|
74
80
|
};
|
|
75
81
|
}
|
|
76
82
|
|
|
77
|
-
|
|
83
|
+
/** The row settled as failed: its turn never finished, and `failureReason`
|
|
84
|
+
* says why. Stamps settle exactly as idleRow's. */
|
|
85
|
+
function failedRow(row, now, failureReason, touch = false) {
|
|
86
|
+
return { ...idleRow(row, now, touch), status: 'failed', stage: 'failed', failureReason };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return { isStaleActive, idleRow, failedRow };
|
|
78
90
|
}
|
|
@@ -52,6 +52,9 @@ export function normalizeWorkerRows(value) {
|
|
|
52
52
|
cwd: clean(row.cwd) || null,
|
|
53
53
|
task_id: clean(row.task_id || row.taskId) || null,
|
|
54
54
|
error: clean(row.error) || null,
|
|
55
|
+
// Why a `failed` row failed (row-liveness, a watchdog stop). Always
|
|
56
|
+
// present, so a later whole-row write clears a stale reason.
|
|
57
|
+
failureReason: clean(row.failureReason) || null,
|
|
55
58
|
permission: clean(row.permission) || null,
|
|
56
59
|
toolPermission: clean(row.toolPermission) || null,
|
|
57
60
|
messages: positiveInt(row.messages) || 0,
|
|
@@ -101,14 +104,14 @@ export function workerRowFromSession(session, fallbackTag = '', extra = {}, getS
|
|
|
101
104
|
// Turn dispatch stamps this; terminal upserts leave it null and the
|
|
102
105
|
// merge in applyWorkerRowUpsert preserves the running turn's value.
|
|
103
106
|
turnStartedAt: clean(extra.turnStartedAt) || null,
|
|
104
|
-
//
|
|
105
|
-
// the new absolute deadline immediately afterwards via scheduleReap().
|
|
107
|
+
// Kept for compatibility with older worker rows; no timer consumes it.
|
|
106
108
|
reapAt: clean(extra.reapAt) || null,
|
|
107
109
|
clientHostPid: positiveInt(extra.clientHostPid) || positiveInt(session?.clientHostPid),
|
|
108
110
|
runtimePid: positiveInt(extra.runtimePid) || process.pid,
|
|
109
111
|
cwd: clean(session?.cwd) || clean(extra.cwd) || null,
|
|
110
112
|
task_id: clean(extra.task_id || extra.taskId) || null,
|
|
111
113
|
error: clean(extra.error) || null,
|
|
114
|
+
failureReason: clean(extra.failureReason) || null,
|
|
112
115
|
permission: clean(session?.permission) || null,
|
|
113
116
|
toolPermission: clean(session?.toolPermission) || null,
|
|
114
117
|
messages: Array.isArray(session?.messages) ? session.messages.length : 0,
|
|
@@ -18,7 +18,13 @@ import {
|
|
|
18
18
|
registerApprovalWaitWriter,
|
|
19
19
|
} from './worker-index/approval-wait.mjs';
|
|
20
20
|
import { createMutationBatch } from './worker-index/mutation-batch.mjs';
|
|
21
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
createRowLiveness,
|
|
23
|
+
isActiveWorkerRow,
|
|
24
|
+
isStaleApprovalWait,
|
|
25
|
+
PROCESS_RESTART_FAILURE,
|
|
26
|
+
runtimeDied,
|
|
27
|
+
} from './worker-index/row-liveness.mjs';
|
|
22
28
|
import { normalizeWorkerRows, workerRowFromSession } from './worker-index/row-shape.mjs';
|
|
23
29
|
import { acquireWorkerRowStore } from './worker-index/row-store.mjs';
|
|
24
30
|
import { findTagTombstone, tagTombstoneKey, tombstoneBlocksWork } from '../../../runtime/shared/agent-reap-state.mjs';
|
|
@@ -35,9 +41,13 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
|
|
|
35
41
|
unreconciled.clear();
|
|
36
42
|
for (const id of ids) reconcileAwaitingUser(id);
|
|
37
43
|
});
|
|
38
|
-
const liveness = createRowLiveness({
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
const liveness = createRowLiveness({
|
|
45
|
+
cfgMod,
|
|
46
|
+
isSessionRunning: (sessionId) => mgr.isSessionTurnInFlight?.(sessionId) === true,
|
|
47
|
+
});
|
|
48
|
+
// Rows this process marked active; settled as failed on exit (their turn
|
|
49
|
+
// dies with the process) so a crash of the host never leaves them
|
|
50
|
+
// "running" forever.
|
|
41
51
|
const activeWorkerKeys = new Set();
|
|
42
52
|
|
|
43
53
|
function readWorkerRows(context = {}) {
|
|
@@ -144,13 +154,17 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
|
|
|
144
154
|
for (const key of keys) {
|
|
145
155
|
const current = byKey.get(key);
|
|
146
156
|
if (!current || positiveInt(current.runtimePid) !== process.pid) continue;
|
|
147
|
-
if (isActiveWorkerRow(current))
|
|
157
|
+
if (isActiveWorkerRow(current)) {
|
|
158
|
+
byKey.set(key, liveness.failedRow(current, now, PROCESS_RESTART_FAILURE, true));
|
|
159
|
+
}
|
|
148
160
|
}
|
|
149
161
|
});
|
|
150
162
|
}
|
|
151
163
|
|
|
152
|
-
// Startup recovery: stale active rows settle
|
|
153
|
-
//
|
|
164
|
+
// Startup recovery: stale active rows settle — as failed when the process
|
|
165
|
+
// that ran their turn is gone (the turn never finished), otherwise to idle —
|
|
166
|
+
// and an approval wait left behind by a runtime that is gone (daemon
|
|
167
|
+
// restart) is cleared.
|
|
154
168
|
function recoverStaleWorkerRows() {
|
|
155
169
|
const now = Date.now();
|
|
156
170
|
const rows = store.readAll();
|
|
@@ -162,7 +176,13 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
|
|
|
162
176
|
for (const row of staleActive) {
|
|
163
177
|
const key = workerRowKey(row);
|
|
164
178
|
const current = byKey.get(key);
|
|
165
|
-
if (current
|
|
179
|
+
if (!current || !liveness.isStaleActive(current, now)) continue;
|
|
180
|
+
byKey.set(
|
|
181
|
+
key,
|
|
182
|
+
runtimeDied(current)
|
|
183
|
+
? liveness.failedRow(current, now, PROCESS_RESTART_FAILURE)
|
|
184
|
+
: liveness.idleRow(current, now)
|
|
185
|
+
);
|
|
166
186
|
}
|
|
167
187
|
});
|
|
168
188
|
}
|
|
@@ -42,6 +42,9 @@ export function createStandaloneAgent({
|
|
|
42
42
|
sessionSurface = null,
|
|
43
43
|
awaitKeychainPrewarm = async () => {},
|
|
44
44
|
isKeychainPrewarmReady = () => true,
|
|
45
|
+
// Provider model catalog for user-pinned spawn models; absent on surfaces
|
|
46
|
+
// without one, where only exact provider + model pass.
|
|
47
|
+
listProviderModels = null,
|
|
45
48
|
}) {
|
|
46
49
|
const canUseSessionSurface = (session) =>
|
|
47
50
|
typeof sessionSurface?.runTurn === 'function' && sessionSurface.canRun?.(session) !== false;
|
|
@@ -105,6 +108,7 @@ export function createStandaloneAgent({
|
|
|
105
108
|
sendFlow,
|
|
106
109
|
closeFlow,
|
|
107
110
|
terminalTrace,
|
|
111
|
+
listProviderModels,
|
|
108
112
|
});
|
|
109
113
|
|
|
110
114
|
function getStatus(context = {}) {
|
|
@@ -18,6 +18,8 @@ export function getProgressWatchdogState(mgr, sessionId) {
|
|
|
18
18
|
registered: Boolean(state?.linked && !state.controller.signal.aborted),
|
|
19
19
|
lastCheckedAt: state?.lastCheckedAt || null,
|
|
20
20
|
error: state?.error || null,
|
|
21
|
+
// The policy this session's watchdog actually enforces.
|
|
22
|
+
policy: state?.watchdogPolicy || null,
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
|