mixdog 1.4.2 → 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 +2 -2
- package/scripts/build-shipped-history.mjs +15 -5
- package/scripts/gate-local.mjs +65 -19
- package/scripts/graph-parity.mjs +8 -3
- package/scripts/lib/gate-scheduler.mjs +2 -1
- package/scripts/lib/run-node-tests.mjs +17 -5
- package/scripts/lib/test-failure-summary.mjs +1 -8
- package/scripts/lib/test-spawn-ledger.mjs +33 -2
- package/scripts/post-release-check.mjs +26 -16
- package/scripts/provider-pingpong-live.mjs +1 -1
- package/scripts/prune-embedding-runtime.mjs +3 -1
- package/scripts/release-paths.mjs +7 -1
- package/src/defaults/shipped-history.json +20 -0
- package/src/defaults/skills/setup/SKILL.md +2 -2
- package/src/defaults/skills/setup/references/actions.md +16 -3
- package/src/defaults/skills/setup/references/surfaces.md +3 -0
- package/src/defaults/skills/setup-guide/SKILL.md +6 -1
- package/src/lib/instruction-text.cjs +36 -0
- package/src/lib/rules-builder.cjs +34 -20
- 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/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +0 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +4 -2
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +0 -9
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
- 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/context/role-instructions.mjs +4 -4
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -1
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +199 -46
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +3 -5
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +9 -3
- package/src/runtime/agent/orchestrator/mcp/client.mjs +3 -5
- 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-probe.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
- 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-responses-payload-parity.fixture.json +288 -300
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +30 -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 -48
- 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 +9 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
- 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/attachment-preflight.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +2 -2
- 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 +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +1 -2
- 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/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 +6 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- 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 +57 -26
- 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 +19 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +19 -10
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +42 -6
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +11 -1
- 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 +1 -1
- 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 +1 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -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-transcript-projection.mjs +14 -5
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +2 -2
- 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/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 +7 -3
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +27 -9
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
- 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/search-tool.mjs +0 -10
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1 -2
- 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/lib/shell-descendants.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -4
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
- 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-server.mjs +12 -12
- 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 +169 -33
- package/src/runtime/connectors/gmail-app-password.mjs +2 -2
- 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 +0 -5
- package/src/runtime/explore/tool.mjs +3 -3
- 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 +11 -1
- package/src/runtime/memory/lib/embedding-reindex.mjs +27 -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/shared/atomic-file.d.mts +8 -0
- package/src/runtime/shared/background-tasks.mjs +22 -4
- 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-catalog.d.mts +4 -5
- package/src/runtime/shared/connector-catalog.mjs +11 -1
- package/src/runtime/shared/file-lock.mjs +8 -3
- package/src/runtime/shared/git-runner.mjs +7 -2
- package/src/runtime/shared/idle-gc.mjs +30 -7
- package/src/runtime/shared/llm/http-agent.mjs +8 -5
- package/src/runtime/shared/llm/system-proxy.mjs +2 -1
- 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/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/tool-card-model.golden.json +3 -12
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-work-units.mjs +31 -6
- package/src/runtime/shared/turn-snapshot.mjs +26 -4
- package/src/runtime/shared/turn-worktree-snapshot.mjs +6 -11
- package/src/runtime/shared/worker-requests.mjs +17 -3
- package/src/runtime/shared/worktrees/branch-management.mjs +1 -5
- 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 +44 -11
- 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 +772 -75
- 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/process.mjs +2 -1
- package/src/runtime/web-search/index.mjs +3 -22
- 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/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 +69 -25
- 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/conversation-import/discovery.mjs +86 -7
- package/src/session-runtime/conversation-import/service.mjs +3 -2
- package/src/session-runtime/goal-facade-api.mjs +49 -3
- 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 +3 -11
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +18 -4
- 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 +4 -4
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +14 -3
- package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
- 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/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-connector-accounts.mjs +5 -1
- package/src/session-runtime/resource-mcp-secrets.mjs +3 -3
- 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 +110 -6
- 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-run.mjs +24 -6
- package/src/session-runtime/services/agent-tool.mjs +51 -1
- package/src/session-runtime/services/channel-admin.mjs +18 -0
- package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
- package/src/session-runtime/services/plugin-admin.mjs +4 -0
- 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/settings-builtin-tools-api.mjs +1 -9
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +1 -1
- package/src/session-runtime/setup-tool/executor.mjs +8 -1
- 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 +26 -1
- 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 +10 -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 +1 -4
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +3 -10
- 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/project-branches.mjs +1 -1
- package/src/session-runtime/workspace/session-view.mjs +1 -1
- package/src/session-runtime/workspace/transitions.mjs +20 -4
- package/src/session-runtime/workspace/worktree-maintenance.mjs +126 -6
- package/src/session-runtime/workspace/worktree-setup.mjs +13 -1
- package/src/session-runtime/workspace/worktree-tool.mjs +16 -0
- package/src/standalone/daemon-agent-control.mjs +25 -8
- package/src/standalone/daemon-desktop-runtime.mjs +6 -2
- package/src/standalone/daemon-lag-profiler.mjs +7 -7
- package/src/standalone/daemon.mjs +54 -2
- package/src/standalone/local-session-runtime.mjs +16 -0
- package/src/standalone/session-client/daemon-unavailable.mjs +1 -1
- package/src/standalone/session-protocol.mjs +11 -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/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/turn-gate.mjs +34 -0
- package/src/standalone/session-service/session-calls.mjs +2 -1
- package/src/tui/App.jsx +8 -0
- package/src/tui/app/clipboard.mjs +1 -1
- 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/settings-picker.mjs +53 -8
- package/src/tui/app/shell-layout/row-budgets.mjs +2 -2
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +1 -1
- package/src/tui/app/use-prompt-queue-history.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +1 -1
- package/src/tui/app/use-transcript-window/geometry.mjs +1 -1
- 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/tool-execution/standard-card.jsx +3 -4
- package/src/tui/components/user-message-skills.mjs +1 -1
- package/src/tui/dist/index.mjs +309 -30
- 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/quota-resume.mjs +1 -1
- 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 +5 -0
- 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/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/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
- package/src/session-runtime/goal-tasks.mjs +0 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// The report a finished ask hands its caller (an agent's owner).
|
|
2
|
+
//
|
|
3
|
+
// A turn's `content` is what the live view still needs at its end: the text
|
|
4
|
+
// since the last tool batch. An answer the turn kept going past (a todo
|
|
5
|
+
// reminder or queued input arrived after it) and a turn that queued input
|
|
6
|
+
// followed in the same ask are both older than that, so the result carries
|
|
7
|
+
// them in `reportContent`, ahead of the newest text.
|
|
8
|
+
|
|
9
|
+
export function joinReports(parts) {
|
|
10
|
+
return parts
|
|
11
|
+
.map((part) => String(part || '').trim())
|
|
12
|
+
.filter(Boolean)
|
|
13
|
+
.join('\n\n');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The whole report of a result: `reportContent` when the ask carried earlier
|
|
17
|
+
* answers, else its content. */
|
|
18
|
+
export function turnReportText(result) {
|
|
19
|
+
if (typeof result?.reportContent === 'string') return result.reportContent;
|
|
20
|
+
return typeof result?.content === 'string' ? result.content : '';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** `result` with `earlier` answers ahead of its own report. */
|
|
24
|
+
export function withEarlierReport(result, earlier) {
|
|
25
|
+
if (!earlier) return result;
|
|
26
|
+
return { ...result, reportContent: joinReports([earlier, turnReportText(result)]) };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** A turn that fails after such answers still hands them on: `error` carries
|
|
30
|
+
* them (`carriedReport`, earliest first) to whoever reports the failure. */
|
|
31
|
+
export function carryReportOnError(error, earlier) {
|
|
32
|
+
if (!earlier || !error || typeof error !== 'object') return error;
|
|
33
|
+
error.carriedReport = joinReports([earlier, typeof error.carriedReport === 'string' ? error.carriedReport : '']);
|
|
34
|
+
return error;
|
|
35
|
+
}
|
|
@@ -90,7 +90,7 @@ const SUMMED_USAGE_FIELDS = [
|
|
|
90
90
|
];
|
|
91
91
|
|
|
92
92
|
/** What `total` added after the running total `earlier` (both from addUsage); null when nothing. */
|
|
93
|
-
|
|
93
|
+
function usageSince(total, earlier) {
|
|
94
94
|
if (!total) return null;
|
|
95
95
|
if (!earlier) return { ...total };
|
|
96
96
|
const delta = {};
|
|
@@ -15,9 +15,10 @@ import { drainPendingMessages, hydratePendingMessages } from './pending-messages
|
|
|
15
15
|
import { _unlinkParentAbortListener, _getRuntimeEntry, _evictTerminalSessionRuntime } from './runtime-liveness.mjs';
|
|
16
16
|
import { acquireSessionLock } from './session-lock.mjs';
|
|
17
17
|
import { createAskPromptQueue } from './ask-queue.mjs';
|
|
18
|
-
import { armTurnDurability, claimTurnRuntime } from './ask-turn-open.mjs';
|
|
18
|
+
import { armTurnDurability, claimTurnRuntime, settleTurnBase } from './ask-turn-open.mjs';
|
|
19
19
|
import { prepareAskTurn, runAskAgentLoop } from './ask-turn-execute.mjs';
|
|
20
20
|
import { commitAskTurn, publishAskTurn } from './ask-turn-settle.mjs';
|
|
21
|
+
import { carryReportOnError, turnReportText, withEarlierReport } from '../loop/turn-report.mjs';
|
|
21
22
|
import { finalizeAskTurnFailure } from './ask-turn-failure.mjs';
|
|
22
23
|
import { armTurnTimeoutOnProviderError, reapTurnShellJobs } from './turn-reap.mjs';
|
|
23
24
|
import { cacheWarmTurnKind, endCacheWarmTurn, failedTurnProvenance, noteCacheWarmTurn } from '../cache-warm.mjs';
|
|
@@ -78,7 +79,17 @@ export function createAskTranscriptMeta(rawTranscriptMeta) {
|
|
|
78
79
|
/** One opened turn from provider call to terminal publish; a failure unwinds
|
|
79
80
|
* the turn state and rethrows. Returns the terminal result preview and the
|
|
80
81
|
* follow-ups drained right after the provider accepted the turn. */
|
|
81
|
-
async function runAskTurn({
|
|
82
|
+
async function runAskTurn({
|
|
83
|
+
sessionId,
|
|
84
|
+
opened,
|
|
85
|
+
input,
|
|
86
|
+
askOpts,
|
|
87
|
+
onToolCall,
|
|
88
|
+
cwdOverride,
|
|
89
|
+
transcript,
|
|
90
|
+
askStartedAt,
|
|
91
|
+
earlierReport,
|
|
92
|
+
}) {
|
|
82
93
|
let releaseWorkspace;
|
|
83
94
|
try {
|
|
84
95
|
releaseWorkspace = await admitWorkspaceActivity(
|
|
@@ -98,6 +109,8 @@ async function runAskTurn({ sessionId, opened, input, askOpts, onToolCall, cwdOv
|
|
|
98
109
|
// them with what the model was told. Asked again for every user turn
|
|
99
110
|
// the ask runs, queued and background follow-ups included.
|
|
100
111
|
currentAgents: askOpts?.agentsNow?.(),
|
|
112
|
+
// The session runtime's in-memory settings (the file trails them).
|
|
113
|
+
agentConfig: askOpts?.agentConfig?.() || null,
|
|
101
114
|
});
|
|
102
115
|
const result = await runAskAgentLoop({
|
|
103
116
|
sessionId,
|
|
@@ -108,14 +121,19 @@ async function runAskTurn({ sessionId, opened, input, askOpts, onToolCall, cwdOv
|
|
|
108
121
|
onToolCall,
|
|
109
122
|
takeAssistantTranscriptMetadata: transcript.takeAssistant,
|
|
110
123
|
});
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
124
|
+
// The earlier turns of this ask relayed nothing (publishAskTurn relays
|
|
125
|
+
// only a turn no queued input follows): their reports lead this one's.
|
|
126
|
+
const terminalResultPreview = withEarlierReport(
|
|
127
|
+
await commitAskTurn({
|
|
128
|
+
sessionId,
|
|
129
|
+
opened,
|
|
130
|
+
prepared,
|
|
131
|
+
result,
|
|
132
|
+
rawTranscriptMeta: transcript.raw,
|
|
133
|
+
askStartedAt,
|
|
134
|
+
}),
|
|
135
|
+
earlierReport
|
|
136
|
+
);
|
|
119
137
|
const drained = publishAskTurn({
|
|
120
138
|
sessionId,
|
|
121
139
|
opened,
|
|
@@ -143,7 +161,8 @@ async function runAskTurn({ sessionId, opened, input, askOpts, onToolCall, cwdOv
|
|
|
143
161
|
askStartedAt,
|
|
144
162
|
});
|
|
145
163
|
reapTurnShellJobs(sessionId, opened.runtime);
|
|
146
|
-
|
|
164
|
+
// Queued work that fails still hands on the reports of the turns before it.
|
|
165
|
+
throw carryReportOnError(err, earlierReport);
|
|
147
166
|
} finally {
|
|
148
167
|
// The result is already published; this only holds the session lock until
|
|
149
168
|
// the reader lease is removed, so the next turn's admission follows it. A
|
|
@@ -255,21 +274,32 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
255
274
|
input.retryAttemptId = askOpts.retryAttemptId;
|
|
256
275
|
retryTurnId = null;
|
|
257
276
|
}
|
|
258
|
-
//
|
|
259
|
-
//
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
277
|
+
// The earlier turns of this ask relayed nothing (publishAskTurn relays
|
|
278
|
+
// only a turn no queued input follows): this turn failing before it
|
|
279
|
+
// runs (runAskTurn carries the report once it has) still hands them on.
|
|
280
|
+
const earlierReport = result ? turnReportText(result) : '';
|
|
281
|
+
let opened;
|
|
282
|
+
try {
|
|
283
|
+
// The previous turn's save has landed and this turn's base is on disk
|
|
284
|
+
// before the turn touches the session (one unsettled turn per session).
|
|
285
|
+
await settleTurnBase(sessionId, { recoverCheckpoint: firstTurn });
|
|
286
|
+
// Synchronous pre-await setup (must happen before any await so
|
|
287
|
+
// closeSession() can't interleave between load and registration).
|
|
288
|
+
const claimed = claimTurnRuntime({
|
|
289
|
+
sessionId,
|
|
290
|
+
askOpts,
|
|
291
|
+
emitStart: firstTurn,
|
|
292
|
+
});
|
|
293
|
+
warmTurn = noteTurnForCacheWarm(sessionId, claimed, input);
|
|
294
|
+
firstTurn = false;
|
|
295
|
+
askGeneration = claimed.askGeneration;
|
|
296
|
+
opened = {
|
|
297
|
+
...claimed,
|
|
298
|
+
...armTurnDurability({ sessionId, ...claimed, pendingEntries: input.pendingEntries }),
|
|
299
|
+
};
|
|
300
|
+
} catch (error) {
|
|
301
|
+
throw carryReportOnError(error, earlierReport);
|
|
302
|
+
}
|
|
273
303
|
// From here the turn's own unwind (ask-turn-failure) acks or releases
|
|
274
304
|
// its entries; the queue keeps owning only the not-yet-started ones.
|
|
275
305
|
queue.markStarted();
|
|
@@ -282,6 +312,7 @@ export async function askSession(sessionId, prompt, context, onToolCall, cwdOver
|
|
|
282
312
|
cwdOverride,
|
|
283
313
|
transcript,
|
|
284
314
|
askStartedAt,
|
|
315
|
+
earlierReport,
|
|
285
316
|
});
|
|
286
317
|
result = turn.result;
|
|
287
318
|
endCacheWarmTurn(sessionId, warmTurn);
|
|
@@ -50,19 +50,21 @@ export function turnStepAutoEffort(autoEffort, effortConfiguration) {
|
|
|
50
50
|
: null;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
// `config`: a session runtime's in-memory agent config (its file copy trails
|
|
54
|
+
// it by a debounce); other callers read the file.
|
|
55
|
+
export function autoEffortMode(config = null) {
|
|
54
56
|
if (process.env.MIXDOG_AUTO_EFFORT) return normalizeAutoEffortMode(process.env.MIXDOG_AUTO_EFFORT);
|
|
55
57
|
try {
|
|
56
|
-
return builtinFeatureActive(readSection('agent'), 'autoEffort') ? 'on' : 'off';
|
|
58
|
+
return builtinFeatureActive(config || readSection('agent'), 'autoEffort') ? 'on' : 'off';
|
|
57
59
|
} catch {
|
|
58
60
|
return 'off';
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
/** The global "Auto reasoning base" setting; absent or unreadable is medium. */
|
|
63
|
-
export function autoEffortBaseSetting() {
|
|
65
|
+
export function autoEffortBaseSetting(config = null) {
|
|
64
66
|
try {
|
|
65
|
-
return autoEffortBase(readSection('agent')?.autoEffortBase);
|
|
67
|
+
return autoEffortBase((config || readSection('agent'))?.autoEffortBase);
|
|
66
68
|
} catch {
|
|
67
69
|
return autoEffortBase(undefined);
|
|
68
70
|
}
|
|
@@ -99,8 +101,8 @@ function lastText(messages, role) {
|
|
|
99
101
|
* briefly (its first-use load is the longest wait): a missing, still-loading,
|
|
100
102
|
* or slow model yields null and the default effort.
|
|
101
103
|
*/
|
|
102
|
-
export async function resolveTurnAutoEffort({ sessionId, session, provider, input }) {
|
|
103
|
-
const mode = autoEffortMode();
|
|
104
|
+
export async function resolveTurnAutoEffort({ sessionId, session, provider, input, config = null }) {
|
|
105
|
+
const mode = autoEffortMode(config);
|
|
104
106
|
// promptSource marks runtime-injected turns (completion notices, queued work).
|
|
105
107
|
// Agent sessions are judged like any other: their spawn brief and later Lead
|
|
106
108
|
// `send` messages arrive as plain prompts.
|
|
@@ -113,7 +115,7 @@ export async function resolveTurnAutoEffort({ sessionId, session, provider, inpu
|
|
|
113
115
|
if (!turnEffortConfigurationMode(session, provider)) return null;
|
|
114
116
|
const chosen = String(session.effort || '').toLowerCase();
|
|
115
117
|
const options = effortOptionsFor(session.provider, autoEffortModel(session.provider, provider, session.model));
|
|
116
|
-
const setting = autoEffortBaseSetting();
|
|
118
|
+
const setting = autoEffortBaseSetting(config);
|
|
117
119
|
const base = clampAutoEffortBase({ base: setting, options }) ?? autoEffortBase(setting);
|
|
118
120
|
const record = {
|
|
119
121
|
at: new Date().toISOString(),
|
|
@@ -59,7 +59,13 @@ function retainedUserTurn(session, retained, transcriptMeta, currentAgents) {
|
|
|
59
59
|
},
|
|
60
60
|
currentAgents
|
|
61
61
|
);
|
|
62
|
-
|
|
62
|
+
const noticeRevision = retained.message.meta?.promptSettingsNoticeRevision;
|
|
63
|
+
return {
|
|
64
|
+
historyMessages,
|
|
65
|
+
userTurnMessage,
|
|
66
|
+
outgoing: [...historyMessages, userTurnMessage],
|
|
67
|
+
promptSettingsNotice: noticeRevision ? { revision: noticeRevision } : null,
|
|
68
|
+
};
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
// The turn's user message: the retained one of a retried failed turn, or a
|
|
@@ -147,7 +153,15 @@ function persistTurnPreflight(session, { turnToken, startedAt, checkpoint, askGe
|
|
|
147
153
|
|
|
148
154
|
/** Resolves the provider, builds the user turn and pre-commits it; returns
|
|
149
155
|
* what the loop and the commit need from this preparation. */
|
|
150
|
-
export async function prepareAskTurn({
|
|
156
|
+
export async function prepareAskTurn({
|
|
157
|
+
sessionId,
|
|
158
|
+
opened,
|
|
159
|
+
input,
|
|
160
|
+
cwdOverride,
|
|
161
|
+
transcriptMeta,
|
|
162
|
+
currentAgents,
|
|
163
|
+
agentConfig = null,
|
|
164
|
+
}) {
|
|
151
165
|
const { turn, runtime, turnSignal, askGeneration, checkpoint, turnToken, startedAt, codexTurnId } = opened;
|
|
152
166
|
const session = turn.session;
|
|
153
167
|
// Where the turn sits in a bot-to-bot chain (session-runtime/bot-hops.mjs).
|
|
@@ -167,7 +181,7 @@ export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, tr
|
|
|
167
181
|
// reads the session as the turn found it (synchronously, on this call).
|
|
168
182
|
// The first request still carries its decision: it is awaited below,
|
|
169
183
|
// together with the user turn, before the effort configuration is stamped.
|
|
170
|
-
const autoEffortPending = resolveTurnAutoEffort({ sessionId, session, provider, input });
|
|
184
|
+
const autoEffortPending = resolveTurnAutoEffort({ sessionId, session, provider, input, config: agentConfig });
|
|
171
185
|
autoEffortPending.catch(() => {});
|
|
172
186
|
applyTurnContextMeta(session, provider);
|
|
173
187
|
const effectiveCwd = cwdOverride || session.cwd;
|
|
@@ -206,6 +220,9 @@ export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, tr
|
|
|
206
220
|
if (effortConfiguration) stampTurnEffort(userTurn.userTurnMessage, effortConfiguration);
|
|
207
221
|
const { historyMessages, outgoing } = userTurn;
|
|
208
222
|
turn.userTurnContent = userTurn.userTurnMessage.content;
|
|
223
|
+
// The turn opens right after the history it was built on: its checkpoint
|
|
224
|
+
// boundary, never looked up again by the prompt's text.
|
|
225
|
+
turn.boundary = historyMessages.length;
|
|
209
226
|
turn.outgoing = outgoing;
|
|
210
227
|
precommitUserTurn(session, outgoing, historyMessages, input);
|
|
211
228
|
persistTurnPreflight(session, { turnToken, startedAt, checkpoint, askGeneration });
|
|
@@ -236,6 +253,7 @@ export async function prepareAskTurn({ sessionId, opened, input, cwdOverride, tr
|
|
|
236
253
|
deferredToolDelta: userTurn.deferredToolDelta,
|
|
237
254
|
goalReminder: userTurn.goalReminder,
|
|
238
255
|
workflowNotice: userTurn.workflowNotice,
|
|
256
|
+
promptSettingsNotice: userTurn.promptSettingsNotice,
|
|
239
257
|
orchestrationModeNotice: userTurn.orchestrationModeNotice,
|
|
240
258
|
workspaceNotice: userTurn.workspaceNotice,
|
|
241
259
|
setupNotice: userTurn.setupNotice,
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
} from './pending-messages.mjs';
|
|
17
17
|
import { _getRuntimeEntry, markSessionCancelled, markSessionError } from './runtime-liveness.mjs';
|
|
18
18
|
import { SessionClosedError } from './session-errors.mjs';
|
|
19
|
-
import {
|
|
19
|
+
import { holdTurnUntilDurable, turnCoveredOnDisk } from './turn-durability.mjs';
|
|
20
20
|
import { attachFailedTurnCompletion } from './ask-turn-settle.mjs';
|
|
21
21
|
import { turnFailureRecord } from '../turn-failure.mjs';
|
|
22
22
|
import { transcriptRouteMetadataFields } from '../../../../shared/transcript-metadata.mjs';
|
|
@@ -97,6 +97,17 @@ async function persistFinalizedSession({ session, sessionId, generation, pending
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
/** Keep the failed turn's checkpoint until a landed save covers its
|
|
101
|
+
* finalized transcript (turn-durability.mjs); returns the save issued for
|
|
102
|
+
* it, or null when an earlier one already landed it. */
|
|
103
|
+
function holdFinalizedTurn({ sessionId, session, turnToken, generation }) {
|
|
104
|
+
const save = turnCoveredOnDisk(session, turnToken)
|
|
105
|
+
? null
|
|
106
|
+
: saveSessionAsync(session, { expectedGeneration: generation });
|
|
107
|
+
holdTurnUntilDurable({ sessionId, session, turnToken, generation, save });
|
|
108
|
+
return save;
|
|
109
|
+
}
|
|
110
|
+
|
|
100
111
|
/** A SessionClosedError unwind: keeps the interruption snapshot unless the
|
|
101
112
|
* runtime already closed, in which case the consumed queue entries are
|
|
102
113
|
* released untouched. */
|
|
@@ -119,14 +130,14 @@ async function finalizeCancelledTurn({
|
|
|
119
130
|
if (currentRuntime?.prepareCloseSnapshot === prepareCloseSnapshot) {
|
|
120
131
|
currentRuntime.prepareCloseSnapshot = null;
|
|
121
132
|
}
|
|
122
|
-
|
|
133
|
+
await persistFinalizedSession({
|
|
123
134
|
session,
|
|
124
135
|
sessionId,
|
|
125
136
|
generation,
|
|
126
137
|
pendingEntries: turn.pendingEntries,
|
|
127
138
|
promptSurvived: finalized.responsePreserved,
|
|
128
139
|
});
|
|
129
|
-
|
|
140
|
+
holdFinalizedTurn({ sessionId, session, turnToken: turnCheckpointToken, generation });
|
|
130
141
|
if (currentRuntime) currentRuntime.session = session;
|
|
131
142
|
markSessionCancelled(sessionId);
|
|
132
143
|
}
|
|
@@ -169,6 +180,9 @@ export async function finalizeAskTurnFailure({
|
|
|
169
180
|
if (session) {
|
|
170
181
|
session.liveTurnMessages = null;
|
|
171
182
|
delete session.activeTurnCheckpoint;
|
|
183
|
+
// Every record saved from here on carries this turn as finalized: a
|
|
184
|
+
// crash after one lands deletes the checkpoint instead of replaying it.
|
|
185
|
+
session.turnCoverage = turnCheckpointToken;
|
|
172
186
|
// The provider prefix snapshot commits per successful send INSIDE the
|
|
173
187
|
// turn, while the transcript unwinds to its pre-turn/finalized shape
|
|
174
188
|
// below. A surviving mid-turn snapshot flags every retry as
|
|
@@ -206,7 +220,8 @@ export async function finalizeAskTurnFailure({
|
|
|
206
220
|
// contract answers "did the provider produce output we must commit?" for
|
|
207
221
|
// every transport. Anthropic's stall/truncation errors carry neither
|
|
208
222
|
// liveTextEmitted nor unsafeToRetry — only partialContent/partialToolCalls
|
|
209
|
-
// —
|
|
223
|
+
// — so consulting the flags would drop the streamed summary from history on
|
|
224
|
+
// that provider.
|
|
210
225
|
const providerOutcome = readStreamOutcome(err);
|
|
211
226
|
const preserveProviderPartial =
|
|
212
227
|
restoredResetText ||
|
|
@@ -252,15 +267,16 @@ export async function finalizeAskTurnFailure({
|
|
|
252
267
|
releasePendingMessages(sessionId, turn.pendingEntries);
|
|
253
268
|
}
|
|
254
269
|
}
|
|
255
|
-
if (
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
270
|
+
if (session) {
|
|
271
|
+
const save = holdFinalizedTurn({ sessionId, session, turnToken: turnCheckpointToken, generation });
|
|
272
|
+
if (save && !errorStateDurable) {
|
|
273
|
+
try {
|
|
274
|
+
await settleAskCleanup(save);
|
|
275
|
+
} catch {
|
|
276
|
+
/* the checkpoint stays until a save covering the turn lands */
|
|
277
|
+
}
|
|
261
278
|
}
|
|
262
279
|
}
|
|
263
|
-
if (errorStateDurable) clearTurnCheckpoint(sessionId, turnCheckpointToken);
|
|
264
280
|
logAskError(sessionId, err, providerOutcome);
|
|
265
281
|
markSessionError(sessionId, err?.message ? err.message : String(err));
|
|
266
282
|
}
|
|
@@ -1,25 +1,50 @@
|
|
|
1
1
|
// manager/ask-turn-open.mjs
|
|
2
|
-
// Opening one turn:
|
|
2
|
+
// Opening one turn: settle the previous turn's durability and the durable
|
|
3
|
+
// base this turn opens on (settleTurnBase, awaited before anything below),
|
|
4
|
+
// load and reconcile the stored session and claim the
|
|
3
5
|
// runtime entry with a fresh abort controller (claimTurnRuntime), then arm
|
|
4
6
|
// the turn's durability — the crash-checkpoint scheduler and the close
|
|
5
7
|
// snapshot hook (armTurnDurability). Both are synchronous so closeSession()
|
|
6
8
|
// cannot interleave between load and registration.
|
|
7
9
|
import { randomUUID } from 'node:crypto';
|
|
8
|
-
import { loadSession
|
|
10
|
+
import { loadSession } from '../store.mjs';
|
|
11
|
+
import { durableTranscriptBase } from '../store/transcript-durability.mjs';
|
|
9
12
|
import { createAbortController } from '../../../../shared/abort-controller.mjs';
|
|
10
13
|
import { normalizeStaleCompactingStage } from './compaction-runner.mjs';
|
|
11
14
|
import { linkParentSignalToSession, markSessionAskStart, _touchRuntime } from './runtime-liveness.mjs';
|
|
12
15
|
import { SessionClosedError } from './session-errors.mjs';
|
|
13
16
|
import { ensureCodexWireSessionId, mintUuidV7 } from './session-id.mjs';
|
|
14
17
|
import { createTurnInterruptionTracker } from './turn-interruption.mjs';
|
|
15
|
-
import {
|
|
18
|
+
import { _recoverTurnCheckpointDurably, setAsideUnrecoveredCheckpoint } from './turn-checkpoint-recovery.mjs';
|
|
19
|
+
import { adoptDiskGeneration, awaitPreviousTurnDurable, ensureDurableTranscript } from './turn-durability.mjs';
|
|
16
20
|
import { emitAskSessionStart } from './ask-support.mjs';
|
|
21
|
+
import { applyHeldSessionRoute } from './session-lifecycle.mjs';
|
|
17
22
|
import { createAskTurnState, createCloseSnapshot, createTurnCheckpointScheduler } from './ask-turn-state.mjs';
|
|
18
23
|
|
|
24
|
+
/** Before a turn claims the session: the previous turn's finalized
|
|
25
|
+
* transcript is durably saved (its checkpoint deleted only then), a crashed
|
|
26
|
+
* turn's checkpoint is recovered (`recoverCheckpoint`, once per ask), and
|
|
27
|
+
* the transcript the turn opens on is the one a landed save holds — so the
|
|
28
|
+
* new checkpoint names a base that is on disk. Throws TurnPersistenceError
|
|
29
|
+
* when a save does not land; other sessions never wait on this one. */
|
|
30
|
+
export async function settleTurnBase(sessionId, { recoverCheckpoint }) {
|
|
31
|
+
await awaitPreviousTurnDurable(sessionId);
|
|
32
|
+
const session = loadSession(sessionId);
|
|
33
|
+
// claimTurnRuntime reports a missing or closed session.
|
|
34
|
+
if (!session || session.closed === true) return;
|
|
35
|
+
adoptDiskGeneration(session, sessionId);
|
|
36
|
+
if (recoverCheckpoint) _recoverTurnCheckpointDurably(session, sessionId);
|
|
37
|
+
await ensureDurableTranscript(session);
|
|
38
|
+
// This turn's checkpoint replaces the session's checkpoint file. Whatever
|
|
39
|
+
// is still there (a conflict, an unreadable header, a crashed turn this
|
|
40
|
+
// ask did not recover) is set aside first, never overwritten.
|
|
41
|
+
setAsideUnrecoveredCheckpoint(session, sessionId);
|
|
42
|
+
}
|
|
43
|
+
|
|
19
44
|
/** Loads the session for a new turn and reconciles its on-disk lifecycle:
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
function loadTurnSession(sessionId
|
|
45
|
+
* a stale compacting stage and split-brain re-adoption of a disk generation
|
|
46
|
+
* another surface bumped. */
|
|
47
|
+
function loadTurnSession(sessionId) {
|
|
23
48
|
const session = loadSession(sessionId);
|
|
24
49
|
if (!session) {
|
|
25
50
|
throw new Error(`Session "${sessionId}" not found`);
|
|
@@ -28,44 +53,21 @@ function loadTurnSession(sessionId, { recoverCheckpoint }) {
|
|
|
28
53
|
throw new SessionClosedError(sessionId, 'session already closed');
|
|
29
54
|
}
|
|
30
55
|
const codexWireSessionId = ensureCodexWireSessionId(session);
|
|
31
|
-
if (recoverCheckpoint) {
|
|
32
|
-
const recovery = recoverTurnCheckpoint(session);
|
|
33
|
-
if (recovery.changed) {
|
|
34
|
-
saveSession(session, {
|
|
35
|
-
sync: true,
|
|
36
|
-
expectedGeneration: session.generation,
|
|
37
|
-
});
|
|
38
|
-
if (recovery.turnToken) clearTurnCheckpoint(sessionId, recovery.turnToken);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
56
|
// A prior crash/partial-save during compaction may have pinned
|
|
42
57
|
// compaction.lastStage='compacting'. This ask is starting fresh, so
|
|
43
58
|
// recover the stale transient stage before the loop's pre-send compact
|
|
44
59
|
// path runs (it will overwrite lastStage with real telemetry).
|
|
45
60
|
normalizeStaleCompactingStage(session);
|
|
46
|
-
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
// while the conversation kept going here. Every save from this process
|
|
50
|
-
// would then be silently dropped by _shouldDrop's ownership rule and
|
|
51
|
-
// the on-disk transcript would freeze at the last landed save. A new
|
|
52
|
-
// ask on a NON-closed session is an explicit ownership claim: adopt
|
|
53
|
-
// the disk generation so this turn's commits land and heal the file.
|
|
54
|
-
const diskLifecycle = readSessionLifecycleFromDisk(sessionId);
|
|
55
|
-
if (
|
|
56
|
-
diskLifecycle &&
|
|
57
|
-
diskLifecycle.closed !== true &&
|
|
58
|
-
diskLifecycle.generation > (typeof session.generation === 'number' ? session.generation : 0)
|
|
59
|
-
) {
|
|
60
|
-
session.generation = diskLifecycle.generation;
|
|
61
|
-
}
|
|
61
|
+
adoptDiskGeneration(session, sessionId);
|
|
62
|
+
// A route saved while the previous turn ran applies from this turn.
|
|
63
|
+
applyHeldSessionRoute(session);
|
|
62
64
|
return { session, codexWireSessionId };
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
/** Loads the session and installs this turn's controller on the runtime
|
|
66
68
|
* entry, re-cascading any parent abort link and marking the ask started. */
|
|
67
|
-
export function claimTurnRuntime({ sessionId, askOpts,
|
|
68
|
-
const { session: preSession, codexWireSessionId } = loadTurnSession(sessionId
|
|
69
|
+
export function claimTurnRuntime({ sessionId, askOpts, emitStart }) {
|
|
70
|
+
const { session: preSession, codexWireSessionId } = loadTurnSession(sessionId);
|
|
69
71
|
const askGeneration = typeof preSession.generation === 'number' ? preSession.generation : 0;
|
|
70
72
|
const runtime = _touchRuntime(sessionId);
|
|
71
73
|
// Preserve any parent-abort link agent-dispatch established BEFORE we
|
|
@@ -121,6 +123,7 @@ export function armTurnDurability({
|
|
|
121
123
|
startedAt,
|
|
122
124
|
turn,
|
|
123
125
|
interruption,
|
|
126
|
+
base: durableTranscriptBase(preSession),
|
|
124
127
|
});
|
|
125
128
|
const prepareCloseSnapshot = createCloseSnapshot({ turn, interruption, checkpoint, runtime });
|
|
126
129
|
// closeSession is synchronous and generation-first by design. Expose a
|
|
@@ -9,6 +9,7 @@ import { positiveInt } from '../../../../shared/numbers.mjs';
|
|
|
9
9
|
import { appendAgentTrace } from '../../agent-trace.mjs';
|
|
10
10
|
import { snapshotPendingDeferredToolDelta } from '../../runtime-core/deferred-tool-delta.mjs';
|
|
11
11
|
import { snapshotPendingGoalReminder } from '../../runtime-core/goal-reminder.mjs';
|
|
12
|
+
import { beginTodoTurn, todoStartReminder } from '../loop/no-tool-turn/todo-check.mjs';
|
|
12
13
|
import { resolveSessionContextMeta } from './context-meta.mjs';
|
|
13
14
|
import {
|
|
14
15
|
promptContentText,
|
|
@@ -20,6 +21,7 @@ import {
|
|
|
20
21
|
snapshotPendingSetupNotice,
|
|
21
22
|
} from './prompt-utils.mjs';
|
|
22
23
|
import { snapshotPendingWorkflowNotice } from './workflow-switch-notice.mjs';
|
|
24
|
+
import { snapshotPendingPromptSettingsNotice } from './prompt-settings.mjs';
|
|
23
25
|
import { snapshotPendingOrchestrationModeNotice } from './orchestration-mode-switch-notice.mjs';
|
|
24
26
|
import { buildAgentListingNotice } from './agent-listing-notice.mjs';
|
|
25
27
|
import { codexWireSendOpts } from './session-id.mjs';
|
|
@@ -175,6 +177,12 @@ export async function buildUserTurn({
|
|
|
175
177
|
}
|
|
176
178
|
const currentTimeBlock = buildCurrentTimeBlock(prompt);
|
|
177
179
|
const deferredToolDelta = snapshotPendingDeferredToolDelta(session);
|
|
180
|
+
// A real prompt (no runtime source: not a Goal turn or task notification)
|
|
181
|
+
// opens a new todo reminder cycle; every turn clears the last turn's waits.
|
|
182
|
+
const genuinePrompt = !turnPromptSource?.source;
|
|
183
|
+
beginTodoTurn(session, { genuine: genuinePrompt });
|
|
184
|
+
// An agent's new brief or follow-up with no open list asks for one, once.
|
|
185
|
+
const todoStart = genuinePrompt ? todoStartReminder(session) : null;
|
|
178
186
|
// Read paused state after hydration and queue selection, not at
|
|
179
187
|
// input intake: either can precede the previous turn's pause.
|
|
180
188
|
// This supplies context only; it never resumes the Goal.
|
|
@@ -192,8 +200,11 @@ export async function buildUserTurn({
|
|
|
192
200
|
const orchestrationModeNotice = snapshotPendingOrchestrationModeNotice(session);
|
|
193
201
|
// Agents enabled or switched off since the conversation was last told.
|
|
194
202
|
const agentListingNotice = buildAgentListingNotice(session, currentAgents);
|
|
203
|
+
// Prompt-shaping settings changed since the prompt was built (told once).
|
|
204
|
+
const promptSettingsNotice = snapshotPendingPromptSettingsNotice(session);
|
|
195
205
|
const reminderBlock = [
|
|
196
206
|
workflowNotice?.content || '',
|
|
207
|
+
promptSettingsNotice?.content || '',
|
|
197
208
|
orchestrationModeNotice?.content || '',
|
|
198
209
|
agentListingNotice?.content || '',
|
|
199
210
|
workspaceNotice?.content || '',
|
|
@@ -201,6 +212,7 @@ export async function buildUserTurn({
|
|
|
201
212
|
currentTimeBlock ? `<system-reminder>\n# Current Time\n${currentTimeBlock}\n</system-reminder>` : '',
|
|
202
213
|
deferredToolDelta?.content || '',
|
|
203
214
|
goalReminder?.content || '',
|
|
215
|
+
todoStart || '',
|
|
204
216
|
]
|
|
205
217
|
.filter(Boolean)
|
|
206
218
|
.join('\n\n');
|
|
@@ -212,6 +224,8 @@ export async function buildUserTurn({
|
|
|
212
224
|
...(effortConfiguration ? { effortConfiguration } : {}),
|
|
213
225
|
// What its reminder told, read back by later turns (agent-listing-notice.mjs).
|
|
214
226
|
...(agentListingNotice ? { agentListing: agentListingNotice.meta } : {}),
|
|
227
|
+
// A retry resubmits this message as is: it acknowledges the same notice.
|
|
228
|
+
...(promptSettingsNotice ? { promptSettingsNoticeRevision: promptSettingsNotice.revision } : {}),
|
|
215
229
|
};
|
|
216
230
|
const userTurnMessage = withRuntimeUserContext(
|
|
217
231
|
{
|
|
@@ -228,6 +242,7 @@ export async function buildUserTurn({
|
|
|
228
242
|
goalReminder,
|
|
229
243
|
workflowNotice,
|
|
230
244
|
orchestrationModeNotice,
|
|
245
|
+
promptSettingsNotice,
|
|
231
246
|
agentListingNotice,
|
|
232
247
|
workspaceNotice,
|
|
233
248
|
setupNotice,
|
|
@@ -10,6 +10,7 @@ import { acknowledgePendingDeferredToolDelta } from '../../runtime-core/deferred
|
|
|
10
10
|
import { acknowledgePendingGoalReminder } from '../../runtime-core/goal-reminder.mjs';
|
|
11
11
|
import { acknowledgePendingSetupNotice, acknowledgePendingWorkspaceNotice } from './prompt-utils.mjs';
|
|
12
12
|
import { acknowledgePendingWorkflowNotice } from './workflow-switch-notice.mjs';
|
|
13
|
+
import { acknowledgePendingPromptSettingsNotice } from './prompt-settings.mjs';
|
|
13
14
|
import { acknowledgePendingOrchestrationModeNotice } from './orchestration-mode-switch-notice.mjs';
|
|
14
15
|
import {
|
|
15
16
|
finalizePendingMessageDelivery,
|
|
@@ -20,7 +21,7 @@ import { applyAskTerminalUsageTotals } from './usage-metrics.mjs';
|
|
|
20
21
|
import { markSessionDone, markSessionEmptyFinal, _getRuntimeEntry } from './runtime-liveness.mjs';
|
|
21
22
|
import { SessionClosedError } from './session-errors.mjs';
|
|
22
23
|
import { filterModelVisibleSessionMessages } from './message-sanitize.mjs';
|
|
23
|
-
import {
|
|
24
|
+
import { holdTurnUntilDurable } from './turn-durability.mjs';
|
|
24
25
|
import { recordProviderContextBaseline } from '../loop/compact-policy.mjs';
|
|
25
26
|
import { throwIfAborted } from '../../../../shared/abort-race.mjs';
|
|
26
27
|
import { appendAssistantTurnMessage, persistProviderState, recordAskUsage } from './ask-turn-commit.mjs';
|
|
@@ -94,7 +95,7 @@ export function attachFailedTurnCompletion(messages, completion) {
|
|
|
94
95
|
/** Commits the loop result into the session: messages, usage, provider state
|
|
95
96
|
* and queue acknowledgements. Returns the terminal result preview. */
|
|
96
97
|
export async function commitAskTurn({ sessionId, opened, prepared, result, rawTranscriptMeta, askStartedAt }) {
|
|
97
|
-
const { turn, runtime, turnSignal, askGeneration,
|
|
98
|
+
const { turn, runtime, turnSignal, askGeneration, prepareCloseSnapshot } = opened;
|
|
98
99
|
const session = turn.session;
|
|
99
100
|
throwIfAborted(turnSignal);
|
|
100
101
|
// Post-loop validation: if closeSession() landed while we were awaiting,
|
|
@@ -111,7 +112,8 @@ export async function commitAskTurn({ sessionId, opened, prepared, result, rawTr
|
|
|
111
112
|
// Turn committed into session.messages; drop the live-turn alias so
|
|
112
113
|
// contextStatus() reverts to the authoritative committed transcript.
|
|
113
114
|
session.liveTurnMessages = null;
|
|
114
|
-
checkpoint
|
|
115
|
+
// The checkpoint keeps recording until publishAskTurn seals the finished
|
|
116
|
+
// transcript into it.
|
|
115
117
|
delete session.activeTurnCheckpoint;
|
|
116
118
|
appendAssistantTurnMessage({
|
|
117
119
|
session,
|
|
@@ -142,6 +144,9 @@ export async function commitAskTurn({ sessionId, opened, prepared, result, rawTr
|
|
|
142
144
|
acknowledgePendingGoalReminder(session, prepared.goalReminder.revision);
|
|
143
145
|
}
|
|
144
146
|
if (prepared.workflowNotice) acknowledgePendingWorkflowNotice(session, prepared.workflowNotice.revision);
|
|
147
|
+
if (prepared.promptSettingsNotice) {
|
|
148
|
+
acknowledgePendingPromptSettingsNotice(session, prepared.promptSettingsNotice.revision);
|
|
149
|
+
}
|
|
145
150
|
if (prepared.orchestrationModeNotice) {
|
|
146
151
|
acknowledgePendingOrchestrationModeNotice(session, prepared.orchestrationModeNotice.revision);
|
|
147
152
|
}
|
|
@@ -160,7 +165,7 @@ export async function commitAskTurn({ sessionId, opened, prepared, result, rawTr
|
|
|
160
165
|
* starts the durable save and marks the session done. Returns the
|
|
161
166
|
* follow-up entries drained right after the provider accepted the turn. */
|
|
162
167
|
export function publishAskTurn({ sessionId, opened, terminalResultPreview, askOpts, rawTranscriptMeta, askStartedAt }) {
|
|
163
|
-
const { turn, runtime, askGeneration, turnToken } = opened;
|
|
168
|
+
const { turn, runtime, askGeneration, turnToken, checkpoint } = opened;
|
|
164
169
|
const session = turn.session;
|
|
165
170
|
// The provider accepted this queued turn: only now remove its
|
|
166
171
|
// durable ids. A crash before here leaves them for at-least-once
|
|
@@ -197,19 +202,23 @@ export function publishAskTurn({ sessionId, opened, terminalResultPreview, askOp
|
|
|
197
202
|
// query/provider send (agentLoop pre-send), not after the previous
|
|
198
203
|
// answer. This lets queued follow-up prompts resume immediately;
|
|
199
204
|
// if they need compaction, their own spinner shows compacting first.
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
|
|
205
|
+
// The finished transcript (final assistant message, completion) is sealed
|
|
206
|
+
// into the checkpoint, and the record the terminal save writes names the
|
|
207
|
+
// turn it covers: a crash before that save lands replays the sealed turn,
|
|
208
|
+
// one after it deletes the checkpoint without a duplicate.
|
|
209
|
+
session.turnCoverage = turnToken;
|
|
210
|
+
checkpoint.seal();
|
|
211
|
+
// Terminal save. The result is already produced and (for agent surfaces)
|
|
212
|
+
// relayed via onTerminalResult above. When completion was relayed to the
|
|
213
|
+
// UI, yield before postMessage structured-clones the full session. Queued
|
|
214
|
+
// follow-up turns retain the original immediate-save ordering. Its landed
|
|
215
|
+
// acknowledgement is this session's next-turn gate (turn-durability.mjs),
|
|
216
|
+
// which alone deletes the checkpoint.
|
|
206
217
|
const saveTerminalSession = terminalRelayed ? saveSessionAsyncDeferred : saveSessionAsync;
|
|
207
218
|
const terminalSave = saveTerminalSession(session, { expectedGeneration: askGeneration });
|
|
219
|
+
holdTurnUntilDurable({ sessionId, session, turnToken, generation: askGeneration, save: terminalSave });
|
|
208
220
|
terminalSave.then(
|
|
209
|
-
() =>
|
|
210
|
-
clearTurnCheckpoint(sessionId, turnToken);
|
|
211
|
-
ingestSessionTurn(session);
|
|
212
|
-
},
|
|
221
|
+
() => ingestSessionTurn(session),
|
|
213
222
|
() => {}
|
|
214
223
|
);
|
|
215
224
|
finalizePendingMessageDelivery(session, turn.pendingEntries, terminalSave, () =>
|
|
@@ -227,7 +236,8 @@ export function publishAskTurn({ sessionId, opened, terminalResultPreview, askOp
|
|
|
227
236
|
const isEmptyFinal =
|
|
228
237
|
!terminalResultPreview.content &&
|
|
229
238
|
!terminalResultPreview.reasoningContent &&
|
|
230
|
-
!terminalResultPreview.reactionCompleted
|
|
239
|
+
!terminalResultPreview.reactionCompleted &&
|
|
240
|
+
!terminalResultPreview.reportContent;
|
|
231
241
|
if (isEmptyFinal) {
|
|
232
242
|
markSessionEmptyFinal(sessionId);
|
|
233
243
|
}
|