mixdog 1.4.1 → 1.4.3
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 +4 -3
- package/scripts/build-shipped-history.mjs +125 -33
- package/scripts/gate-local.mjs +220 -63
- package/scripts/graph-parity.mjs +8 -3
- package/scripts/lib/gate-scheduler.mjs +139 -32
- package/scripts/lib/gate-timing-reporter.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +71 -34
- package/scripts/lib/scoped-temp.mjs +1 -0
- package/scripts/lib/test-failure-records.mjs +14 -1
- package/scripts/lib/test-failure-summary.mjs +9 -4
- package/scripts/lib/test-spawn-ledger.mjs +43 -3
- package/scripts/post-release-check.mjs +26 -16
- package/scripts/pptx-kit-index.mjs +5 -6
- package/scripts/provider-pingpong-live.mjs +1 -1
- package/scripts/prune-embedding-runtime.mjs +3 -1
- package/scripts/release-paths.mjs +7 -1
- package/scripts/suite-health.mjs +110 -28
- package/scripts/test.mjs +9 -14
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/explore/AGENT.md +22 -0
- package/src/agents/explore/agent.json +6 -0
- package/src/cli.mjs +7 -0
- package/src/defaults/agents.json +7 -0
- package/src/defaults/shipped-history.json +38 -2
- package/src/defaults/skills/browser-use/SKILL.md +4 -1
- package/src/defaults/skills/code-tidy/SKILL.md +71 -102
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
- package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
- package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
- package/src/defaults/skills/computer-use/SKILL.md +12 -2
- package/src/defaults/skills/setup/SKILL.md +2 -2
- package/src/defaults/skills/setup/references/actions.md +28 -9
- package/src/defaults/skills/setup/references/surfaces.md +5 -2
- package/src/defaults/skills/setup-guide/SKILL.md +11 -3
- package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
- package/src/defaults/skills/skill-creator/SKILL.md +85 -190
- package/src/defaults/skills/skill-creator/references/design.md +70 -162
- package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
- package/src/defaults/skills/test-suite/SKILL.md +194 -0
- package/src/defaults/skills/test-suite/references/case-management.md +51 -0
- package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
- package/src/defaults/skills/test-suite/references/reliability.md +49 -0
- package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
- package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
- package/src/defaults/skills/visualize/SKILL.md +6 -2
- package/src/lib/instruction-text.cjs +36 -0
- package/src/lib/rules-builder.cjs +40 -50
- package/src/orchestration/balanced.md +23 -0
- package/src/orchestration/focused.md +22 -0
- package/src/orchestration/none.md +5 -0
- package/src/orchestration/swarm.md +24 -0
- package/src/rules/agent-mode/AGENT_MODE.md +3 -1
- package/src/rules/agent-mode/MIXY.md +2 -2
- package/src/rules/lead/LEAD.md +3 -3
- package/src/rules/shared/20-research.md +3 -6
- package/src/rules/shared/40-editing.md +1 -0
- package/src/rules/shared/60-verification.md +10 -9
- package/src/rules/shared/70-delivery.md +4 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
- package/src/runtime/agent/orchestrator/config.mjs +12 -7
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
- package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
- package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
- package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
- package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
- package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
- package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
- package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
- package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
- package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
- package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
- package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
- package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
- package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
- package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/attachment-reference.mjs +1 -1
- package/src/runtime/attachments/pdf-extract.mjs +1 -1
- package/src/runtime/attachments/store.d.mts +1 -0
- package/src/runtime/attachments/store.mjs +2 -2
- package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
- package/src/runtime/channels/lib/scheduler.mjs +33 -0
- package/src/runtime/channels/lib/schedules-db.mjs +11 -4
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
- package/src/runtime/channels/lib/whisper-port.mjs +19 -10
- package/src/runtime/channels/lib/whisper-server.mjs +22 -13
- package/src/runtime/channels/lib/worker-main.mjs +9 -31
- package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
- package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
- package/src/runtime/connectors/gmail-app-password.mjs +4 -4
- package/src/runtime/connectors/google-mcp.mjs +1 -1
- package/src/runtime/effort-judge/judge-client.mjs +2 -2
- package/src/runtime/effort-judge/judge-input.mjs +4 -4
- package/src/runtime/explore/explorer.mjs +88 -0
- package/src/runtime/explore/tool-defs.mjs +35 -0
- package/src/runtime/explore/tool.mjs +123 -0
- package/src/runtime/local-provider/hardware.mjs +1 -1
- package/src/runtime/media/adapters/codex-image.mjs +3 -3
- package/src/runtime/media/adapters/gemini-video.mjs +1 -1
- package/src/runtime/media/media-usage.mjs +1 -1
- package/src/runtime/media/store.mjs +1 -1
- package/src/runtime/memory/index.mjs +15 -1
- package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
- package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
- package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
- package/src/runtime/memory/lib/memory-embed.mjs +83 -14
- package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
- package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
- package/src/runtime/memory/lib/memory.mjs +17 -0
- package/src/runtime/memory/lib/pg/process.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
- package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/capabilities.mjs +1 -1
- package/src/runtime/office/core/office-core.mjs +1 -1
- package/src/runtime/office/design/content-model.mjs +3 -3
- package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
- package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
- package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
- package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
- package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
- package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +8 -6
- package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
- package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
- package/src/runtime/shared/agent-route-config.mjs +17 -2
- package/src/runtime/shared/atomic-file.d.mts +8 -0
- package/src/runtime/shared/atomic-file.mjs +103 -2
- package/src/runtime/shared/background-tasks.mjs +37 -10
- package/src/runtime/shared/background-wait.mjs +66 -0
- package/src/runtime/shared/child-guardian.mjs +17 -7
- package/src/runtime/shared/config.mjs +313 -16
- package/src/runtime/shared/connector-accounts.mjs +5 -5
- package/src/runtime/shared/connector-catalog.d.mts +14 -8
- package/src/runtime/shared/connector-catalog.mjs +70 -52
- package/src/runtime/shared/custom-provider-keys.mjs +20 -0
- package/src/runtime/shared/file-has-data.mjs +26 -2
- package/src/runtime/shared/file-lock.mjs +21 -18
- package/src/runtime/shared/git-launch.d.mts +9 -0
- package/src/runtime/shared/git-launch.mjs +213 -0
- package/src/runtime/shared/git-runner-worker.mjs +2 -1
- package/src/runtime/shared/git-runner.mjs +7 -2
- package/src/runtime/shared/idle-gc.mjs +30 -7
- package/src/runtime/shared/llm/cost.mjs +6 -1
- package/src/runtime/shared/llm/http-agent.mjs +316 -29
- package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
- package/src/runtime/shared/llm/model-catalog.mjs +46 -6
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
- package/src/runtime/shared/llm/system-proxy.mjs +453 -0
- package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
- package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
- package/src/runtime/shared/maintenance-schedule.mjs +109 -0
- package/src/runtime/shared/process-runner.mjs +8 -4
- package/src/runtime/shared/provider-accounts.mjs +52 -2
- package/src/runtime/shared/routine-trigger.d.mts +13 -0
- package/src/runtime/shared/routine-trigger.mjs +34 -0
- package/src/runtime/shared/run-child.d.mts +2 -1
- package/src/runtime/shared/run-child.mjs +70 -18
- package/src/runtime/shared/session-scratch.mjs +14 -2
- package/src/runtime/shared/shipped-definitions.mjs +7 -1
- package/src/runtime/shared/staged-install-worker.mjs +5 -0
- package/src/runtime/shared/staged-update.mjs +47 -2
- package/src/runtime/shared/tool-card-model.golden.json +3 -12
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-surface.mjs +110 -36
- package/src/runtime/shared/tool-work-units.mjs +35 -6
- package/src/runtime/shared/turn-snapshot.mjs +26 -4
- package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
- package/src/runtime/shared/worker-requests.mjs +17 -3
- package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
- package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
- package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
- package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
- package/src/runtime/shared/worktrees/contract.mjs +16 -6
- package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
- package/src/runtime/shared/worktrees/disk.mjs +79 -2
- package/src/runtime/shared/worktrees/git.mjs +97 -7
- package/src/runtime/shared/worktrees/include.mjs +6 -4
- package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
- package/src/runtime/shared/worktrees/manager.mjs +962 -197
- package/src/runtime/shared/worktrees/settings.mjs +33 -7
- package/src/runtime/shared/worktrees/test-support.mjs +5 -1
- package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
- package/src/runtime/tidy/install.mjs +95 -15
- package/src/runtime/tidy/languages.mjs +17 -15
- package/src/runtime/tidy/process.mjs +9 -5
- package/src/runtime/tidy/resolve.mjs +19 -16
- package/src/runtime/tidy/runners/biome.mjs +3 -3
- package/src/runtime/tidy/tool.mjs +1 -1
- package/src/runtime/tidy/worktree.mjs +10 -6
- package/src/runtime/visualize-bridge/client.mjs +4 -1
- package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
- package/src/runtime/web-search/index.mjs +4 -23
- package/src/runtime/web-search/lib/web-tools.mjs +2 -2
- package/src/runtime/web-search/tool-defs.mjs +17 -26
- package/src/session-runtime/agent-profile-changes.mjs +55 -4
- package/src/session-runtime/agent-task-sessions.mjs +410 -353
- package/src/session-runtime/boot/apis.mjs +27 -4
- package/src/session-runtime/boot/begin.mjs +2 -0
- package/src/session-runtime/boot/config.mjs +10 -1
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/providers.mjs +70 -3
- package/src/session-runtime/boot/session.mjs +2 -0
- package/src/session-runtime/boot/tools.mjs +71 -25
- package/src/session-runtime/bot-status.mjs +103 -103
- package/src/session-runtime/channel-config-api.mjs +1 -0
- package/src/session-runtime/config-change-effects.mjs +179 -0
- package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
- package/src/session-runtime/config-lifecycle.mjs +160 -24
- package/src/session-runtime/connector-merge-migration.mjs +18 -15
- package/src/session-runtime/conversation-import/discovery.mjs +245 -47
- package/src/session-runtime/conversation-import/service.mjs +12 -5
- package/src/session-runtime/goal-facade-api.mjs +49 -3
- package/src/session-runtime/handoff-attachments.mjs +1 -1
- package/src/session-runtime/held-requests.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
- package/src/session-runtime/internal-tool-executor.mjs +12 -19
- package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
- package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
- package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
- package/src/session-runtime/lifecycle/teardown.mjs +1 -1
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
- package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
- package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
- package/src/session-runtime/mixy-heartbeat.mjs +1 -1
- package/src/session-runtime/model-route/set-route.mjs +40 -7
- package/src/session-runtime/native-web-search/routes.mjs +3 -3
- package/src/session-runtime/provider-auth/login.mjs +2 -2
- package/src/session-runtime/provider-auth/refresh.mjs +6 -3
- package/src/session-runtime/provider-auth/setup.mjs +1 -1
- package/src/session-runtime/provider-readiness.mjs +53 -4
- package/src/session-runtime/resource-api.mjs +1 -1
- package/src/session-runtime/resource-extension-sync.mjs +4 -8
- package/src/session-runtime/resource-mcp-api.mjs +98 -35
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
- package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
- package/src/session-runtime/resource-mcp-servers.mjs +5 -4
- package/src/session-runtime/resource-plugins-api.mjs +4 -0
- package/src/session-runtime/routine-executor.mjs +152 -0
- package/src/session-runtime/routine-home-turn.mjs +46 -5
- package/src/session-runtime/runtime-facade.mjs +5 -0
- package/src/session-runtime/runtime-feature-gates.mjs +2 -11
- package/src/session-runtime/schedule-session-run.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
- package/src/session-runtime/services/agent-tool.mjs +51 -1
- package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
- package/src/session-runtime/services/channel-admin.mjs +18 -0
- package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
- package/src/session-runtime/services/daemon-candidate.mjs +4 -1
- package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
- package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
- package/src/session-runtime/services/plugin-admin.mjs +14 -6
- package/src/session-runtime/services/provider-admin.mjs +281 -10
- package/src/session-runtime/services/seeds.mjs +7 -0
- package/src/session-runtime/services/usage-stats-model.mjs +32 -11
- package/src/session-runtime/session-create/materialize.mjs +4 -2
- package/src/session-runtime/session-create/session-options.mjs +2 -0
- package/src/session-runtime/session-turn-api.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
- package/src/session-runtime/settings-system-api.mjs +1 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
- package/src/session-runtime/setup-tool/executor.mjs +14 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
- package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
- package/src/session-runtime/tool-policy-refresh.mjs +182 -5
- package/src/session-runtime/tool-surface.mjs +38 -1
- package/src/session-runtime/turn/agent-ops.mjs +33 -2
- package/src/session-runtime/turn/session-ops.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
- package/src/session-runtime/turn/turn-run.mjs +1 -1
- package/src/session-runtime/webhook-session-run.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
- package/src/session-runtime/workflow-agents-api.mjs +2 -0
- package/src/session-runtime/workspace/activity-guards.mjs +176 -0
- package/src/session-runtime/workspace/project-branches.mjs +1 -1
- package/src/session-runtime/workspace/session-view.mjs +149 -0
- package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
- package/src/session-runtime/workspace/transition-runner.mjs +188 -0
- package/src/session-runtime/workspace/transitions.mjs +128 -1070
- package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
- package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
- package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
- package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
- package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
- package/src/standalone/daemon-agent-control.mjs +25 -8
- package/src/standalone/daemon-desktop-runtime.mjs +8 -2
- package/src/standalone/daemon-lag-profiler.mjs +7 -7
- package/src/standalone/daemon-session-control.mjs +151 -136
- package/src/standalone/daemon.mjs +61 -2
- package/src/standalone/desktop-service-registry.mjs +9 -0
- package/src/standalone/local-session-runtime.mjs +21 -1
- package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
- package/src/standalone/session-client.mjs +5 -1
- package/src/standalone/session-frame-stream.mjs +83 -11
- package/src/standalone/session-protocol.mjs +15 -0
- package/src/standalone/session-service/agent-route-follow.mjs +23 -20
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
- package/src/standalone/session-service/agent-tree.mjs +45 -9
- package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
- package/src/standalone/session-service/quota-resume.mjs +9 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
- package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
- package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
- package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
- package/src/standalone/session-service/session-calls.mjs +2 -1
- package/src/standalone/session-service/stored-reader.mjs +127 -40
- package/src/tui/App.jsx +162 -164
- package/src/tui/app/app-view/floating-panel.jsx +3 -0
- package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
- package/src/tui/app/clipboard.mjs +22 -11
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/doctor.mjs +2 -2
- package/src/tui/app/panel-signature.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
- package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
- package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
- package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
- package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
- package/src/tui/app/provider-setup-picker.mjs +20 -13
- package/src/tui/app/settings-picker.mjs +53 -8
- package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
- package/src/tui/app/slash-commands.mjs +2 -1
- package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
- package/src/tui/app/slash-dispatch.mjs +1 -1
- package/src/tui/app/use-btw-panel.mjs +29 -0
- package/src/tui/app/use-context-panel-refresh.mjs +31 -0
- package/src/tui/app/use-model-catalog-cache.mjs +13 -10
- package/src/tui/app/use-mouse-input.mjs +11 -0
- package/src/tui/app/use-onboarding-start.mjs +8 -3
- package/src/tui/app/use-panel-transition.mjs +10 -1
- package/src/tui/app/use-pasted-buffers.mjs +28 -20
- package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
- package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
- package/src/tui/app/use-prompt-queue-history.mjs +5 -4
- package/src/tui/app/use-selection-focus.mjs +11 -2
- package/src/tui/app/use-selection-geometry.mjs +18 -9
- package/src/tui/app/use-selection-paint.mjs +4 -4
- package/src/tui/app/use-selection-stitch.mjs +3 -3
- package/src/tui/app/use-slash-palette.mjs +62 -0
- package/src/tui/app/use-terminal-chrome.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +48 -33
- package/src/tui/app/use-transcript-follow.mjs +12 -4
- package/src/tui/app/use-transcript-scroll.mjs +46 -17
- package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
- package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
- package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
- package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
- package/src/tui/app/use-transcript-window.mjs +21 -11
- package/src/tui/app/use-tui-ready.mjs +18 -0
- package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
- package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
- package/src/tui/components/Picker.jsx +27 -3
- package/src/tui/components/SignInUrl.jsx +68 -0
- package/src/tui/components/TextEntryPanel.jsx +76 -46
- package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
- package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
- package/src/tui/components/question-panel-model.mjs +4 -4
- package/src/tui/components/sign-in-url-layout.mjs +24 -0
- package/src/tui/components/tool-execution/standard-card.jsx +3 -4
- package/src/tui/components/user-message-skills.mjs +1 -1
- package/src/tui/dist/index.mjs +2205 -1371
- package/src/tui/markdown/render-ansi.mjs +1 -1
- package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
- package/src/tui/session/agent-job-feed.mjs +2 -0
- package/src/tui/session/context-state.mjs +3 -0
- package/src/tui/session/goal-turn-state.mjs +6 -2
- package/src/tui/session/quota-resume.mjs +1 -1
- package/src/tui/session/session-api/controls.mjs +4 -0
- package/src/tui/session/session-api/extensions.mjs +8 -0
- package/src/tui/session/session-api/intake/abort.mjs +2 -1
- package/src/tui/session/session-api/intake.mjs +2 -0
- package/src/tui/session/session-api/integrations.mjs +2 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
- package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
- package/src/tui/session/session-api/settings.mjs +2 -2
- package/src/tui/session/session-api/worktree.mjs +13 -1
- package/src/tui/session/session-flow/drain.mjs +11 -14
- package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
- package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
- package/src/tui/session/transcript-spill.mjs +92 -4
- package/src/tui/session/transcript-store.mjs +2 -0
- package/src/tui/session/turn-quiet.mjs +1 -1
- package/src/tui/session/turn.mjs +3 -0
- package/src/tui/session/worktree-setup-notice.mjs +1 -1
- package/src/tui/spinner-meta.mjs +3 -3
- package/src/tui/spinner-verbs.mjs +2 -2
- package/src/defaults/skills/goal-management/SKILL.md +0 -169
- package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
- package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
- package/src/session-runtime/goal-tasks.mjs +0 -1
|
@@ -124,6 +124,15 @@ export function createQuotaResumeScheduler({
|
|
|
124
124
|
function tick() {
|
|
125
125
|
if (running) return running;
|
|
126
126
|
running = (async () => {
|
|
127
|
+
// The setting turned off anywhere (another process, a hand edit), not
|
|
128
|
+
// only through setQuotaAutoResumeEnabled here: nothing pending resumes.
|
|
129
|
+
if (store.quotaAutoResumeEnabled?.() === false) {
|
|
130
|
+
if (store.listQuotaResumeEntries().length) {
|
|
131
|
+
store.cancelAllQuotaResumeEntries();
|
|
132
|
+
log('quota resume off: pending resumes cancelled');
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
127
136
|
for (const entry of store.listQuotaResumeEntries()) {
|
|
128
137
|
if (isClosed()) return;
|
|
129
138
|
if (entry.resetAt > now() || !isCurrent(store, entry)) continue;
|
|
@@ -5,6 +5,7 @@ import { SESSION_CONFIGURE_ACTION_SET, SESSION_READ_ACTION_SET } from '../../ses
|
|
|
5
5
|
import { annotateSpan, markPhase } from '../../../runtime/shared/slow-span.mjs';
|
|
6
6
|
import { sanitizeForWire } from '../../session-wire-values.mjs';
|
|
7
7
|
import { botWorkBySession } from '../../../runtime/shared/bot-owned-work.mjs';
|
|
8
|
+
import { createSessionTurnGate } from './turn-gate.mjs';
|
|
8
9
|
|
|
9
10
|
/** Reads a session without a live runtime answers from disk (readStoredReview). */
|
|
10
11
|
const STORED_REVIEW_ACTIONS = new Set([
|
|
@@ -43,6 +44,9 @@ export function createSessionActionCalls(ctx) {
|
|
|
43
44
|
const { bodyForClient } = ctx.projection;
|
|
44
45
|
const { retainUnwatched, awaitingApprovalSessionKinds, roomHandoffQuestions } = ctx.retention;
|
|
45
46
|
const { assertAvailable, hostedEntryForSession, entryForSession } = ctx.entries;
|
|
47
|
+
const { stateBusy } = ctx.retention;
|
|
48
|
+
const sessionOwner = ctx.projection?.sessionOwner;
|
|
49
|
+
const turnGate = ctx.turnGate ?? createSessionTurnGate();
|
|
46
50
|
|
|
47
51
|
/** A cold session's review, read from its durable turn record (the same
|
|
48
52
|
* source a runtime loaded only to answer it would read). Bodiless: the
|
|
@@ -82,7 +86,12 @@ export function createSessionActionCalls(ctx) {
|
|
|
82
86
|
if (storedReview && !hosted) return storedReviewResult(id, name, args, baseRevision);
|
|
83
87
|
const entry = hosted || (await entryForSession(id, openHints || {}));
|
|
84
88
|
assertAvailable(entry);
|
|
85
|
-
|
|
89
|
+
// A remote read of the context status waits for an empty session's
|
|
90
|
+
// settings reconcile; the local accessor stays synchronous.
|
|
91
|
+
const target =
|
|
92
|
+
name === 'contextStatus' && typeof entry.runtime.contextStatusSettled === 'function'
|
|
93
|
+
? entry.runtime.contextStatusSettled
|
|
94
|
+
: entry.runtime[name];
|
|
86
95
|
if (typeof target !== 'function') throw new TypeError(`session action ${name} is unavailable`);
|
|
87
96
|
markPhase('load');
|
|
88
97
|
const value = await target.apply(entry.runtime, Array.isArray(args) ? args : []);
|
|
@@ -162,9 +171,50 @@ export function createSessionActionCalls(ctx) {
|
|
|
162
171
|
};
|
|
163
172
|
}
|
|
164
173
|
|
|
174
|
+
/** The desktop's auto-delete through the control session (`sessionId`):
|
|
175
|
+
* `args` = [target id, { lastUsedAt }]. The target is closed to service
|
|
176
|
+
* turn starts while the runtime's idle-only delete checks and acts
|
|
177
|
+
* (session-delete.mjs deleteSessionIfIdle); one being admitted refuses it. */
|
|
178
|
+
async function deleteIdleSession({ sessionId, args = [], open: openHints = {}, baseRevision = null } = {}) {
|
|
179
|
+
assertAvailable();
|
|
180
|
+
const controlId = String(sessionId || '');
|
|
181
|
+
if (!controlId) throw new TypeError('sessionId is required');
|
|
182
|
+
const [target, expected] = Array.isArray(args) ? args : [];
|
|
183
|
+
const id = String(target || '');
|
|
184
|
+
const entry = await entryForSession(controlId, openHints || {});
|
|
185
|
+
assertAvailable(entry);
|
|
186
|
+
if (typeof entry.runtime.deleteSessionIfIdle !== 'function') {
|
|
187
|
+
throw new TypeError('session action deleteSessionIfIdle is unavailable');
|
|
188
|
+
}
|
|
189
|
+
let value;
|
|
190
|
+
const reopen = id ? turnGate.fence(id) : null;
|
|
191
|
+
if (!reopen) value = { deleted: false, reason: id ? 'turn-starting' : 'invalid' };
|
|
192
|
+
else {
|
|
193
|
+
try {
|
|
194
|
+
value = await entry.runtime.deleteSessionIfIdle(id, expected ?? {}, {
|
|
195
|
+
isHostedBusy: (sessionIdToCheck) => {
|
|
196
|
+
const owner = sessionOwner?.(sessionIdToCheck);
|
|
197
|
+
return Boolean(owner) && stateBusy(owner.runtime?.getState?.());
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
} finally {
|
|
201
|
+
reopen();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
log(`session action deleteSessionIfIdle session=${id} result=${resultSummary(value?.deleted ?? value)}`);
|
|
205
|
+
const step = advanceForCaller(entry);
|
|
206
|
+
retainUnwatched(entry);
|
|
207
|
+
return {
|
|
208
|
+
value: sanitizeForWire(value) ?? null,
|
|
209
|
+
sessionId: responseSessionId(entry, controlId),
|
|
210
|
+
...bodyForClient(step, Number.isInteger(baseRevision) ? baseRevision : null),
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
|
|
165
214
|
async function configureSession(params = {}, callCtx = null) {
|
|
166
215
|
const revision = Math.max(0, Number(callCtx?.revision) || 0);
|
|
167
216
|
const action = params?.action;
|
|
217
|
+
if (action === 'deleteSessionIfIdle') return deleteIdleSession(params);
|
|
168
218
|
// Revision 0 desktop adapters routed some reads through configure because
|
|
169
219
|
// their local read list lagged the session surface. A newer daemon accepts
|
|
170
220
|
// those reads without weakening the current revision's finite lanes.
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
// sessions that carry an active Goal after daemon replacement is wired in from
|
|
5
5
|
// ./goal-recovery.mjs.
|
|
6
6
|
import { createGoalRecovery } from './goal-recovery.mjs';
|
|
7
|
+
import { createSessionTurnGate } from './turn-gate.mjs';
|
|
7
8
|
import {
|
|
8
9
|
attachmentsForIntake,
|
|
9
10
|
materializePromptSubmission,
|
|
@@ -54,6 +55,8 @@ export function createSessionTurnCalls(ctx) {
|
|
|
54
55
|
const { log, readStoredGoal, listStoredActiveGoalSessionIds, hasAgentSession, sessionResult, advanceForCaller } = ctx;
|
|
55
56
|
const { retainUnwatched } = ctx.retention;
|
|
56
57
|
const { entryForSession } = ctx.entries;
|
|
58
|
+
// One gate per service, shared with the idle-only delete (session-calls.mjs).
|
|
59
|
+
const turnGate = ctx.turnGate ?? createSessionTurnGate();
|
|
57
60
|
|
|
58
61
|
/** Publishes the step an action produced and keeps the entry on the retention clock. */
|
|
59
62
|
const settleAction = (entry, reason) => {
|
|
@@ -66,16 +69,26 @@ export function createSessionTurnCalls(ctx) {
|
|
|
66
69
|
// attachment conversion that has not yet become a turn.
|
|
67
70
|
const intakeAborts = new Map();
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
/** Run `start` as an admitted turn start of `sessionId` (turn-gate.mjs). */
|
|
73
|
+
async function admitted(sessionId, start) {
|
|
74
|
+
const leave = turnGate.enter(sessionId);
|
|
75
|
+
try {
|
|
76
|
+
return await start();
|
|
77
|
+
} finally {
|
|
78
|
+
leave();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function submitSession(params = {}) {
|
|
83
|
+
const id = String(params?.sessionId || '');
|
|
78
84
|
if (!id) throw new TypeError('sessionId is required');
|
|
85
|
+
return admitted(id, () => submitAdmitted(id, params));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function submitAdmitted(
|
|
89
|
+
id,
|
|
90
|
+
{ prompt, options = {}, open: openHints = {}, baseRevision = null, signal = null } = {}
|
|
91
|
+
) {
|
|
79
92
|
const entry = await entryForSession(id, openHints || {});
|
|
80
93
|
const target = entry.runtime.submitAsync;
|
|
81
94
|
if (typeof target !== 'function') throw new TypeError('session runtime must implement submitAsync');
|
|
@@ -150,9 +163,12 @@ export function createSessionTurnCalls(ctx) {
|
|
|
150
163
|
async function materializeSession(sessionId, openHints = {}) {
|
|
151
164
|
const id = String(sessionId || '');
|
|
152
165
|
if (!id) throw new TypeError('sessionId is required');
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
166
|
+
// Its callers start work on the runtime (Goal and quota resumes, bots).
|
|
167
|
+
return admitted(id, async () => {
|
|
168
|
+
const entry = await entryForSession(id, openHints || {});
|
|
169
|
+
retainUnwatched(entry, 'daemon session owner');
|
|
170
|
+
return entry.runtime;
|
|
171
|
+
});
|
|
156
172
|
}
|
|
157
173
|
|
|
158
174
|
const recoverActiveGoals = createGoalRecovery({
|
|
@@ -196,12 +212,15 @@ export function createSessionTurnCalls(ctx) {
|
|
|
196
212
|
async function approveSession({ sessionId, approvalId, decision, open: openHints = {}, baseRevision = null } = {}) {
|
|
197
213
|
const id = String(sessionId || '');
|
|
198
214
|
if (!id) throw new TypeError('sessionId is required');
|
|
199
|
-
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
215
|
+
// An answer resumes the turn: an admitted start.
|
|
216
|
+
const { entry, approved } = await admitted(id, async () => {
|
|
217
|
+
const hosted = await entryForSession(id, openHints || {});
|
|
218
|
+
const target = hosted.runtime.resolveToolApproval;
|
|
219
|
+
if (typeof target !== 'function') {
|
|
220
|
+
throw new TypeError('session action resolveToolApproval is unavailable');
|
|
221
|
+
}
|
|
222
|
+
return { entry: hosted, approved: await target.call(hosted.runtime, approvalId, decision) };
|
|
223
|
+
});
|
|
205
224
|
const step = settleAction(entry, 'headless session approval');
|
|
206
225
|
return sessionResult(entry, step, baseRevision, { approved: approved === true });
|
|
207
226
|
}
|
|
@@ -6,60 +6,26 @@ import { SESSION_READ_ACTION_SET } from '../../session-protocol.mjs';
|
|
|
6
6
|
import { SESSION_ID_PATTERN } from '../agent-tree.mjs';
|
|
7
7
|
import {
|
|
8
8
|
loadLiveTranscriptHead,
|
|
9
|
+
readTranscriptHistory,
|
|
9
10
|
readTranscriptRange,
|
|
10
11
|
rebudgetTranscriptWindow,
|
|
12
|
+
requestedTranscriptHistory,
|
|
11
13
|
requestedHeldTranscript,
|
|
12
14
|
requestedTranscriptWindow,
|
|
13
15
|
requestLiveTranscriptWindow,
|
|
16
|
+
restartTranscriptWindow,
|
|
17
|
+
transcriptAnswerBounds,
|
|
14
18
|
transcriptPageBody,
|
|
19
|
+
transcriptWindowOversized,
|
|
15
20
|
} from '../projection/transcript-window.mjs';
|
|
16
21
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
-
const {
|
|
25
|
-
subscriberToken,
|
|
26
|
-
addSubscriber,
|
|
27
|
-
trackPendingViewer,
|
|
28
|
-
dropPendingViewer,
|
|
29
|
-
adoptPendingViewers,
|
|
30
|
-
notePrependViewer,
|
|
31
|
-
} = ctx.viewers;
|
|
32
|
-
const { sessionBusy, retainUnwatched, releaseProjection, startEvictionSweep } = ctx.retention;
|
|
33
|
-
const {
|
|
34
|
-
assertAvailable,
|
|
35
|
-
createEntry,
|
|
36
|
-
getOrCreateSessionEntry,
|
|
37
|
-
entryForSession,
|
|
38
|
-
liveEntryForView,
|
|
39
|
-
bindExternalSessionView,
|
|
40
|
-
destroy,
|
|
41
|
-
} = ctx.entries;
|
|
42
|
-
const {
|
|
43
|
-
storedSessionProjection,
|
|
44
|
-
storedProjectionUnchanged,
|
|
45
|
-
requestedMessageSlice,
|
|
46
|
-
forgetStoredSession,
|
|
47
|
-
releaseStoredSession,
|
|
48
|
-
} = ctx.storedReader;
|
|
49
|
-
|
|
50
|
-
/** A read/subscribe names the transcript window its view wants (none: the
|
|
51
|
-
* whole transcript). A window grown past what a resumed runtime holds is
|
|
52
|
-
* completed from durable history, which a live session never keeps cached. */
|
|
53
|
-
async function applyTranscriptRequest(entry, params, sessionId) {
|
|
54
|
-
const request = requestedTranscriptWindow(params);
|
|
55
|
-
// A model-message read (messageStart) is not a view and leaves the window.
|
|
56
|
-
if (request || !Number.isInteger(params.messageStart)) requestLiveTranscriptWindow(entry, request);
|
|
57
|
-
// No baseline the next step can patch: this caller receives the window
|
|
58
|
-
// whole, so it goes out within its byte budget.
|
|
59
|
-
if (request && params.baseRevision !== entry.revision) rebudgetTranscriptWindow(entry);
|
|
60
|
-
if (await loadLiveTranscriptHead(entry, sessionId, readStoredSession)) forgetStoredSession(sessionId);
|
|
61
|
-
assertAvailable(entry);
|
|
62
|
-
}
|
|
22
|
+
/** Creating (reserving) a session. */
|
|
23
|
+
function createSessionCreation(ctx) {
|
|
24
|
+
const { log, sessionResult, advanceForCaller } = ctx;
|
|
25
|
+
const { currentSessionId } = ctx.projection;
|
|
26
|
+
const { addSubscriber, adoptPendingViewers } = ctx.viewers;
|
|
27
|
+
const { retainUnwatched } = ctx.retention;
|
|
28
|
+
const { assertAvailable, createEntry, getOrCreateSessionEntry, destroy } = ctx.entries;
|
|
63
29
|
|
|
64
30
|
async function createReservedSession(params, viewer, reservedSessionId) {
|
|
65
31
|
const entry = await createEntry({ ...params, sessionId: reservedSessionId }, viewer);
|
|
@@ -103,6 +69,138 @@ export function createSessionViewCalls(ctx) {
|
|
|
103
69
|
return sessionResult(entry, step);
|
|
104
70
|
}
|
|
105
71
|
|
|
72
|
+
return { createSession };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** The transcript window a live view is answered through: requesting it,
|
|
76
|
+
* bounding the answer, and attaching a subscriber to a live entry. */
|
|
77
|
+
function createLiveTranscriptAnswers(ctx) {
|
|
78
|
+
const { readStoredSession, sessionResult, advanceForCaller } = ctx;
|
|
79
|
+
const { currentSessionId } = ctx.projection;
|
|
80
|
+
const { addSubscriber } = ctx.viewers;
|
|
81
|
+
const { assertAvailable } = ctx.entries;
|
|
82
|
+
|
|
83
|
+
/** A read/subscribe names the transcript window its view wants (none: the
|
|
84
|
+
* whole transcript). A window grown past what a resumed runtime holds is
|
|
85
|
+
* completed from durable history, sliced from the store's cached display
|
|
86
|
+
* history of the record's content. */
|
|
87
|
+
async function applyTranscriptRequest(entry, params, sessionId) {
|
|
88
|
+
const request = requestedTranscriptWindow(params);
|
|
89
|
+
// A model-message read (messageStart) is not a view and leaves the window.
|
|
90
|
+
if (request || !Number.isInteger(params.messageStart)) requestLiveTranscriptWindow(entry, request);
|
|
91
|
+
// No baseline the next step can patch: this caller receives the window
|
|
92
|
+
// whole, so it goes out within its byte budget.
|
|
93
|
+
if (request && params.baseRevision !== entry.revision) rebudgetTranscriptWindow(entry);
|
|
94
|
+
await loadLiveTranscriptHead(entry, sessionId, readStoredSession);
|
|
95
|
+
assertAvailable(entry);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** The caller's answer for `step`, reduced to a page when it proves the rows
|
|
99
|
+
* it holds and they fit one answer. A window that would go out whole past
|
|
100
|
+
* the request's bounds (transcriptAnswerBounds) does not: a caller already
|
|
101
|
+
* at this revision needs no body; any other gets a bounded recovery
|
|
102
|
+
* snapshot — the window restarts from a fresh tail, which the views
|
|
103
|
+
* attached receive as a step too. */
|
|
104
|
+
function boundedSessionResult(entry, step, params, baseRevision, extra) {
|
|
105
|
+
const prepend = params.transcriptPrepend === true;
|
|
106
|
+
const bounds = transcriptAnswerBounds(requestedTranscriptWindow(params));
|
|
107
|
+
const result = transcriptPageBody(
|
|
108
|
+
sessionResult(entry, step, baseRevision, extra, { prepend }),
|
|
109
|
+
requestedHeldTranscript(params),
|
|
110
|
+
{ byteBudget: bounds.byteBudget }
|
|
111
|
+
);
|
|
112
|
+
if (!transcriptWindowOversized(entry, result.full, bounds)) return result;
|
|
113
|
+
if (baseRevision === step.revision) {
|
|
114
|
+
const { full: _full, ...bodiless } = result;
|
|
115
|
+
return bodiless;
|
|
116
|
+
}
|
|
117
|
+
restartTranscriptWindow(entry, bounds.maxItems);
|
|
118
|
+
return sessionResult(entry, advanceForCaller(entry), baseRevision, extra, { prepend });
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Publish BEFORE attaching: the views already there get the frame, the new
|
|
122
|
+
* one gets the same revision once in its reply. */
|
|
123
|
+
const subscribeLive = async (entry, params, viewer, baseRevision) => {
|
|
124
|
+
await applyTranscriptRequest(entry, params, currentSessionId(entry) || String(params.sessionId || ''));
|
|
125
|
+
const prepend = params.transcriptPrepend === true;
|
|
126
|
+
let step = advanceForCaller(entry);
|
|
127
|
+
// Bounded like a read (boundedSessionResult), before attaching: the new
|
|
128
|
+
// view receives the restarted tail once, in its reply.
|
|
129
|
+
const bounds = transcriptAnswerBounds(requestedTranscriptWindow(params));
|
|
130
|
+
if (transcriptWindowOversized(entry, sessionResult(entry, step, baseRevision, {}, { prepend }).full, bounds)) {
|
|
131
|
+
restartTranscriptWindow(entry, bounds.maxItems);
|
|
132
|
+
step = advanceForCaller(entry);
|
|
133
|
+
}
|
|
134
|
+
addSubscriber(entry, viewer);
|
|
135
|
+
return sessionResult(entry, step, baseRevision, { subscribed: true }, { prepend });
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return { applyTranscriptRequest, boundedSessionResult, subscribeLive };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** Detaching a view from a live or cold session. */
|
|
142
|
+
function createSessionUnsubscribe(ctx) {
|
|
143
|
+
const { log, externalViewEntries } = ctx;
|
|
144
|
+
const { externalEntryForView, sessionOwner } = ctx.projection;
|
|
145
|
+
const { subscriberToken, dropPendingViewer } = ctx.viewers;
|
|
146
|
+
const { sessionBusy, releaseProjection, startEvictionSweep } = ctx.retention;
|
|
147
|
+
const { destroy } = ctx.entries;
|
|
148
|
+
const { releaseStoredSession } = ctx.storedReader;
|
|
149
|
+
|
|
150
|
+
async function unsubscribeSession({ sessionId } = {}, viewer = null) {
|
|
151
|
+
const id = String(sessionId || '');
|
|
152
|
+
if (!id) throw new TypeError('sessionId is required');
|
|
153
|
+
const coldViewers = dropPendingViewer(id, viewer);
|
|
154
|
+
const owner = sessionOwner(id);
|
|
155
|
+
if (!owner) {
|
|
156
|
+
const external = externalEntryForView(id);
|
|
157
|
+
if (external) {
|
|
158
|
+
const token = subscriberToken(viewer);
|
|
159
|
+
if (token) external.subscribers?.delete(token);
|
|
160
|
+
if ((external.subscribers?.size || 0) === 0) externalViewEntries.delete(id);
|
|
161
|
+
}
|
|
162
|
+
// The last cold view left: its disk projection turns idle, kept within
|
|
163
|
+
// the store's idle budget so a revisit skips the parse.
|
|
164
|
+
if (!coldViewers) releaseStoredSession(id);
|
|
165
|
+
return { sessionId: id, unsubscribed: true };
|
|
166
|
+
}
|
|
167
|
+
const entry = owner;
|
|
168
|
+
const token = subscriberToken(viewer);
|
|
169
|
+
if (token) entry.subscribers?.delete(token);
|
|
170
|
+
if ((entry.subscribers?.size || 0) === 0) {
|
|
171
|
+
entry.transcriptView = null;
|
|
172
|
+
if (entry.reservedOnly && !sessionBusy(entry)) {
|
|
173
|
+
await destroy(entry, 'unclaimed session reservation', {
|
|
174
|
+
keepBackgroundWork: true,
|
|
175
|
+
});
|
|
176
|
+
return { sessionId: id, unsubscribed: true };
|
|
177
|
+
}
|
|
178
|
+
entry.retainedAt = Date.now();
|
|
179
|
+
releaseProjection(entry);
|
|
180
|
+
startEvictionSweep();
|
|
181
|
+
}
|
|
182
|
+
log(`session unsubscribed session=${id}${token ? ` client=${token}` : ''}`);
|
|
183
|
+
return { sessionId: id, unsubscribed: true };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return { unsubscribeSession };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function createSessionViewCalls(ctx) {
|
|
190
|
+
const { readStoredSession, runSessionAction, advanceForCaller } = ctx;
|
|
191
|
+
const { externalEntryForView, projectionResult, unchangedProjectionResult, sessionOwner } = ctx.projection;
|
|
192
|
+
/** The owner a concurrent materialization may have produced while a disk
|
|
193
|
+
* read was in flight: a daemon-owned runtime outranks an external view. */
|
|
194
|
+
const lateOwnerFor = (id) => sessionOwner(id) || externalEntryForView(id);
|
|
195
|
+
const { trackPendingViewer, dropPendingViewer, notePrependViewer } = ctx.viewers;
|
|
196
|
+
const { retainUnwatched } = ctx.retention;
|
|
197
|
+
const { assertAvailable, entryForSession, liveEntryForView, bindExternalSessionView } = ctx.entries;
|
|
198
|
+
const { storedSessionProjection, storedProjectionUnchanged, storedPageOnly, requestedMessageSlice } =
|
|
199
|
+
ctx.storedReader;
|
|
200
|
+
const { createSession } = createSessionCreation(ctx);
|
|
201
|
+
const { applyTranscriptRequest, boundedSessionResult, subscribeLive } = createLiveTranscriptAnswers(ctx);
|
|
202
|
+
const { unsubscribeSession } = createSessionUnsubscribe(ctx);
|
|
203
|
+
|
|
106
204
|
async function liveSessionReadResult(entry, params, sessionId, baseRevision) {
|
|
107
205
|
assertAvailable(entry);
|
|
108
206
|
await applyTranscriptRequest(entry, params, sessionId);
|
|
@@ -110,11 +208,7 @@ export function createSessionViewCalls(ctx) {
|
|
|
110
208
|
retainUnwatched(entry, 'headless session read');
|
|
111
209
|
const messages = await requestedMessageSlice(params, sessionId);
|
|
112
210
|
assertAvailable(entry);
|
|
113
|
-
|
|
114
|
-
return transcriptPageBody(
|
|
115
|
-
sessionResult(entry, step, baseRevision, messages, { prepend }),
|
|
116
|
-
requestedHeldTranscript(params)
|
|
117
|
-
);
|
|
211
|
+
return boundedSessionResult(entry, step, params, baseRevision, messages);
|
|
118
212
|
}
|
|
119
213
|
|
|
120
214
|
/** The live entry a view can attach to: the owner, an external view, or a
|
|
@@ -146,6 +240,13 @@ export function createSessionViewCalls(ctx) {
|
|
|
146
240
|
assertAvailable(live);
|
|
147
241
|
return { range };
|
|
148
242
|
}
|
|
243
|
+
const historyRequest = requestedTranscriptHistory(params);
|
|
244
|
+
if (historyRequest) {
|
|
245
|
+
// Read-only: no window, baseline or revision of any view moves.
|
|
246
|
+
const history = await readTranscriptHistory(live, id, readStoredSession, historyRequest);
|
|
247
|
+
assertAvailable(live);
|
|
248
|
+
return { history };
|
|
249
|
+
}
|
|
149
250
|
if (live) {
|
|
150
251
|
return liveSessionReadResult(live, params, id, baseRevision);
|
|
151
252
|
}
|
|
@@ -162,7 +263,8 @@ export function createSessionViewCalls(ctx) {
|
|
|
162
263
|
const lateOwner = lateOwnerFor(id);
|
|
163
264
|
return lateOwner ? liveSessionReadResult(lateOwner, params, id, baseRevision) : held;
|
|
164
265
|
}
|
|
165
|
-
const
|
|
266
|
+
const heldRows = requestedHeldTranscript(params);
|
|
267
|
+
const projection = await storedSessionProjection(id, openHints, window, heldRows, baseProjectionStamp);
|
|
166
268
|
assertAvailable();
|
|
167
269
|
const lateOwner = lateOwnerFor(id);
|
|
168
270
|
if (lateOwner) {
|
|
@@ -179,28 +281,18 @@ export function createSessionViewCalls(ctx) {
|
|
|
179
281
|
});
|
|
180
282
|
const messages = await requestedMessageSlice(params, id);
|
|
181
283
|
assertAvailable();
|
|
182
|
-
|
|
284
|
+
// The stored reader already proved (or disproved) the held rows, and
|
|
285
|
+
// its projection then carries only the page above them.
|
|
286
|
+
const page = storedPageOnly(projection)
|
|
287
|
+
? transcriptPageBody(result, heldRows, { proven: true, byteBudget: window?.byteBudget, pageOnly: true })
|
|
288
|
+
: result;
|
|
289
|
+
return { ...page, ...messages };
|
|
183
290
|
}
|
|
184
291
|
// Embedders without a store reader keep the legacy load-on-read seam.
|
|
185
292
|
const entry = await entryForSession(id, openHints || {});
|
|
186
293
|
return liveSessionReadResult(entry, params, id, baseRevision);
|
|
187
294
|
}
|
|
188
295
|
|
|
189
|
-
/** Publish BEFORE attaching: the views already there get the frame, the new
|
|
190
|
-
* one gets the same revision once in its reply. */
|
|
191
|
-
const subscribeLive = async (entry, params, viewer, baseRevision) => {
|
|
192
|
-
await applyTranscriptRequest(entry, params, currentSessionId(entry) || String(params.sessionId || ''));
|
|
193
|
-
const step = advanceForCaller(entry);
|
|
194
|
-
addSubscriber(entry, viewer);
|
|
195
|
-
return sessionResult(
|
|
196
|
-
entry,
|
|
197
|
-
step,
|
|
198
|
-
baseRevision,
|
|
199
|
-
{ subscribed: true },
|
|
200
|
-
{ prepend: params.transcriptPrepend === true }
|
|
201
|
-
);
|
|
202
|
-
};
|
|
203
|
-
|
|
204
296
|
async function subscribeSession(params = {}, viewer = null) {
|
|
205
297
|
const { sessionId, open: openHints = {}, baseRevision = null } = params;
|
|
206
298
|
assertAvailable();
|
|
@@ -236,41 +328,5 @@ export function createSessionViewCalls(ctx) {
|
|
|
236
328
|
return subscribeLive(entry, params, viewer, baseRevision);
|
|
237
329
|
}
|
|
238
330
|
|
|
239
|
-
async function unsubscribeSession({ sessionId } = {}, viewer = null) {
|
|
240
|
-
const id = String(sessionId || '');
|
|
241
|
-
if (!id) throw new TypeError('sessionId is required');
|
|
242
|
-
const coldViewers = dropPendingViewer(id, viewer);
|
|
243
|
-
const owner = sessionOwner(id);
|
|
244
|
-
if (!owner) {
|
|
245
|
-
const external = externalEntryForView(id);
|
|
246
|
-
if (external) {
|
|
247
|
-
const token = subscriberToken(viewer);
|
|
248
|
-
if (token) external.subscribers?.delete(token);
|
|
249
|
-
if ((external.subscribers?.size || 0) === 0) externalViewEntries.delete(id);
|
|
250
|
-
}
|
|
251
|
-
// The last cold view left: its disk projection turns idle, kept within
|
|
252
|
-
// the store's idle budget so a revisit skips the parse.
|
|
253
|
-
if (!coldViewers) releaseStoredSession(id);
|
|
254
|
-
return { sessionId: id, unsubscribed: true };
|
|
255
|
-
}
|
|
256
|
-
const entry = owner;
|
|
257
|
-
const token = subscriberToken(viewer);
|
|
258
|
-
if (token) entry.subscribers?.delete(token);
|
|
259
|
-
if ((entry.subscribers?.size || 0) === 0) {
|
|
260
|
-
entry.transcriptView = null;
|
|
261
|
-
if (entry.reservedOnly && !sessionBusy(entry)) {
|
|
262
|
-
await destroy(entry, 'unclaimed session reservation', {
|
|
263
|
-
keepBackgroundWork: true,
|
|
264
|
-
});
|
|
265
|
-
return { sessionId: id, unsubscribed: true };
|
|
266
|
-
}
|
|
267
|
-
entry.retainedAt = Date.now();
|
|
268
|
-
releaseProjection(entry);
|
|
269
|
-
startEvictionSweep();
|
|
270
|
-
}
|
|
271
|
-
log(`session unsubscribed session=${id}${token ? ` client=${token}` : ''}`);
|
|
272
|
-
return { sessionId: id, unsubscribed: true };
|
|
273
|
-
}
|
|
274
|
-
|
|
275
331
|
return { createSession, readSession, subscribeSession, unsubscribeSession };
|
|
276
332
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// session-calls/turn-gate.mjs
|
|
2
|
+
// The service's turn starts per session (a submit's intake, an approval that
|
|
3
|
+
// resumes a turn, a materialization for a Goal or quota resume) against the
|
|
4
|
+
// desktop's idle-only delete: the delete closes a session to new starts only
|
|
5
|
+
// while none is being admitted, and a start refuses while it is closed.
|
|
6
|
+
import { SessionClosedError } from '../../../runtime/agent/orchestrator/session/manager/session-errors.mjs';
|
|
7
|
+
|
|
8
|
+
export function createSessionTurnGate() {
|
|
9
|
+
const starting = new Map(); // sessionId -> admissions in flight
|
|
10
|
+
const fenced = new Set();
|
|
11
|
+
return {
|
|
12
|
+
/** Admit a turn start of `sessionId`; the returned release ends it. */
|
|
13
|
+
enter(sessionId) {
|
|
14
|
+
if (fenced.has(sessionId)) {
|
|
15
|
+
throw new SessionClosedError(sessionId, 'session is being deleted', 'auto-retention-delete');
|
|
16
|
+
}
|
|
17
|
+
starting.set(sessionId, (starting.get(sessionId) || 0) + 1);
|
|
18
|
+
let left = false;
|
|
19
|
+
return () => {
|
|
20
|
+
if (left) return;
|
|
21
|
+
left = true;
|
|
22
|
+
const count = (starting.get(sessionId) || 1) - 1;
|
|
23
|
+
if (count > 0) starting.set(sessionId, count);
|
|
24
|
+
else starting.delete(sessionId);
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
/** Close `sessionId` to turn starts; null while one is being admitted. */
|
|
28
|
+
fence(sessionId) {
|
|
29
|
+
if (starting.has(sessionId) || fenced.has(sessionId)) return null;
|
|
30
|
+
fenced.add(sessionId);
|
|
31
|
+
return () => fenced.delete(sessionId);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { createSessionActionCalls } from './session-calls/session-action.mjs';
|
|
15
15
|
import { createSessionTurnCalls } from './session-calls/session-turns.mjs';
|
|
16
16
|
import { createSessionViewCalls } from './session-calls/session-views.mjs';
|
|
17
|
+
import { createSessionTurnGate } from './session-calls/turn-gate.mjs';
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* @param {object} deps
|
|
@@ -54,7 +55,7 @@ export function createSessionCalls(deps) {
|
|
|
54
55
|
return step;
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
const ctx = { ...deps, sessionResult, responseSessionId, advanceForCaller };
|
|
58
|
+
const ctx = { ...deps, sessionResult, responseSessionId, advanceForCaller, turnGate: createSessionTurnGate() };
|
|
58
59
|
const actions = createSessionActionCalls(ctx);
|
|
59
60
|
const views = createSessionViewCalls({ ...ctx, runSessionAction: actions.runSessionAction });
|
|
60
61
|
const turns = createSessionTurnCalls(ctx);
|