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
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* src/tui/session/active-tool-summary.mjs - surfaced-tool activity summary.
|
|
3
3
|
*
|
|
4
4
|
* Status surfaces must react at tool start, before a shell is backgrounded or
|
|
5
|
-
* an agent worker
|
|
5
|
+
* an agent worker row exists. Track the three surfaced categories
|
|
6
6
|
* directly; background shell records and worker rows later dedupe by max.
|
|
7
7
|
*/
|
|
8
8
|
// Tool category -> the activeTools key it publishes under. Iteration order is
|
|
@@ -47,9 +47,6 @@ export function createContextState({
|
|
|
47
47
|
// (fresh id, copied transcript), hosts validating "resume returned the
|
|
48
48
|
// requested session" must accept the fork by its origin id.
|
|
49
49
|
sessionForkedFrom: runtime.session?.forkedFrom || null,
|
|
50
|
-
// Remote-attach marker: this surface is a live viewer on a session owned
|
|
51
|
-
// by another process; submits are injected, transcript follows disk.
|
|
52
|
-
sessionRemoteAttached: runtime.session?.remoteAttached === true,
|
|
53
50
|
clientHostPid: runtime.clientHostPid || null,
|
|
54
51
|
model: runtime.model,
|
|
55
52
|
provider: runtime.provider,
|
|
@@ -8,7 +8,7 @@ import { isGoalQueuedEntry } from '../queue-helpers.mjs';
|
|
|
8
8
|
export function createContinuationQueue({ runtime, flags, getState, getPending, enqueue, visibility }) {
|
|
9
9
|
let scheduled = null;
|
|
10
10
|
let disposed = false;
|
|
11
|
-
const halted = () => disposed || flags.disposed || flags.pendingSessionReset;
|
|
11
|
+
const halted = () => disposed || flags.disposed || flags.pendingSessionReset || flags.quotaResumePending;
|
|
12
12
|
|
|
13
13
|
const cancelQueuedGoalContinuations = ({ keepCloseoutFor = null } = {}) => {
|
|
14
14
|
const pending = getPending();
|
|
@@ -38,7 +38,6 @@ export function createContinuationQueue({ runtime, flags, getState, getPending,
|
|
|
38
38
|
|
|
39
39
|
const shouldRunGoalContinuation = (entry) => {
|
|
40
40
|
if (halted()) return false;
|
|
41
|
-
if (getState().sessionRemoteAttached) return false;
|
|
42
41
|
if (entry?.mode === 'goal-closeout') {
|
|
43
42
|
const goal = visibility.refreshGoalState();
|
|
44
43
|
return goal?.status === 'duration_reached' && clean(entry.goalId) === clean(goal.id);
|
|
@@ -55,7 +54,7 @@ export function createContinuationQueue({ runtime, flags, getState, getPending,
|
|
|
55
54
|
scheduled = null;
|
|
56
55
|
if (halted()) return;
|
|
57
56
|
const state = getState();
|
|
58
|
-
if (state.busy || state.commandBusy
|
|
57
|
+
if (state.busy || state.commandBusy) return;
|
|
59
58
|
// Queued user work runs first, and a queued Goal entry already carries
|
|
60
59
|
// the next continuation.
|
|
61
60
|
if (getPending().length > 0) return;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// Deadline notices for the running Goal: the advance warning and the closeout
|
|
2
2
|
// once the duration is reached.
|
|
3
3
|
import { clean } from '../../../runtime/shared/clean.mjs';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
goalDeadlineReached,
|
|
6
|
+
goalDeadlineWarning,
|
|
7
|
+
} from '../../../runtime/agent/orchestrator/runtime-core/goal-text.mjs';
|
|
5
8
|
import { isGoalQueuedEntry } from '../queue-helpers.mjs';
|
|
6
9
|
|
|
7
10
|
export function createDeadlineDelivery({ runtime, getState, getPending, enqueue, halted }) {
|
|
@@ -54,7 +57,6 @@ export function createDeadlineDelivery({ runtime, getState, getPending, enqueue,
|
|
|
54
57
|
const deliverGoalCloseout = (goal) => {
|
|
55
58
|
if (halted()) return;
|
|
56
59
|
const state = getState();
|
|
57
|
-
if (state.sessionRemoteAttached) return;
|
|
58
60
|
if (!state.busy && getPending().some((entry) => !isGoalQueuedEntry(entry))) {
|
|
59
61
|
runtime.markGoalReminder?.('deadline-reached');
|
|
60
62
|
return;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/tui/session/goal-continuation/session-boundary.mjs - a session boundary
|
|
3
|
+
* (resume, new session, context switch) changes which Goal is current, so the
|
|
4
|
+
* continuation queued for the previous session is dropped and the current
|
|
5
|
+
* session's Goal is re-read and re-armed once the boundary settles.
|
|
6
|
+
*/
|
|
7
|
+
const SESSION_BOUNDARY_METHODS = ['resume', 'newSession', 'switchContext'];
|
|
8
|
+
|
|
9
|
+
export function rearmGoalContinuationOnSessionBoundaries({ api, bag }) {
|
|
10
|
+
for (const method of SESSION_BOUNDARY_METHODS) {
|
|
11
|
+
if (typeof api[method] !== 'function') continue;
|
|
12
|
+
const base = api[method].bind(api);
|
|
13
|
+
api[method] = async (...args) => {
|
|
14
|
+
const result = await base(...args);
|
|
15
|
+
bag.cancelQueuedGoalContinuations?.();
|
|
16
|
+
bag.refreshGoalState?.();
|
|
17
|
+
bag.scheduleGoalContinuation?.();
|
|
18
|
+
return result;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -11,42 +11,23 @@
|
|
|
11
11
|
import {
|
|
12
12
|
cancelQuotaResumeEntry,
|
|
13
13
|
forgetQuotaSuspendedGoal,
|
|
14
|
-
isAgentOnlySession,
|
|
15
14
|
noteQuotaSuspendedGoal,
|
|
16
15
|
publicQuotaResume,
|
|
17
16
|
quotaAutoResumeEnabled,
|
|
18
17
|
quotaResumeEntry,
|
|
19
18
|
quotaSuspendedGoal,
|
|
19
|
+
rekeyQuotaResumeTurn,
|
|
20
20
|
scheduleQuotaResumeEntry,
|
|
21
21
|
subscribeQuotaResume,
|
|
22
22
|
} from '../../runtime/shared/quota-resume-store.mjs';
|
|
23
|
-
import { createSubmissionIntake } from './session-api/intake/submission.mjs';
|
|
24
23
|
|
|
25
24
|
export const RETRY_CONTINUE_INSTRUCTION = 'Continue from where you left off.';
|
|
25
|
+
import { transcriptTurnKeys } from '../../runtime/shared/transcript-turn-keys.mjs';
|
|
26
|
+
export { transcriptTurnKeys };
|
|
26
27
|
|
|
27
28
|
// Rows that frame a turn rather than carry its output (desktop transcript-rows).
|
|
28
29
|
const TURN_CHROME_KINDS = new Set(['user', 'turndone', 'statusdone', 'notice']);
|
|
29
30
|
|
|
30
|
-
function stableItemKey(item, index) {
|
|
31
|
-
if (item?.id !== undefined && item?.id !== null) return String(item.id);
|
|
32
|
-
return `${item?.kind || 'item'}:${item?.text || item?.label || item?.status || ''}:${index}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** Turn identity per transcript row — the same keys the desktop derives. */
|
|
36
|
-
export function transcriptTurnKeys(items) {
|
|
37
|
-
const transcript = Array.isArray(items) ? items : [];
|
|
38
|
-
const keys = [];
|
|
39
|
-
let activeTurn = null;
|
|
40
|
-
for (let index = 0; index < transcript.length; index += 1) {
|
|
41
|
-
const item = transcript[index];
|
|
42
|
-
if (item?.kind === 'user') activeTurn = `turn:${stableItemKey(item, index)}`;
|
|
43
|
-
if (!activeTurn) activeTurn = `segment:${stableItemKey(item, index)}`;
|
|
44
|
-
keys.push(activeTurn);
|
|
45
|
-
if (item?.kind === 'turndone') activeTurn = null;
|
|
46
|
-
}
|
|
47
|
-
return keys;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
31
|
/** The failed turndone that ended the transcript on exhausted provider quota,
|
|
51
32
|
* when no later turn has begun: { turnKey, quota: { provider, model, resetAt|null } }. */
|
|
52
33
|
export function latestQuotaFailure(items) {
|
|
@@ -106,7 +87,7 @@ export function failedTurnRetryPrompt(items, turnKey) {
|
|
|
106
87
|
}
|
|
107
88
|
if (!TURN_CHROME_KINDS.has(String(item?.kind || ''))) sampled = true;
|
|
108
89
|
}
|
|
109
|
-
if (!prompt) return null;
|
|
90
|
+
if (!prompt) return sampled ? RETRY_CONTINUE_INSTRUCTION : null;
|
|
110
91
|
// Transcript rows keep only attachment metadata, so a text-only replay
|
|
111
92
|
// would drop the attachments and the rewind would delete the original row.
|
|
112
93
|
if (hasAttachments && !sampled) return null;
|
|
@@ -116,11 +97,6 @@ export function failedTurnRetryPrompt(items, turnKey) {
|
|
|
116
97
|
export function createQuotaResumeLane(bag) {
|
|
117
98
|
const { runtime, flags, getState, set, pending } = bag;
|
|
118
99
|
const currentId = () => String(getState().sessionId || '');
|
|
119
|
-
let intake = null;
|
|
120
|
-
const submitAsync = (...args) => {
|
|
121
|
-
intake ??= createSubmissionIntake(bag);
|
|
122
|
-
return intake.submitAsync(...args);
|
|
123
|
-
};
|
|
124
100
|
|
|
125
101
|
const publishQuotaResume = () => {
|
|
126
102
|
const next = publicQuotaResume(quotaResumeEntry(currentId()));
|
|
@@ -140,8 +116,6 @@ export function createQuotaResumeLane(bag) {
|
|
|
140
116
|
routeProvider: String(runtime.sessionProvider ?? runtime.provider ?? ''),
|
|
141
117
|
routeModel: String(runtime.sessionModel ?? runtime.model ?? ''),
|
|
142
118
|
});
|
|
143
|
-
// A delegated agent child never owns a resume: the Lead decides its retries.
|
|
144
|
-
const agentOnly = () => isAgentOnlySession({ id: currentId(), ...runtime.session });
|
|
145
119
|
const queueResume = (sessionId, failure) =>
|
|
146
120
|
scheduleQuotaResumeEntry({ sessionId, turnKey: failure.turnKey, ...failure.quota, ...sessionRoute() });
|
|
147
121
|
|
|
@@ -151,6 +125,7 @@ export function createQuotaResumeLane(bag) {
|
|
|
151
125
|
// that window also keeps the settlement from recording the Goal.
|
|
152
126
|
let settlement = null;
|
|
153
127
|
let cancelEpoch = 0;
|
|
128
|
+
let retryClaim = '';
|
|
154
129
|
|
|
155
130
|
const cancelFor = (sessionId) => {
|
|
156
131
|
cancelEpoch += 1;
|
|
@@ -169,24 +144,107 @@ export function createQuotaResumeLane(bag) {
|
|
|
169
144
|
state.commandBusy ||
|
|
170
145
|
flags.autoClearRunning ||
|
|
171
146
|
flags.draining ||
|
|
147
|
+
flags.quotaResumePending ||
|
|
172
148
|
pending.length > 0
|
|
173
149
|
);
|
|
174
150
|
};
|
|
175
151
|
|
|
176
|
-
/**
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
152
|
+
/** A resume preserves its history rather than running idle auto-clear. */
|
|
153
|
+
function retainedRetryInput() {
|
|
154
|
+
const messages = runtime.readModelMessages?.().messages;
|
|
155
|
+
const message = Array.isArray(messages) ? messages.findLast((item) => item?.role !== 'system') : null;
|
|
156
|
+
const transcript = message?.meta?.transcript;
|
|
157
|
+
if (message?.role !== 'user' || !transcript?.messageId || transcript?.completion?.status !== 'failed') return null;
|
|
158
|
+
return { content: message.content, messageId: transcript.messageId, attemptId: transcript.completion.attemptId };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function retryFailedTurn(turnKey) {
|
|
162
|
+
const retained = retainedRetryInput();
|
|
163
|
+
if (retained) {
|
|
164
|
+
return bag.enqueue(retained.content, {
|
|
165
|
+
mode: 'prompt',
|
|
166
|
+
id: bag.nextId(),
|
|
167
|
+
retryFailedTurn: true,
|
|
168
|
+
retryTurnId: retained.messageId,
|
|
169
|
+
retryAttemptId: retained.attemptId,
|
|
170
|
+
suppressDisplay: true,
|
|
171
|
+
skipSlashCommands: true,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
180
174
|
const prompt = failedTurnRetryPrompt(getState().items, turnKey);
|
|
181
175
|
if (!prompt) return false;
|
|
182
|
-
|
|
183
|
-
|
|
176
|
+
return bag.enqueue(prompt, { mode: 'prompt', id: bag.nextId(), displayText: prompt, retryFailedTurn: true });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function finishResume(id, entry, goalId = '') {
|
|
180
|
+
if (entry) cancelQuotaResumeEntry(id, { generation: entry.generation });
|
|
181
|
+
if (goalId && quotaSuspendedGoal(id, entry?.turnKey || latestFailedTurnKey(getState().items)) === goalId) {
|
|
182
|
+
forgetQuotaSuspendedGoal(id);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async function resumeGoal(id, key, goalId, entry, claim) {
|
|
187
|
+
const token = { epoch: cancelEpoch, admitted: false };
|
|
188
|
+
const generation = entry?.generation ?? null;
|
|
189
|
+
const current = () =>
|
|
190
|
+
currentId() === id &&
|
|
191
|
+
cancelEpoch === token.epoch &&
|
|
192
|
+
!flags.disposed &&
|
|
193
|
+
(flags.admission || 'open') === 'open' &&
|
|
194
|
+
latestFailedTurnKey(getState().items) === key &&
|
|
195
|
+
(quotaResumeEntry(id)?.generation ?? null) === generation;
|
|
196
|
+
const prompt = failedTurnRetryPrompt(getState().items, key);
|
|
197
|
+
const retained = retainedRetryInput();
|
|
198
|
+
flags.quotaResumePending = token;
|
|
199
|
+
let accepted = false;
|
|
200
|
+
let recoveryFailed = false;
|
|
201
|
+
try {
|
|
202
|
+
if (typeof runtime.reactivateUsageLimitedGoal !== 'function') throw new Error('Goal resume is unavailable.');
|
|
203
|
+
const goal = await runtime.reactivateUsageLimitedGoal(goalId, {
|
|
204
|
+
isCurrent: current,
|
|
205
|
+
accept: () => {
|
|
206
|
+
if (!current()) return false;
|
|
207
|
+
if ((retained || prompt) && retryFailedTurn(key) === false) return false;
|
|
208
|
+
token.admitted = true;
|
|
209
|
+
return true;
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
accepted = goal?.status === 'active' && token.admitted;
|
|
213
|
+
if (accepted) finishResume(id, entry, goalId);
|
|
214
|
+
return accepted;
|
|
215
|
+
} catch (error) {
|
|
216
|
+
recoveryFailed = error?.quotaResumeRollbackFailed === true;
|
|
217
|
+
bag.pushNotice?.(`Goal resume failed: ${error?.message || error}`, 'warn', { transcript: true });
|
|
218
|
+
throw error;
|
|
219
|
+
} finally {
|
|
220
|
+
if (!accepted && retryClaim === claim) retryClaim = '';
|
|
221
|
+
if (!recoveryFailed && flags.quotaResumePending === token) {
|
|
222
|
+
flags.quotaResumePending = null;
|
|
223
|
+
void bag.drain?.();
|
|
224
|
+
if (accepted && !retained && !prompt) bag.scheduleGoalContinuation?.();
|
|
225
|
+
}
|
|
184
226
|
}
|
|
185
|
-
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function hasResumeInput(key) {
|
|
230
|
+
if (retainedRetryInput()) return true;
|
|
231
|
+
if (failedTurnRetryPrompt(getState().items, key)) return true;
|
|
232
|
+
if (key.startsWith('turn:')) return false;
|
|
233
|
+
return Boolean(
|
|
234
|
+
quotaSuspendedGoal(currentId(), key) ||
|
|
235
|
+
(runtime.goalStatus?.()?.id && typeof runtime.reactivateUsageLimitedGoal === 'function')
|
|
236
|
+
);
|
|
186
237
|
}
|
|
187
238
|
|
|
188
239
|
return {
|
|
189
240
|
publishQuotaResume,
|
|
241
|
+
reconcileQuotaResume() {
|
|
242
|
+
const items = getState().items;
|
|
243
|
+
const key = latestFailedTurnKey(items);
|
|
244
|
+
const failure = items?.findLast((item) => item?.kind === 'turndone');
|
|
245
|
+
if (!key || failure?.attemptId || !failure?.checkpointId) return false;
|
|
246
|
+
return rekeyQuotaResumeTurn(currentId(), `turn:${failure.checkpointId}`, key);
|
|
247
|
+
},
|
|
190
248
|
disposeQuotaResume: unsubscribe,
|
|
191
249
|
|
|
192
250
|
/** Turn close, synchronously with the failed turndone: with a known reset
|
|
@@ -198,7 +256,13 @@ export function createQuotaResumeLane(bag) {
|
|
|
198
256
|
settlement = null;
|
|
199
257
|
if (!id || !failure) return null;
|
|
200
258
|
settlement = { sessionId: id, turnKey: failure.turnKey, epoch: cancelEpoch };
|
|
201
|
-
if (failure.quota.resetAt === null || !quotaAutoResumeEnabled()
|
|
259
|
+
if (failure.quota.resetAt === null || !quotaAutoResumeEnabled()) return null;
|
|
260
|
+
if (!hasResumeInput(failure.turnKey)) {
|
|
261
|
+
bag.pushNotice?.('This turn cannot be resumed automatically. Send a new message to continue.', 'warn', {
|
|
262
|
+
transcript: true,
|
|
263
|
+
});
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
202
266
|
return queueResume(id, failure);
|
|
203
267
|
},
|
|
204
268
|
|
|
@@ -220,22 +284,24 @@ export function createQuotaResumeLane(bag) {
|
|
|
220
284
|
/** Explicit request to auto-resume the latest quota-failed turn. */
|
|
221
285
|
scheduleQuotaResume(sessionId) {
|
|
222
286
|
requireAddressed(sessionId);
|
|
223
|
-
if (agentOnly()) throw new Error('agent sessions do not auto-resume; the Lead decides retries');
|
|
224
287
|
const failure = latestQuotaFailure(getState().items);
|
|
225
288
|
if (!failure || failure.quota.resetAt === null) {
|
|
226
289
|
throw new Error('latest turn did not fail on exhausted provider quota with a known reset time');
|
|
227
290
|
}
|
|
291
|
+
if (!hasResumeInput(failure.turnKey))
|
|
292
|
+
throw new Error('This turn cannot be resumed automatically. Send a new message to continue.');
|
|
228
293
|
queueResume(sessionId, failure);
|
|
229
294
|
return true;
|
|
230
295
|
},
|
|
231
296
|
|
|
232
297
|
cancelQuotaResume(sessionId) {
|
|
233
298
|
requireAddressed(sessionId);
|
|
299
|
+
cancelEpoch += 1;
|
|
234
300
|
cancelQuotaResumeEntry(sessionId);
|
|
235
301
|
return true;
|
|
236
302
|
},
|
|
237
303
|
|
|
238
|
-
/** A
|
|
304
|
+
/** A session clear/delete supersedes the wait. */
|
|
239
305
|
supersedeQuotaResume(sessionId) {
|
|
240
306
|
if (sessionId) cancelFor(String(sessionId));
|
|
241
307
|
},
|
|
@@ -248,7 +314,23 @@ export function createQuotaResumeLane(bag) {
|
|
|
248
314
|
requireAddressed(sessionId);
|
|
249
315
|
const key = String(turnKey || '');
|
|
250
316
|
if (!key || retryBlocked() || latestFailedTurnKey(getState().items) !== key) return false;
|
|
251
|
-
|
|
317
|
+
const claim = `${sessionId}\u0000${key}`;
|
|
318
|
+
if (retryClaim === claim) return false;
|
|
319
|
+
const goalId = quotaSuspendedGoal(sessionId, key);
|
|
320
|
+
if (!retainedRetryInput() && !failedTurnRetryPrompt(getState().items, key) && !goalId) {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
retryClaim = claim;
|
|
324
|
+
const entry = quotaResumeEntry(sessionId);
|
|
325
|
+
if (goalId) return resumeGoal(sessionId, key, goalId, entry, claim);
|
|
326
|
+
let accepted = false;
|
|
327
|
+
try {
|
|
328
|
+
accepted = retryFailedTurn(key) !== false;
|
|
329
|
+
if (accepted) finishResume(sessionId, entry);
|
|
330
|
+
return accepted;
|
|
331
|
+
} finally {
|
|
332
|
+
if (!accepted && retryClaim === claim) retryClaim = '';
|
|
333
|
+
}
|
|
252
334
|
},
|
|
253
335
|
|
|
254
336
|
/** Scheduler fire for the entry of `generation`, after a usable reading.
|
|
@@ -258,10 +340,6 @@ export function createQuotaResumeLane(bag) {
|
|
|
258
340
|
const id = currentId();
|
|
259
341
|
const entry = quotaResumeEntry(id);
|
|
260
342
|
if (!id || !entry || entry.generation !== generation) return 'stale';
|
|
261
|
-
if (agentOnly()) {
|
|
262
|
-
cancelQuotaResumeEntry(id, { generation });
|
|
263
|
-
return 'agent-session';
|
|
264
|
-
}
|
|
265
343
|
const state = getState();
|
|
266
344
|
if (retryBlocked()) return 'busy';
|
|
267
345
|
const failure = latestQuotaFailure(state.items);
|
|
@@ -269,28 +347,29 @@ export function createQuotaResumeLane(bag) {
|
|
|
269
347
|
cancelQuotaResumeEntry(id, { generation });
|
|
270
348
|
return 'superseded';
|
|
271
349
|
}
|
|
272
|
-
const route = sessionRoute();
|
|
273
|
-
if (route.routeProvider !== entry.routeProvider || route.routeModel !== entry.routeModel) {
|
|
274
|
-
cancelQuotaResumeEntry(id, { generation });
|
|
275
|
-
return 'route-changed';
|
|
276
|
-
}
|
|
277
350
|
const goalId = quotaSuspendedGoal(id, entry.turnKey);
|
|
278
351
|
// A user turn replays its prompt; an automatic Goal turn has no user row
|
|
279
352
|
// and resumes as its Goal's next continuation.
|
|
280
|
-
|
|
281
|
-
|
|
353
|
+
if (!retainedRetryInput() && !failedTurnRetryPrompt(state.items, entry.turnKey) && !goalId) {
|
|
354
|
+
bag.pushNotice?.('This turn cannot be resumed automatically. Send a new message to continue.', 'warn', {
|
|
355
|
+
transcript: true,
|
|
356
|
+
});
|
|
282
357
|
cancelQuotaResumeEntry(id, { generation });
|
|
283
358
|
return 'unreplayable';
|
|
284
359
|
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
if (
|
|
293
|
-
|
|
360
|
+
const claim = `${id}\u0000${entry.turnKey}`;
|
|
361
|
+
if (retryClaim === claim) return 'stale';
|
|
362
|
+
retryClaim = claim;
|
|
363
|
+
if (goalId)
|
|
364
|
+
return resumeGoal(id, entry.turnKey, goalId, entry, claim).then((accepted) =>
|
|
365
|
+
accepted ? 'fired' : 'rejected'
|
|
366
|
+
);
|
|
367
|
+
if (retryFailedTurn(entry.turnKey) === false) {
|
|
368
|
+
retryClaim = '';
|
|
369
|
+
return 'rejected';
|
|
370
|
+
}
|
|
371
|
+
finishResume(id, entry);
|
|
372
|
+
return 'fired';
|
|
294
373
|
},
|
|
295
374
|
};
|
|
296
375
|
}
|
|
@@ -93,16 +93,14 @@ export function createSessionCommandsApi(bag) {
|
|
|
93
93
|
};
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
// The compaction pass
|
|
97
|
-
|
|
98
|
-
// would not reduce anything and then adds no row for it.
|
|
99
|
-
async function runCompaction(startedAt, { quiet = false } = {}) {
|
|
96
|
+
// The explicit compaction pass, under a lock its caller holds.
|
|
97
|
+
async function runCompaction(startedAt) {
|
|
100
98
|
// Give Ink one event-loop turn to paint the compacting spinner before
|
|
101
99
|
// runtime.compact() starts synchronous session/transcript work (same
|
|
102
100
|
// yield as the auto-clear path; without it /compact looks frozen with
|
|
103
101
|
// no spinner until the compact already finished).
|
|
104
102
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
105
|
-
const result = await runtime.compact({ recoverAgent: true
|
|
103
|
+
const result = await runtime.compact({ recoverAgent: true });
|
|
106
104
|
const compactChanged = Boolean(result && !result.error && result.changed !== false);
|
|
107
105
|
syncContextStats({
|
|
108
106
|
allowEstimated: true,
|
|
@@ -115,16 +113,12 @@ export function createSessionCommandsApi(bag) {
|
|
|
115
113
|
archived: compactionArchivedRows(result),
|
|
116
114
|
});
|
|
117
115
|
set({ items: replaceItems(items, { preserveSpill: true }) });
|
|
118
|
-
} else
|
|
116
|
+
} else {
|
|
119
117
|
pushItem(compactDoneItem(result, startedAt));
|
|
120
118
|
}
|
|
121
119
|
return result;
|
|
122
120
|
}
|
|
123
121
|
|
|
124
|
-
// An in-place model switch compacts first on the current model (routes.mjs
|
|
125
|
-
// holds the command lock and shows the compacting status meanwhile).
|
|
126
|
-
bag.compactBeforeModelSwitch = () => runCompaction(Date.now(), { quiet: true });
|
|
127
|
-
|
|
128
122
|
async function compactCommand() {
|
|
129
123
|
if (getState().commandBusy) return null;
|
|
130
124
|
if (getState().busy) return scheduleCompactForTurnEnd(compactCommand);
|
|
@@ -67,6 +67,18 @@ export function createSessionControlsApi(bag) {
|
|
|
67
67
|
stopShellJob: async (taskId) => {
|
|
68
68
|
return (await runtime.stopShellJob?.(taskId)) ?? { stopped: false, error: 'shell job control is unavailable' };
|
|
69
69
|
},
|
|
70
|
+
// Explicit force-release of a shell whose termination is unconfirmed:
|
|
71
|
+
// { released, error? }. Surfaces confirm with the user before calling.
|
|
72
|
+
releaseShellJob: async (taskId) => {
|
|
73
|
+
return (
|
|
74
|
+
(await runtime.releaseShellJob?.(taskId)) ?? { released: false, error: 'shell job control is unavailable' }
|
|
75
|
+
);
|
|
76
|
+
},
|
|
77
|
+
// This session's live shell jobs, each flagged when its termination is
|
|
78
|
+
// unconfirmed: { jobs }.
|
|
79
|
+
listShellJobs: async () => {
|
|
80
|
+
return (await runtime.listShellJobs?.()) ?? { jobs: [] };
|
|
81
|
+
},
|
|
70
82
|
goalControl: async (args = {}) => {
|
|
71
83
|
const result = await runtime.goalControl?.(args);
|
|
72
84
|
if (['pause', 'stop'].includes(result?.action)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Dispose: release
|
|
1
|
+
// Dispose: release timers, subscriptions, approvals and OAuth flows,
|
|
2
2
|
// persist steering, then close the runtime — once.
|
|
3
3
|
import { flushTuiSteeringPersist } from '../../tui-steering-persist.mjs';
|
|
4
4
|
|
|
@@ -20,14 +20,6 @@ export function createDisposeAction(bag, { oauthFlows }) {
|
|
|
20
20
|
if (flags.disposed) return;
|
|
21
21
|
disposeEmit?.();
|
|
22
22
|
flags.disposed = true;
|
|
23
|
-
// Release the interactive-presence beacon so a cross-open after this
|
|
24
|
-
// surface exits takes normal ownership instead of viewer-attaching to a
|
|
25
|
-
// dead owner (crash paths fall back to the 2min staleness window).
|
|
26
|
-
try {
|
|
27
|
-
runtime.clearSessionPresence?.();
|
|
28
|
-
} catch {
|
|
29
|
-
/* best-effort */
|
|
30
|
-
}
|
|
31
23
|
clearToastTimers();
|
|
32
24
|
disposeTranscriptSpill?.();
|
|
33
25
|
disposeGoalContinuation?.();
|
|
@@ -41,6 +33,7 @@ export function createDisposeAction(bag, { oauthFlows }) {
|
|
|
41
33
|
'unsubscribeRemoteState',
|
|
42
34
|
'unsubscribeCompletionWakeGate',
|
|
43
35
|
'unsubscribeGitHeadWatch',
|
|
36
|
+
'unsubscribeWorktreeSetup',
|
|
44
37
|
]) {
|
|
45
38
|
try {
|
|
46
39
|
lifecycle[key]?.();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Resume: reopen a stored session, rebuild the visible transcript from its
|
|
2
|
-
// messages and reconcile
|
|
2
|
+
// messages and reconcile steering at the same boundary.
|
|
3
3
|
import { primeContextEstimates } from '../../../../runtime/agent/orchestrator/session/context-utils.mjs';
|
|
4
4
|
import { resumedTranscriptArchive } from '../../compaction-view.mjs';
|
|
5
5
|
|
|
@@ -63,12 +63,7 @@ export function createResumeAction(bag, { restoreTranscriptItems }) {
|
|
|
63
63
|
...routeState(),
|
|
64
64
|
stats: { ...getState().stats },
|
|
65
65
|
});
|
|
66
|
-
|
|
67
|
-
// start). The 3s share tick otherwise leaves a live-owned session on
|
|
68
|
-
// the stale disk snapshot and then full-swaps it seconds after entry —
|
|
69
|
-
// the visible transcript lurch. Connecting here makes the owner's
|
|
70
|
-
// full frame land at the resume boundary, so entry paints settled.
|
|
71
|
-
bag.ensureLiveShare?.();
|
|
66
|
+
bag.reconcileQuotaResume?.();
|
|
72
67
|
// A shard/process restart recreates the runtime before resuming its
|
|
73
68
|
// durable session. Restore accepted steering while commandBusy is
|
|
74
69
|
// still held so the central release hook drains it exactly once after
|
|
@@ -20,14 +20,14 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
|
|
|
20
20
|
// work for a conversation that is being closed. A durable close that fails
|
|
21
21
|
// restores admission with every accepted input intact; one that succeeds
|
|
22
22
|
// leaves the session terminal and settles queued submissions explicitly.
|
|
23
|
-
function closeCanonical(reason) {
|
|
23
|
+
function closeCanonical(reason, options) {
|
|
24
24
|
const flags = bag.flags || {};
|
|
25
25
|
const previous = flags.admission || 'open';
|
|
26
|
-
if (previous === 'terminal') return runtime.closeCanonicalSession?.(reason) === true;
|
|
26
|
+
if (previous === 'terminal') return runtime.closeCanonicalSession?.(reason, options) === true;
|
|
27
27
|
flags.admission = 'closing';
|
|
28
28
|
let closed = false;
|
|
29
29
|
try {
|
|
30
|
-
closed = runtime.closeCanonicalSession?.(reason) === true;
|
|
30
|
+
closed = runtime.closeCanonicalSession?.(reason, options) === true;
|
|
31
31
|
} catch (error) {
|
|
32
32
|
flags.admission = previous;
|
|
33
33
|
restoreAdmission();
|
|
@@ -50,6 +50,7 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
return {
|
|
53
|
+
isSessionTerminal: () => bag.flags?.admission === 'terminal' || runtime.isSessionTerminal?.() === true,
|
|
53
54
|
resolveToolApproval: (id, decision = {}) => {
|
|
54
55
|
const approved = decision === true || decision?.approved === true;
|
|
55
56
|
return finishToolApproval(
|
|
@@ -57,7 +58,8 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
|
|
|
57
58
|
approved,
|
|
58
59
|
decision?.reason || (approved ? 'approved by user' : 'denied by user'),
|
|
59
60
|
typeof decision?.device === 'string' ? decision.device : '',
|
|
60
|
-
decision?.answers
|
|
61
|
+
decision?.answers,
|
|
62
|
+
typeof decision?.reply === 'string' ? decision.reply : undefined
|
|
61
63
|
);
|
|
62
64
|
},
|
|
63
65
|
pushNotice,
|
|
@@ -83,8 +85,6 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
|
|
|
83
85
|
throw new Error('latest turn did not fail on exhausted provider quota');
|
|
84
86
|
}
|
|
85
87
|
if (typeof runtime.continueSessionInModel !== 'function') throw new Error('runtime cannot continue in a model');
|
|
86
|
-
// Continuing elsewhere supersedes waiting for this provider's reset.
|
|
87
|
-
bag.supersedeQuotaResume?.(sessionId);
|
|
88
88
|
bag.set({ commandBusy: true });
|
|
89
89
|
try {
|
|
90
90
|
const result = await runtime.continueSessionInModel(sessionId, route);
|
|
@@ -99,10 +99,12 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
|
|
|
99
99
|
bag.flushEmitImmediate?.();
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
|
-
// Desktop sidebar watcher hook: the
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
102
|
+
// Desktop sidebar watcher hook: the desktop host watches this directory,
|
|
103
|
+
// and a session record write (a turn starting or settling) schedules a
|
|
104
|
+
// debounced catalog refresh that re-reads `working` from the daemon's
|
|
105
|
+
// in-memory run state. Without it the watcher silently no-ops and the
|
|
106
|
+
// sidebar only refreshes on other store notifications (user: spinner kept
|
|
107
|
+
// spinning after the turn ended).
|
|
106
108
|
sessionStoreDir: () => {
|
|
107
109
|
try {
|
|
108
110
|
return runtime.sessionStoreDir?.() || null;
|
|
@@ -116,7 +118,7 @@ export function createSessionLifecycleApi(bag, { restoreTranscriptItems, oauthFl
|
|
|
116
118
|
deliverToolCompletion: (sessionId, text, meta = {}) =>
|
|
117
119
|
runtime.deliverToolCompletion?.(sessionId, text, meta) === true,
|
|
118
120
|
|
|
119
|
-
closeCanonicalSession: (reason = 'canonical-session-close') => closeCanonical(reason),
|
|
121
|
+
closeCanonicalSession: (reason = 'canonical-session-close', options) => closeCanonical(reason, options),
|
|
120
122
|
|
|
121
123
|
bindSessionAddress: (sessionId) => runtime.bindSessionAddress?.(sessionId) === true,
|
|
122
124
|
|
|
@@ -122,6 +122,8 @@ export function createSessionMediaApi(bag) {
|
|
|
122
122
|
listMediaLanes: () => runtime.listMediaLanes?.(),
|
|
123
123
|
getMediaDefault: (kind) => runtime.getMediaDefault?.(kind),
|
|
124
124
|
setMediaDefault: (input) => runtime.setMediaDefault?.(input),
|
|
125
|
+
getMediaPins: () => runtime.getMediaPins?.(),
|
|
126
|
+
setMediaPin: (input) => runtime.setMediaPin?.(input),
|
|
125
127
|
listMediaAssets: (options) => runtime.listMediaAssets?.(options),
|
|
126
128
|
readMediaAsset: (id, options) => runtime.readMediaAsset?.(id, options),
|
|
127
129
|
cacheMediaThumbnail: (id, input) => runtime.cacheMediaThumbnail?.(id, input),
|