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
|
@@ -11,6 +11,23 @@ import {
|
|
|
11
11
|
readStoredGoalSnapshot,
|
|
12
12
|
} from '../runtime/agent/orchestrator/runtime-core/goal-runtime.mjs';
|
|
13
13
|
|
|
14
|
+
/** Catalog rows with the daemon's in-memory turn activity overlaid: `working`
|
|
15
|
+
* on a session whose own turn is in flight, `agentWorking` on a Lead with an
|
|
16
|
+
* in-flight Agent session. Every session runs in this process, so the runtime
|
|
17
|
+
* state is the whole answer — storage carries no liveness. */
|
|
18
|
+
async function withRuntimeActivity(rows) {
|
|
19
|
+
// The import-free leaf holding the runtime map: no session manager graph.
|
|
20
|
+
const { inFlightSessionActivity } = await import('../runtime/agent/orchestrator/session/manager/runtime-state.mjs');
|
|
21
|
+
const { working, agentWorking } = inFlightSessionActivity();
|
|
22
|
+
if (!working.size) return rows;
|
|
23
|
+
return rows.map((row) => {
|
|
24
|
+
const own = working.has(row?.id);
|
|
25
|
+
const agents = agentWorking.has(row?.id);
|
|
26
|
+
if (!own && !agents) return row;
|
|
27
|
+
return { ...row, ...(own ? { working: true } : {}), ...(agents ? { agentWorking: true } : {}) };
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
14
31
|
export function createStoredSessionViews({ desktopRuntime, dataDir }) {
|
|
15
32
|
return {
|
|
16
33
|
// Settled identity of the files a stored projection is built from; the
|
|
@@ -86,11 +103,14 @@ export function createStoredSessionViews({ desktopRuntime, dataDir }) {
|
|
|
86
103
|
// ignored, full array). An authoritative refresh is never paged.
|
|
87
104
|
const page = options.page && typeof options.page === 'object' ? options.page : null;
|
|
88
105
|
if (page && !refreshFromStorage && store.listStoredSessionSummaryPage) {
|
|
89
|
-
|
|
106
|
+
const listed = await store.listStoredSessionSummaryPage({ limit: page.limit, cursor: page.cursor });
|
|
107
|
+
return { ...listed, sessions: await withRuntimeActivity(listed.sessions) };
|
|
90
108
|
}
|
|
91
109
|
// The async listing may answer from the session catalog DB.
|
|
92
|
-
|
|
93
|
-
|
|
110
|
+
const rows = store.listStoredSessionSummariesAsync
|
|
111
|
+
? await store.listStoredSessionSummariesAsync({ refreshFromStorage })
|
|
112
|
+
: store.listStoredSessionSummaries({ refreshFromStorage });
|
|
113
|
+
return withRuntimeActivity(rows);
|
|
94
114
|
},
|
|
95
115
|
};
|
|
96
116
|
}
|
|
@@ -91,6 +91,7 @@ import { createLagProfiler } from './daemon-lag-profiler.mjs';
|
|
|
91
91
|
import { createChannelsRuntimeLoader } from './daemon-channels-loader.mjs';
|
|
92
92
|
import { createDesktopRuntime } from './daemon-desktop-runtime.mjs';
|
|
93
93
|
import { createCanonicalAgentControl } from './daemon-agent-control.mjs';
|
|
94
|
+
import { createSessionControl } from './daemon-session-control.mjs';
|
|
94
95
|
import { flushAllIndexWrites } from '../session-runtime/services/agent-tool/index-write-queue.mjs';
|
|
95
96
|
import { registerAutomationAgentTool } from '../session-runtime/automation-agents.mjs';
|
|
96
97
|
import {
|
|
@@ -913,6 +914,7 @@ async function main() {
|
|
|
913
914
|
log,
|
|
914
915
|
measureBootPhase: bootPhases.measure,
|
|
915
916
|
executeAgentControl: agentControl.execute,
|
|
917
|
+
executeSessionControl: createSessionControl({ getSessionService: () => sessionService }),
|
|
916
918
|
});
|
|
917
919
|
// Codex-style runtime: daemon routing and independent async session actors
|
|
918
920
|
// share one V8 isolate and module graph. CPU-heavy work stays in bounded
|
|
@@ -165,6 +165,8 @@ export class DesktopServiceRegistry {
|
|
|
165
165
|
moduleUrl: requestedModule,
|
|
166
166
|
instance,
|
|
167
167
|
subscribers: new Set(),
|
|
168
|
+
visibilityEpochs: new Map(),
|
|
169
|
+
nextVisibilityEpoch: 0,
|
|
168
170
|
};
|
|
169
171
|
this.#servicesById.set(requestedId, record);
|
|
170
172
|
this.#servicesByModule.set(requestedModule, record);
|
|
@@ -187,7 +189,14 @@ export class DesktopServiceRegistry {
|
|
|
187
189
|
const service = await this.#initialize(params);
|
|
188
190
|
if (this.#closed) throw new Error('session service is closed');
|
|
189
191
|
const token = subscriberToken(ctx);
|
|
190
|
-
if (token)
|
|
192
|
+
if (token) {
|
|
193
|
+
service.subscribers.add(token);
|
|
194
|
+
// The adapter outlives desktop processes, whose request counters restart.
|
|
195
|
+
// Allocate the ordering namespace here, not from a client's wall clock.
|
|
196
|
+
if (!service.visibilityEpochs.has(token)) {
|
|
197
|
+
service.visibilityEpochs.set(token, ++service.nextVisibilityEpoch);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
191
200
|
this.#syncModelProxyPresence();
|
|
192
201
|
return { desktopId: service.desktopId };
|
|
193
202
|
}
|
|
@@ -215,14 +224,23 @@ export class DesktopServiceRegistry {
|
|
|
215
224
|
}
|
|
216
225
|
|
|
217
226
|
async invoke({ desktopId, method, args = [] } = {}, ctx = null) {
|
|
218
|
-
const { service } = this.#requireSubscribed(desktopId, ctx);
|
|
227
|
+
const { service, token } = this.#requireSubscribed(desktopId, ctx);
|
|
219
228
|
const name = String(method || '');
|
|
220
229
|
if (!name) throw new TypeError('desktop service method is required');
|
|
230
|
+
let callArgs = Array.isArray(args) ? args : [];
|
|
231
|
+
if (name === 'setVisibleSessions' && token) {
|
|
232
|
+
const epoch = service.visibilityEpochs.get(token);
|
|
233
|
+
if (epoch === undefined) {
|
|
234
|
+
service.subscribers.delete(token);
|
|
235
|
+
throw new Error('desktop service client is not initialized');
|
|
236
|
+
}
|
|
237
|
+
callArgs = [callArgs[0], callArgs[1], epoch];
|
|
238
|
+
}
|
|
221
239
|
// `[slow-op] desktop.invoke` names the call it timed: a desktop operation
|
|
222
240
|
// (Git reads) or a session capability, not only the generic route.
|
|
223
241
|
const target = name === 'invokeDesktopOperation' || name === 'invokeCapability' ? String(args?.[0] || '') : '';
|
|
224
242
|
annotateSpan(target ? `${name}:${target}` : name);
|
|
225
|
-
return sanitizeForWire(await service.instance.invoke(name,
|
|
243
|
+
return sanitizeForWire(await service.instance.invoke(name, callArgs)) ?? null;
|
|
226
244
|
}
|
|
227
245
|
|
|
228
246
|
async control({ desktopId, message } = {}, ctx = null) {
|
|
@@ -241,7 +259,7 @@ export class DesktopServiceRegistry {
|
|
|
241
259
|
async unsubscribe({ desktopId } = {}, ctx = null) {
|
|
242
260
|
const service = this.#require(desktopId);
|
|
243
261
|
const token = subscriberToken(ctx);
|
|
244
|
-
if (token) service
|
|
262
|
+
if (token) await this.#releaseSubscriber(service, token);
|
|
245
263
|
this.#syncModelProxyPresence();
|
|
246
264
|
return { ok: true, unsubscribed: true };
|
|
247
265
|
}
|
|
@@ -250,11 +268,20 @@ export class DesktopServiceRegistry {
|
|
|
250
268
|
const token = String(clientToken || '');
|
|
251
269
|
if (!token) return;
|
|
252
270
|
for (const service of this.#servicesById.values()) {
|
|
253
|
-
service.
|
|
271
|
+
void this.#releaseSubscriber(service, token).catch((error) => {
|
|
272
|
+
this.#log(`desktop visibility release failed: ${error?.message || error}`);
|
|
273
|
+
});
|
|
254
274
|
}
|
|
255
275
|
this.#syncModelProxyPresence();
|
|
256
276
|
}
|
|
257
277
|
|
|
278
|
+
async #releaseSubscriber(service, token) {
|
|
279
|
+
service.subscribers.delete(token);
|
|
280
|
+
const epoch = service.visibilityEpochs.get(token);
|
|
281
|
+
service.visibilityEpochs.delete(token);
|
|
282
|
+
if (epoch !== undefined) await service.instance.releaseClient?.(epoch);
|
|
283
|
+
}
|
|
284
|
+
|
|
258
285
|
notifySessionRuntimeReleased(sessionId, reason) {
|
|
259
286
|
// An evicted session has NO session subscribers. Its desktop resources
|
|
260
287
|
// still belong to the desktop service and must be notified on that lane.
|
|
@@ -15,6 +15,7 @@ import { createGoalContinuation } from '../tui/session/goal-continuation.mjs';
|
|
|
15
15
|
import { createToolApproval } from '../tui/session/tool-approval.mjs';
|
|
16
16
|
import { createToolCardResults } from '../tui/session/tool-card-results.mjs';
|
|
17
17
|
import { createAgentJobFeed } from '../tui/session/agent-job-feed.mjs';
|
|
18
|
+
import { createWorktreeSetupNotices } from '../tui/session/worktree-setup-notice.mjs';
|
|
18
19
|
import { createContextState } from '../tui/session/context-state.mjs';
|
|
19
20
|
import { createSessionFlow } from '../tui/session/session-flow.mjs';
|
|
20
21
|
import { createRunTurn } from '../tui/session/turn.mjs';
|
|
@@ -28,7 +29,7 @@ import { createActiveToolTracker } from '../tui/session/active-tool-summary.mjs'
|
|
|
28
29
|
import { createTranscriptStore } from '../tui/session/transcript-store.mjs';
|
|
29
30
|
import { createTranscriptIntake } from '../tui/session/transcript-intake.mjs';
|
|
30
31
|
import { createNoticeSurface } from '../tui/session/notice-surface.mjs';
|
|
31
|
-
import {
|
|
32
|
+
import { rearmGoalContinuationOnSessionBoundaries } from '../tui/session/goal-continuation/session-boundary.mjs';
|
|
32
33
|
import { createTranscriptRouteMetadata } from '../runtime/shared/transcript-metadata.mjs';
|
|
33
34
|
import { formatDoctorReport, runDoctorChecks } from '../tui/app/doctor.mjs';
|
|
34
35
|
// tuiDebug is an opt-in diagnostic trace for the hang chain (runTurn start/end,
|
|
@@ -109,7 +110,6 @@ export { parseBackgroundTaskEnvelope } from '../tui/session/agent-envelope.mjs';
|
|
|
109
110
|
*/
|
|
110
111
|
export function createRuntimePulse({
|
|
111
112
|
flags,
|
|
112
|
-
liveShareMirroring,
|
|
113
113
|
getState,
|
|
114
114
|
getPublishedState,
|
|
115
115
|
set,
|
|
@@ -138,13 +138,6 @@ export function createRuntimePulse({
|
|
|
138
138
|
const pulse = () => {
|
|
139
139
|
if (flags.disposed) return;
|
|
140
140
|
if (flags.pendingSessionReset) return;
|
|
141
|
-
// Attached viewer with a live pipe: the owner's frames are authoritative
|
|
142
|
-
// for stats/agent/tool state. Recomputing them locally here would stomp
|
|
143
|
-
// the mirror with this process's empty registries every 2s.
|
|
144
|
-
if (liveShareMirroring()) {
|
|
145
|
-
publishChanged({ ...routeState() });
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
141
|
syncContextStats({ allowEstimated: true });
|
|
149
142
|
publishChanged({
|
|
150
143
|
...routeState(),
|
|
@@ -177,6 +170,7 @@ export async function createLocalSessionRuntime({
|
|
|
177
170
|
sessionProfile,
|
|
178
171
|
worktree,
|
|
179
172
|
executeAgentControl,
|
|
173
|
+
executeSessionControl,
|
|
180
174
|
} = {}) {
|
|
181
175
|
const startedAt = performance.now();
|
|
182
176
|
bootProfile('session:create:start', { provider: providerName, model, toolMode, remote });
|
|
@@ -209,6 +203,7 @@ export async function createLocalSessionRuntime({
|
|
|
209
203
|
// Session creation worktree intent; consumed by the workspace transition scope.
|
|
210
204
|
...(worktree && typeof worktree === 'object' ? { worktree } : {}),
|
|
211
205
|
...(typeof executeAgentControl === 'function' ? { executeAgentControl } : {}),
|
|
206
|
+
...(typeof executeSessionControl === 'function' ? { executeSessionControl } : {}),
|
|
212
207
|
});
|
|
213
208
|
bootProfile('session:create:runtime-ready', { ms: (performance.now() - startedAt).toFixed(1) });
|
|
214
209
|
const runtimeCwd = runtime.cwd || process.cwd();
|
|
@@ -322,7 +317,6 @@ export async function createLocalSessionRuntime({
|
|
|
322
317
|
);
|
|
323
318
|
const runtimePulse = createRuntimePulse({
|
|
324
319
|
flags,
|
|
325
|
-
liveShareMirroring: () => bag.liveShareMirroring?.() === true,
|
|
326
320
|
getState,
|
|
327
321
|
getPublishedState,
|
|
328
322
|
set,
|
|
@@ -374,9 +368,14 @@ export async function createLocalSessionRuntime({
|
|
|
374
368
|
itemIndexById,
|
|
375
369
|
});
|
|
376
370
|
lifecycle.unsubscribeRuntimeNotifications = subscribeRuntimeNotifications();
|
|
371
|
+
if (typeof runtime.onWorktreeSetup === 'function') {
|
|
372
|
+
lifecycle.unsubscribeWorktreeSetup = runtime.onWorktreeSetup(
|
|
373
|
+
createWorktreeSetupNotices({ pushItem, patchItem, nextId })
|
|
374
|
+
);
|
|
375
|
+
}
|
|
377
376
|
if (typeof runtime.onAgentStatusChange === 'function') {
|
|
378
377
|
lifecycle.unsubscribeAgentStatus = runtime.onAgentStatusChange(() => {
|
|
379
|
-
if (flags.disposed || flags.pendingSessionReset
|
|
378
|
+
if (flags.disposed || flags.pendingSessionReset) return;
|
|
380
379
|
set({ ...agentStatusState({ force: true }) });
|
|
381
380
|
bag.scheduleGoalContinuation?.();
|
|
382
381
|
});
|
|
@@ -474,7 +473,7 @@ export async function createLocalSessionRuntime({
|
|
|
474
473
|
bag.runTurn = createRunTurn(bag);
|
|
475
474
|
bag.doctor = { runDoctorChecks, formatDoctorReport };
|
|
476
475
|
const api = createSessionApi(bag);
|
|
477
|
-
|
|
476
|
+
rearmGoalContinuationOnSessionBoundaries({ api, bag });
|
|
478
477
|
void Promise.resolve(bag.restoreLeadSteeringFromDisk())
|
|
479
478
|
.catch(() => {})
|
|
480
479
|
.finally(() => {
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
export const SESSION_READ_ACTIONS = Object.freeze([
|
|
9
|
+
'inspectProjectBranch',
|
|
10
|
+
'isSessionTerminal',
|
|
9
11
|
'contextStatus',
|
|
10
12
|
'getAgentDefinition',
|
|
11
13
|
'getAutoClear',
|
|
@@ -18,6 +20,7 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
18
20
|
'getDisabledSkills',
|
|
19
21
|
'getMediaDefault',
|
|
20
22
|
'getMediaJob',
|
|
23
|
+
'getMediaPins',
|
|
21
24
|
'getMcpServerConfig',
|
|
22
25
|
'getMcpOAuthLoginStatus',
|
|
23
26
|
'getOnboardingStatus',
|
|
@@ -71,6 +74,7 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
71
74
|
'listProviders',
|
|
72
75
|
'listWebSearchModels',
|
|
73
76
|
'listThemes',
|
|
77
|
+
'listShellJobs',
|
|
74
78
|
'listWorkflows',
|
|
75
79
|
'mcpStatus',
|
|
76
80
|
'pluginsStatus',
|
|
@@ -194,6 +198,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
194
198
|
'startLocalProviderModelMaintenance',
|
|
195
199
|
'deleteLocalProviderModel',
|
|
196
200
|
'setMediaDefault',
|
|
201
|
+
'setMediaPin',
|
|
197
202
|
'setModel',
|
|
198
203
|
'setOutputStyle',
|
|
199
204
|
'setPluginEnabled',
|
|
@@ -219,6 +224,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
219
224
|
'startConversationImport',
|
|
220
225
|
'startMediaJob',
|
|
221
226
|
'stopShellJob',
|
|
227
|
+
'releaseShellJob',
|
|
222
228
|
'switchContext',
|
|
223
229
|
'taskControl',
|
|
224
230
|
'testWebhook',
|
|
@@ -233,6 +239,7 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
233
239
|
'selectBranch',
|
|
234
240
|
'selectProjectBranch',
|
|
235
241
|
'mergeProjectBranch',
|
|
242
|
+
'manageProjectBranch',
|
|
236
243
|
'requestWorktree',
|
|
237
244
|
'mergeWorkspace',
|
|
238
245
|
'removeWorktree',
|
|
@@ -27,6 +27,7 @@ export function createInlineSessionRuntimeHost({
|
|
|
27
27
|
await keychain.prewarmSecrets();
|
|
28
28
|
},
|
|
29
29
|
executeAgentControl = null,
|
|
30
|
+
executeSessionControl = null,
|
|
30
31
|
} = {}) {
|
|
31
32
|
let closed = false;
|
|
32
33
|
let closePromise = null;
|
|
@@ -59,6 +60,7 @@ export function createInlineSessionRuntimeHost({
|
|
|
59
60
|
...options,
|
|
60
61
|
...(options.cwd ? {} : { cwd }),
|
|
61
62
|
...(typeof executeAgentControl === 'function' ? { executeAgentControl } : {}),
|
|
63
|
+
...(typeof executeSessionControl === 'function' ? { executeSessionControl } : {}),
|
|
62
64
|
});
|
|
63
65
|
if (closed) {
|
|
64
66
|
try {
|
|
@@ -24,7 +24,7 @@ export function createAgentCancellation({
|
|
|
24
24
|
log,
|
|
25
25
|
rememberCancelTranscript,
|
|
26
26
|
}) {
|
|
27
|
-
const
|
|
27
|
+
const agentCloseRuns = new Map();
|
|
28
28
|
|
|
29
29
|
/** The runtime entry that can close this descriptor: the live owner, else a
|
|
30
30
|
* freshly loaded one (null when loading fails, which is logged). */
|
|
@@ -44,66 +44,108 @@ export function createAgentCancellation({
|
|
|
44
44
|
}
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
function
|
|
48
|
-
const
|
|
49
|
-
if (!id) return Promise.resolve(false);
|
|
50
|
-
const active = agentCancelRuns.get(id);
|
|
47
|
+
function closeOne(id, reason, options) {
|
|
48
|
+
const active = agentCloseRuns.get(id);
|
|
51
49
|
if (active) return active;
|
|
52
50
|
let run;
|
|
53
|
-
run = (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
run = Promise.resolve()
|
|
52
|
+
.then(async () => {
|
|
53
|
+
cancelBackgroundTasks({
|
|
54
|
+
surface: 'agent',
|
|
55
|
+
callerSessionId: id,
|
|
56
|
+
reason,
|
|
57
|
+
});
|
|
58
|
+
cancelOwnAgentTasks(id, reason);
|
|
59
|
+
const descriptor = registry.get(id);
|
|
60
|
+
if (!descriptor) return false;
|
|
61
|
+
if ((await sessionOwner(id)?.runtime?.isSessionTerminal?.()) === true) return true;
|
|
62
|
+
const entry = await closableEntry(id, descriptor);
|
|
63
|
+
const closeCanonical = entry?.runtime?.closeCanonicalSession;
|
|
64
|
+
if (typeof closeCanonical !== 'function') {
|
|
65
|
+
throw new TypeError('session runtime must implement closeCanonicalSession');
|
|
66
|
+
}
|
|
67
|
+
// The close clears the transcript: capture a running turn's transcript
|
|
68
|
+
// first so the cancelled turn still hands off its partial output.
|
|
69
|
+
if (descriptor.status === 'running') {
|
|
70
|
+
try {
|
|
71
|
+
const { messages } = await entry.runtime.readModelMessages(0);
|
|
72
|
+
rememberCancelTranscript(id, messages);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
log(`agent cancel transcript read failed session=${id}: ${error?.message || error}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const closed = await closeCanonical.call(entry.runtime, reason, { tombstone: options.tombstone === true });
|
|
78
|
+
if (closed !== true) throw new Error(`agent session ${id} could not be durably closed`);
|
|
79
|
+
descriptor.closed = options.tombstone === true;
|
|
80
|
+
descriptor.status = descriptor.closed ? 'closed' : 'cancelled';
|
|
81
|
+
descriptor.stage = descriptor.status;
|
|
82
|
+
descriptor.updatedAt = Date.now();
|
|
83
|
+
return true;
|
|
84
|
+
})
|
|
85
|
+
.finally(() => {
|
|
86
|
+
if (agentCloseRuns.get(id) === run) agentCloseRuns.delete(id);
|
|
59
87
|
});
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
88
|
+
agentCloseRuns.set(id, run);
|
|
89
|
+
return run;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
async function cancelAgentTree(sessionId, reason = 'agent session cancelled', options = {}) {
|
|
93
|
+
const id = String(sessionId || '').trim();
|
|
94
|
+
if (!id) return false;
|
|
95
|
+
await rehydrateAgentSessions();
|
|
96
|
+
const seen = new Set();
|
|
97
|
+
const ordered = [];
|
|
98
|
+
const visit = (current) => {
|
|
99
|
+
if (seen.has(current)) return;
|
|
100
|
+
seen.add(current);
|
|
101
|
+
for (const child of registry.childrenOf(current)) visit(child);
|
|
102
|
+
ordered.push(current);
|
|
103
|
+
};
|
|
104
|
+
visit(id);
|
|
105
|
+
const release = registry.beginCancellation(ordered);
|
|
106
|
+
try {
|
|
107
|
+
let closed = false;
|
|
108
|
+
const failures = [];
|
|
109
|
+
// Descendant-first, one at a time; a failed member never skips the rest.
|
|
110
|
+
for (const current of ordered) {
|
|
74
111
|
try {
|
|
75
|
-
|
|
76
|
-
rememberCancelTranscript(id, messages);
|
|
112
|
+
closed = (await closeOne(current, reason, options)) || closed;
|
|
77
113
|
} catch (error) {
|
|
78
|
-
log(`agent cancel
|
|
114
|
+
log(`agent cancel failed session=${current}: ${error?.message || error}`);
|
|
115
|
+
failures.push(error);
|
|
79
116
|
}
|
|
80
117
|
}
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
118
|
+
if (failures.length === 1) throw failures[0];
|
|
119
|
+
if (failures.length) {
|
|
120
|
+
const details = failures.map((error) => error?.message || String(error)).join('; ');
|
|
121
|
+
throw new AggregateError(
|
|
122
|
+
failures,
|
|
123
|
+
`agent tree cancel failed for ${failures.length} of ${ordered.length} sessions: ${details}`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return closed;
|
|
127
|
+
} finally {
|
|
128
|
+
release();
|
|
129
|
+
}
|
|
93
130
|
}
|
|
94
131
|
|
|
95
132
|
async function cancelAgentDescendants(parentSessionId, reason = 'parent session cancelled') {
|
|
96
133
|
await rehydrateAgentSessions();
|
|
97
134
|
const parentId = String(parentSessionId || '');
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
135
|
+
const release = registry.beginCancellation([parentId]);
|
|
136
|
+
try {
|
|
137
|
+
cancelBackgroundTasks({
|
|
138
|
+
surface: 'agent',
|
|
139
|
+
callerSessionId: parentId,
|
|
140
|
+
reason,
|
|
141
|
+
});
|
|
142
|
+
const children = registry.childrenOf(parentId);
|
|
143
|
+
if (!children.length) return false;
|
|
144
|
+
await Promise.all(children.map((childId) => cancelAgentTree(childId, reason)));
|
|
145
|
+
return true;
|
|
146
|
+
} finally {
|
|
147
|
+
release();
|
|
148
|
+
}
|
|
107
149
|
}
|
|
108
150
|
|
|
109
151
|
return { cancelAgentTree, cancelAgentDescendants };
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
// caller's spec, creation of the runtime behind it, and the descriptor linked
|
|
4
4
|
// into the agent registry. Running a turn on that child is ./agent-turns.mjs.
|
|
5
5
|
|
|
6
|
-
export function createAgentChildFactory({ registry, rehydrateAgentSessions, createSession }) {
|
|
6
|
+
export function createAgentChildFactory({ registry, rehydrateAgentSessions, createSession, entryForSession }) {
|
|
7
7
|
return async function createAgentChild({ spec = {}, tag = null } = {}) {
|
|
8
8
|
await rehydrateAgentSessions();
|
|
9
9
|
const parentSessionId = String(spec.parentSessionId || '').trim();
|
|
10
10
|
if (!parentSessionId) throw new TypeError('agent child parentSessionId is required');
|
|
11
|
+
const parentEpoch = registry.assertAdmission(parentSessionId);
|
|
11
12
|
const ownerSessionId = String(
|
|
12
13
|
spec.ownerSessionId || registry.get(parentSessionId)?.ownerSessionId || parentSessionId
|
|
13
14
|
);
|
|
@@ -29,6 +30,7 @@ export function createAgentChildFactory({ registry, rehydrateAgentSessions, crea
|
|
|
29
30
|
sourceType: spec.sourceType || 'agent',
|
|
30
31
|
sourceName: spec.sourceName || spec.agent || 'agent',
|
|
31
32
|
clientHostPid: spec.clientHostPid || null,
|
|
33
|
+
...(preset.fallbacks !== undefined ? { routeFallbacks: preset.fallbacks } : {}),
|
|
32
34
|
};
|
|
33
35
|
const created = await createSession({
|
|
34
36
|
cwd: spec.cwd || process.cwd(),
|
|
@@ -45,6 +47,22 @@ export function createAgentChildFactory({ registry, rehydrateAgentSessions, crea
|
|
|
45
47
|
toolMode: 'full',
|
|
46
48
|
sessionProfile,
|
|
47
49
|
});
|
|
50
|
+
try {
|
|
51
|
+
registry.assertAdmission(parentSessionId, parentEpoch);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
// The parent was cancelled while the runtime was being created: close it
|
|
54
|
+
// like any cancelled child instead of leaving it unlinked and open.
|
|
55
|
+
try {
|
|
56
|
+
const entry = await entryForSession?.(created.sessionId, {
|
|
57
|
+
cwd: spec.cwd || process.cwd(),
|
|
58
|
+
provider,
|
|
59
|
+
model,
|
|
60
|
+
toolMode: 'full',
|
|
61
|
+
});
|
|
62
|
+
await entry?.runtime?.closeCanonicalSession?.('parent cancelled during agent creation', { tombstone: false });
|
|
63
|
+
} catch {}
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
48
66
|
const descriptor = registry.linkAgentDescriptor({
|
|
49
67
|
id: created.sessionId,
|
|
50
68
|
...sessionProfile,
|
|
@@ -6,6 +6,8 @@ export const SESSION_ID_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
|
6
6
|
export function createAgentRegistry() {
|
|
7
7
|
const agentSessions = new Map();
|
|
8
8
|
const agentChildren = new Map();
|
|
9
|
+
const cancellationCounts = new Map();
|
|
10
|
+
const cancellationEpochs = new Map();
|
|
9
11
|
|
|
10
12
|
function linkAgentDescriptor(descriptor) {
|
|
11
13
|
const sessionId = String(descriptor?.id || '').trim();
|
|
@@ -54,6 +56,27 @@ export function createAgentRegistry() {
|
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
return {
|
|
59
|
+
assertAdmission(id, epoch = cancellationEpochs.get(id) || 0) {
|
|
60
|
+
if (cancellationCounts.has(id) || (cancellationEpochs.get(id) || 0) !== epoch) {
|
|
61
|
+
throw new Error(`agent session ${id} was cancelled during admission`);
|
|
62
|
+
}
|
|
63
|
+
return epoch;
|
|
64
|
+
},
|
|
65
|
+
beginCancellation(ids) {
|
|
66
|
+
for (const id of ids) {
|
|
67
|
+
cancellationCounts.set(id, (cancellationCounts.get(id) || 0) + 1);
|
|
68
|
+
cancellationEpochs.set(id, (cancellationEpochs.get(id) || 0) + 1);
|
|
69
|
+
}
|
|
70
|
+
return () => {
|
|
71
|
+
for (const id of ids) {
|
|
72
|
+
const remaining = (cancellationCounts.get(id) || 0) - 1;
|
|
73
|
+
if (remaining > 0) cancellationCounts.set(id, remaining);
|
|
74
|
+
else cancellationCounts.delete(id);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
isCancelling: (id) => cancellationCounts.has(id),
|
|
79
|
+
cancellationEpoch: (id) => cancellationEpochs.get(id) || 0,
|
|
57
80
|
linkAgentDescriptor,
|
|
58
81
|
agentDescendantSessionIds,
|
|
59
82
|
get: (sessionId) => agentSessions.get(String(sessionId || '').trim()),
|
|
@@ -68,6 +91,8 @@ export function createAgentRegistry() {
|
|
|
68
91
|
clear() {
|
|
69
92
|
agentSessions.clear();
|
|
70
93
|
agentChildren.clear();
|
|
94
|
+
cancellationCounts.clear();
|
|
95
|
+
cancellationEpochs.clear();
|
|
71
96
|
},
|
|
72
97
|
};
|
|
73
98
|
}
|
|
@@ -14,7 +14,12 @@ export function createAgentTurns({
|
|
|
14
14
|
takeWatchdogStop,
|
|
15
15
|
takeCancelTranscript,
|
|
16
16
|
}) {
|
|
17
|
-
const createAgentChild = createAgentChildFactory({
|
|
17
|
+
const createAgentChild = createAgentChildFactory({
|
|
18
|
+
registry,
|
|
19
|
+
rehydrateAgentSessions,
|
|
20
|
+
createSession,
|
|
21
|
+
entryForSession,
|
|
22
|
+
});
|
|
18
23
|
|
|
19
24
|
// The turn was stopped (progress watchdog or cancellation): rethrow its error
|
|
20
25
|
// carrying the assistant text the turn produced, so the owner still gets a
|
|
@@ -35,6 +40,7 @@ export function createAgentTurns({
|
|
|
35
40
|
async function runAgentTurn({ session, prompt, context = null, onToolResult, onTerminalResult } = {}) {
|
|
36
41
|
await rehydrateAgentSessions();
|
|
37
42
|
const sessionId = String(session?.id || session || '').trim();
|
|
43
|
+
const cancelEpoch = registry.assertAdmission(sessionId);
|
|
38
44
|
const descriptor = registry.get(sessionId);
|
|
39
45
|
if (!descriptor || descriptor.closed) {
|
|
40
46
|
throw new Error(`agent session ${sessionId || '(empty)'} is closed`);
|
|
@@ -46,6 +52,7 @@ export function createAgentTurns({
|
|
|
46
52
|
toolMode: 'full',
|
|
47
53
|
});
|
|
48
54
|
const target = entry.runtime.submitAndWait;
|
|
55
|
+
registry.assertAdmission(sessionId, cancelEpoch);
|
|
49
56
|
if (typeof target !== 'function') {
|
|
50
57
|
throw new TypeError('session runtime must implement submitAndWait');
|
|
51
58
|
}
|
|
@@ -55,6 +62,7 @@ export function createAgentTurns({
|
|
|
55
62
|
// Transcript length before this turn: where a watchdog stop's partial
|
|
56
63
|
// output starts.
|
|
57
64
|
const { messageCount: messageStart } = await entry.runtime.readModelMessages(Number.MAX_SAFE_INTEGER);
|
|
65
|
+
registry.assertAdmission(sessionId, cancelEpoch);
|
|
58
66
|
descriptor.status = 'running';
|
|
59
67
|
descriptor.stage = 'running';
|
|
60
68
|
descriptor.updatedAt = Date.now();
|
|
@@ -109,9 +109,34 @@ export function createAgentTree({
|
|
|
109
109
|
canRun: (session) => Boolean(registry.get(session?.id)),
|
|
110
110
|
createChild: createAgentChild,
|
|
111
111
|
runTurn: runAgentTurn,
|
|
112
|
+
/** A model or tuning change for a reused child goes through the session's
|
|
113
|
+
* own route API: saved at once, applied from the next turn (never refused
|
|
114
|
+
* because a turn is running). `route` may be partial; the route write
|
|
115
|
+
* completes it against the latest selected route. The descriptor follows
|
|
116
|
+
* the selected route. */
|
|
117
|
+
async setRoute({ session, route }) {
|
|
118
|
+
const descriptor = registry.get(session?.id);
|
|
119
|
+
if (!descriptor || descriptor.closed) throw new Error('agent session is closed');
|
|
120
|
+
const entry = await entryForSession(descriptor.id, {
|
|
121
|
+
cwd: descriptor.cwd,
|
|
122
|
+
provider: descriptor.provider,
|
|
123
|
+
model: descriptor.model,
|
|
124
|
+
toolMode: 'full',
|
|
125
|
+
});
|
|
126
|
+
try {
|
|
127
|
+
const applied = await entry.runtime.setRoute({ ...route, sessionOnly: true });
|
|
128
|
+
descriptor.provider = applied?.provider || route.provider || descriptor.provider;
|
|
129
|
+
descriptor.model = applied?.model || route.model || descriptor.model;
|
|
130
|
+
descriptor.updatedAt = Date.now();
|
|
131
|
+
return applied;
|
|
132
|
+
} finally {
|
|
133
|
+
retainUnwatched(entry, 'agent route change');
|
|
134
|
+
}
|
|
135
|
+
},
|
|
112
136
|
async enqueueTurn({ session, prompt, context = null }) {
|
|
113
137
|
const descriptor = registry.get(session?.id);
|
|
114
138
|
if (!descriptor || descriptor.closed) throw new Error('agent session is closed');
|
|
139
|
+
const cancelEpoch = registry.assertAdmission(descriptor.id);
|
|
115
140
|
const runtime = sessionOwner(descriptor.id)?.runtime;
|
|
116
141
|
if (!runtime || !stateBusy(runtime.getState())) return null;
|
|
117
142
|
const accepted = await runtime.submitAsync(String(prompt || ''), {
|
|
@@ -122,6 +147,7 @@ export function createAgentTree({
|
|
|
122
147
|
transcriptMeta: { sender: 'lead' },
|
|
123
148
|
});
|
|
124
149
|
if (accepted === false) throw new Error('agent follow-up was not accepted');
|
|
150
|
+
registry.assertAdmission(descriptor.id, cancelEpoch);
|
|
125
151
|
return { queueDepth: runtime.getState()?.queued?.length ?? null };
|
|
126
152
|
},
|
|
127
153
|
});
|
|
@@ -167,9 +193,9 @@ export function createAgentTree({
|
|
|
167
193
|
if (handoff) descriptor.lastHandoff = handoff;
|
|
168
194
|
return handoff;
|
|
169
195
|
},
|
|
170
|
-
async closeSession(sessionId, reason = 'agent session closed') {
|
|
196
|
+
async closeSession(sessionId, reason = 'agent session closed', options = {}) {
|
|
171
197
|
await rehydrateAgentSessions();
|
|
172
|
-
return cancelAgentTree(sessionId, reason);
|
|
198
|
+
return cancelAgentTree(sessionId, reason, options);
|
|
173
199
|
},
|
|
174
200
|
unloadSessionRuntime: (sessionId) => {
|
|
175
201
|
progress.delete(sessionId);
|