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
|
@@ -61,8 +61,20 @@ export function createWorktreeSetup({ backend, newTxId, planWorktreeSetup, runWo
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
};
|
|
64
|
+
if (claimed.blocked?.length) {
|
|
65
|
+
report.notes.push(
|
|
66
|
+
`Dependencies were not installed: ${claimed.blocked.join(', ')} ${claimed.blocked.length > 1 ? 'are links' : 'is a link'}, and any install here could empty the folder it points at (such as the main checkout's) through it. Remove the link (never its target); the next turn installs.`
|
|
67
|
+
);
|
|
68
|
+
session.pendingSetupNotice = { revision: Date.now(), content: worktreePreparationNote(report) };
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
64
71
|
try {
|
|
65
|
-
const plan = await planWorktreeSetup({
|
|
72
|
+
const plan = await planWorktreeSetup({
|
|
73
|
+
worktreeDir: here.cwd,
|
|
74
|
+
mainDir: here.projectPath,
|
|
75
|
+
shared: claimed.shared ?? [],
|
|
76
|
+
signal,
|
|
77
|
+
});
|
|
66
78
|
report.dependencyNotes = plan.notes;
|
|
67
79
|
if (plan.commands.length) {
|
|
68
80
|
report.installs = await runWorktreeSetup({ commands: plan.commands, signal, onProgress: emit });
|
|
@@ -147,6 +147,11 @@ export function createWorktreeToolHost({ getSession, getWorkspaceApi, executeSes
|
|
|
147
147
|
}
|
|
148
148
|
const lane = laneFor(entry.ownerSessionId, callerSessionId, scope);
|
|
149
149
|
const menu = await lane.menu();
|
|
150
|
+
// This session's worktree that it does not work in: removed where it is,
|
|
151
|
+
// without entering it (its own running workers elsewhere never block that).
|
|
152
|
+
if (lane.own && menu.workspace?.worktreeId !== entry.id) {
|
|
153
|
+
return workspaceApi().removeOwnedWorktree({ entryId: entry.id, force: request.force === true });
|
|
154
|
+
}
|
|
150
155
|
if (menu.retainedWorktree?.id !== entry.id) {
|
|
151
156
|
throw new Error(
|
|
152
157
|
`git worktree remove: ${entry.path} is not the current worktree of session ${entry.ownerSessionId}; enter it (worktree_action enter, branch ${entry.branch}) first, then remove it`
|
|
@@ -174,6 +179,17 @@ export function createWorktreeToolHost({ getSession, getWorkspaceApi, executeSes
|
|
|
174
179
|
return merge(lane());
|
|
175
180
|
case 'remove': {
|
|
176
181
|
const force = request.force === true;
|
|
182
|
+
if (request.branch) {
|
|
183
|
+
// By branch: the managed worktree of that branch this session owns.
|
|
184
|
+
const rows = await workspaceApi().listWorktrees();
|
|
185
|
+
const row = rows.find((item) => item.branch === request.branch && item.ownerSessionId === callerSessionId);
|
|
186
|
+
if (!row) {
|
|
187
|
+
throw new Error(
|
|
188
|
+
`git worktree remove: this session owns no managed worktree of branch ${request.branch}; git worktree list shows them`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
return removePath({ path: row.path, force }, callerSessionId, scope);
|
|
192
|
+
}
|
|
177
193
|
if (request.sessionId && request.sessionId !== callerSessionId) {
|
|
178
194
|
const gone = await orphan((row) => row.ownerSessionId === request.sessionId);
|
|
179
195
|
if (gone) return workspaceApi().removeOrphanWorktree({ entryId: gone.id, force });
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
//
|
|
7
7
|
// Inputs: `getSessionService` / `getSessionRuntimeHost` (both are wired after
|
|
8
8
|
// this control exists — the host takes `execute` as a constructor option), and
|
|
9
|
-
// `cwd`. Output: { canonicalAgentTool, execute }.
|
|
9
|
+
// `cwd`. Output: { canonicalAgentTool, execute, runForeground, dispose }.
|
|
10
10
|
|
|
11
11
|
export function createCanonicalAgentControl({ getSessionService, getSessionRuntimeHost, cwd }) {
|
|
12
12
|
let canonicalAgentToolPromise = null;
|
|
@@ -43,16 +43,33 @@ export function createCanonicalAgentControl({ getSessionService, getSessionRunti
|
|
|
43
43
|
return canonicalAgentToolPromise;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
/** `context` rooted at its caller session (agent-tool: the owner is the caller's root). */
|
|
47
|
+
async function scopeContext(context) {
|
|
48
48
|
const sessionService = getSessionService();
|
|
49
49
|
const parentSessionId = String(context?.callerSessionId || '').trim();
|
|
50
50
|
await sessionService.rehydrateAgentSessions();
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
return {
|
|
52
|
+
parentSessionId,
|
|
53
|
+
sessionService,
|
|
54
|
+
scopedContext: {
|
|
55
|
+
...context,
|
|
56
|
+
callerSessionId: parentSessionId || null,
|
|
57
|
+
ownerSessionId: sessionService.rootOwnerSessionId(parentSessionId),
|
|
58
|
+
},
|
|
55
59
|
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** One agent run to its end for a caller with no session to hand it to
|
|
63
|
+
* (routine-executor.mjs): resolves `{ sessionId, content }`. */
|
|
64
|
+
async function runForeground(args = {}, context = {}, options = {}) {
|
|
65
|
+
const tool = await canonicalAgentTool();
|
|
66
|
+
const { scopedContext } = await scopeContext(context);
|
|
67
|
+
return await tool.runToCompletion(args, scopedContext, options);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function execute(args = {}, context = {}) {
|
|
71
|
+
const tool = await canonicalAgentTool();
|
|
72
|
+
const { parentSessionId, sessionService, scopedContext } = await scopeContext(context);
|
|
56
73
|
if (String(args?.type || '') === '__close_all') {
|
|
57
74
|
await tool.closeAll?.(String(args?.reason || 'agent owner closed'), {
|
|
58
75
|
callerSessionId: parentSessionId || null,
|
|
@@ -72,5 +89,5 @@ export function createCanonicalAgentControl({ getSessionService, getSessionRunti
|
|
|
72
89
|
await tool?.disposeAsync?.({ settle: true });
|
|
73
90
|
}
|
|
74
91
|
|
|
75
|
-
return { canonicalAgentTool, execute, dispose };
|
|
92
|
+
return { canonicalAgentTool, execute, runForeground, dispose };
|
|
76
93
|
}
|
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
* this daemon's in-memory turn activity (every session runs inline here, so
|
|
13
13
|
* it is the single source of truth; worker index files only declare work). */
|
|
14
14
|
async function loadSessionStoreWithRuntimeActivity() {
|
|
15
|
-
const [store, runtime, progress, tasks] = await Promise.all([
|
|
15
|
+
const [store, runtime, progress, tasks, liveState] = await Promise.all([
|
|
16
16
|
import('../runtime/agent/orchestrator/session/store-summary-reader.mjs'),
|
|
17
17
|
// The import-free leaf holding the runtime map: no session manager graph.
|
|
18
18
|
import('../runtime/agent/orchestrator/session/manager/runtime-state.mjs'),
|
|
19
19
|
import('../runtime/agent/orchestrator/session/agent-pool-progress.mjs'),
|
|
20
20
|
import('../runtime/shared/background-tasks.mjs'),
|
|
21
|
+
import('../runtime/agent/orchestrator/session/store/live-state.mjs'),
|
|
21
22
|
]);
|
|
22
23
|
return {
|
|
23
24
|
...store,
|
|
@@ -33,7 +34,10 @@ async function loadSessionStoreWithRuntimeActivity() {
|
|
|
33
34
|
});
|
|
34
35
|
const awaiting = tasks.activeBackgroundTaskSessionIds({ surface: 'shell', awaitedOnly: true });
|
|
35
36
|
return progress.withTurnProgress(
|
|
36
|
-
|
|
37
|
+
progress.withLiveUsage(
|
|
38
|
+
progress.withLiveTodo(rows, (sessionId) => liveState._liveSessions.get(sessionId)),
|
|
39
|
+
(sessionId) => liveState._liveSessions.get(sessionId)
|
|
40
|
+
),
|
|
37
41
|
(sessionId) => runtime.runtimeState.get(sessionId),
|
|
38
42
|
runtime.isTurnInFlight,
|
|
39
43
|
(sessionId) => awaiting.has(sessionId)
|
|
@@ -15,14 +15,14 @@ import path from 'node:path';
|
|
|
15
15
|
import { fileURLToPath } from 'node:url';
|
|
16
16
|
|
|
17
17
|
export const LAG_PROFILE_FLAG_FILE = 'lag-profile.on';
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const LAG_PROFILE_DIR_NAME = 'profiles';
|
|
19
|
+
const LAG_PROFILE_KEEP = 10;
|
|
20
|
+
const LAG_PROFILE_TOP = 15;
|
|
21
21
|
export const LAG_PROFILE_SAMPLING_US = 1000;
|
|
22
|
-
|
|
22
|
+
const LAG_P99_THRESHOLD_MS = 1000;
|
|
23
23
|
// The owner lease's stall threshold: any window holding one logged
|
|
24
24
|
// `event loop stalled` line is kept.
|
|
25
|
-
|
|
25
|
+
const LAG_MAX_THRESHOLD_MS = 1000;
|
|
26
26
|
|
|
27
27
|
const PROFILE_FILE_RE = /^daemon-lag-.+\.cpuprofile$/;
|
|
28
28
|
const SRC_ROOT = fileURLToPath(new URL('..', import.meta.url));
|
|
@@ -90,12 +90,12 @@ export function summarizeCpuProfile(profile, { limit = LAG_PROFILE_TOP, srcRoot
|
|
|
90
90
|
.slice(0, limit);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
function formatTopEntries(entries) {
|
|
94
94
|
return entries.map((entry) => `${entry.label}=${Math.round(entry.ms)}ms`).join(',');
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
/** Keep only the `keep` newest daemon-lag profiles (names sort by timestamp). */
|
|
98
|
-
|
|
98
|
+
async function pruneProfiles(dir, keep = LAG_PROFILE_KEEP) {
|
|
99
99
|
const names = (await fsp.readdir(dir)).filter((name) => PROFILE_FILE_RE.test(name)).sort();
|
|
100
100
|
const stale = names.slice(0, Math.max(0, names.length - keep));
|
|
101
101
|
for (const name of stale) await fsp.rm(path.join(dir, name), { force: true });
|
|
@@ -841,6 +841,50 @@ async function startChannelFrontDoor({ channelsRuntime, bootPhases }) {
|
|
|
841
841
|
return bootPhases.measure('channel-transport-start', () => transport.start());
|
|
842
842
|
}
|
|
843
843
|
|
|
844
|
+
async function startDaemonMaintenance() {
|
|
845
|
+
const [schedule, liveness, { IN_FLIGHT_STAGES }] = await Promise.all([
|
|
846
|
+
import('../runtime/shared/maintenance-schedule.mjs'),
|
|
847
|
+
import('../runtime/agent/orchestrator/session/manager/runtime-liveness.mjs'),
|
|
848
|
+
import('../runtime/agent/orchestrator/session/manager/runtime-state.mjs'),
|
|
849
|
+
]);
|
|
850
|
+
const entries = () => [...liveness._runtimeEntries()];
|
|
851
|
+
schedule.registerMaintenanceIdleProbe(
|
|
852
|
+
() =>
|
|
853
|
+
!entries().some(
|
|
854
|
+
([, entry]) => (entry?.controller && !entry.controller.signal?.aborted) || IN_FLIGHT_STAGES.has(entry?.stage)
|
|
855
|
+
)
|
|
856
|
+
);
|
|
857
|
+
schedule.registerMaintenanceTask(
|
|
858
|
+
'worktree-cleanup',
|
|
859
|
+
async () => {
|
|
860
|
+
const maintenance = await import('../runtime/shared/worktrees/maintenance.mjs');
|
|
861
|
+
// Every session with an open runtime entry here counts as live, read
|
|
862
|
+
// again right before each removal (one that opened meanwhile keeps its folder).
|
|
863
|
+
const liveSessionIds = () =>
|
|
864
|
+
entries()
|
|
865
|
+
.filter(([, entry]) => entry && entry.closed !== true)
|
|
866
|
+
.map(([id]) => id);
|
|
867
|
+
const report = await maintenance.runWorktreeCleanup({
|
|
868
|
+
liveSessionIds: liveSessionIds(),
|
|
869
|
+
currentLiveSessionIds: liveSessionIds,
|
|
870
|
+
});
|
|
871
|
+
const incomplete = report.kept.filter((item) => item.reason === 'incomplete');
|
|
872
|
+
if (report.removed.length || report.errors.length || incomplete.length) {
|
|
873
|
+
log(
|
|
874
|
+
`worktree cleanup: removed ${report.removed.length}, incomplete ${incomplete.length}` +
|
|
875
|
+
`${incomplete.length ? ` (${incomplete.map((item) => item.id).join(', ')})` : ''}, errors ${report.errors.length}`
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
},
|
|
879
|
+
{
|
|
880
|
+
intervalMs: 60 * 60_000,
|
|
881
|
+
initialDelayMs: 3 * 60_000,
|
|
882
|
+
onError: (error) => log(`worktree cleanup failed: ${error?.message || error}`),
|
|
883
|
+
}
|
|
884
|
+
);
|
|
885
|
+
schedule.startMaintenanceSchedule();
|
|
886
|
+
}
|
|
887
|
+
|
|
844
888
|
async function main() {
|
|
845
889
|
const startedAt = performance.now();
|
|
846
890
|
const bootPhases = createBootPhaseProfiler({ log, startedAt });
|
|
@@ -865,14 +909,19 @@ async function main() {
|
|
|
865
909
|
.then((maintenance) => maintenance.reconcileWorktreesAtStartup())
|
|
866
910
|
.then((report) => {
|
|
867
911
|
const changed = report.removed.length + report.recovered.length + report.pruned.length;
|
|
868
|
-
|
|
912
|
+
const incomplete = report.kept.filter((item) => item.reason === 'incomplete').length;
|
|
913
|
+
if (changed || incomplete || report.errors.length) {
|
|
869
914
|
log(
|
|
870
915
|
`worktree reconcile: removed ${report.removed.length}, recovered ${report.recovered.length}, ` +
|
|
871
|
-
`pruned ${report.pruned.length}, errors ${report.errors.length}`
|
|
916
|
+
`pruned ${report.pruned.length}, incomplete ${incomplete}, errors ${report.errors.length}`
|
|
872
917
|
);
|
|
873
918
|
}
|
|
874
919
|
})
|
|
875
920
|
.catch((error) => log(`worktree reconcile failed: ${error?.message || error}`));
|
|
921
|
+
// Idle-time housekeeping (shared/maintenance-schedule.mjs): the worktree
|
|
922
|
+
// cleanup's count/age limits and archive rules once the desktop (favorites)
|
|
923
|
+
// is attached, then hourly while no session is mid-turn.
|
|
924
|
+
void startDaemonMaintenance().catch((error) => log(`maintenance schedule failed: ${error?.message || error}`));
|
|
876
925
|
// The daemon owns prompt attachments; its census runs off the boot path
|
|
877
926
|
// (first attempt after the store's start delay, then per its interval).
|
|
878
927
|
void import('../runtime/attachments/store.mjs').then((store) => store.startAttachmentGc()).catch(() => {});
|
|
@@ -1043,6 +1092,9 @@ async function main() {
|
|
|
1043
1092
|
submit: async (sessionId, prompt, options) =>
|
|
1044
1093
|
(await sessionService.submitSession({ sessionId, prompt, options }))?.accepted === true,
|
|
1045
1094
|
abort: (sessionId) => sessionService.abortSession({ sessionId }),
|
|
1095
|
+
// A routine's executor sub-agent, run to its end before its bot is woken
|
|
1096
|
+
// (routine-executor.mjs); resolves `{ sessionId, content }`.
|
|
1097
|
+
runAgent: (args, context, options) => agentControl.runForeground(args, context, options),
|
|
1046
1098
|
});
|
|
1047
1099
|
// A bot's next turn, whatever starts it, first reads the progress updates
|
|
1048
1100
|
// queued for its thread (they wake nobody on their own).
|
|
@@ -17,6 +17,7 @@ import { createToolCardResults } from '../tui/session/tool-card-results.mjs';
|
|
|
17
17
|
import { createAgentJobFeed } from '../tui/session/agent-job-feed.mjs';
|
|
18
18
|
import { createWorktreeSetupNotices } from '../tui/session/worktree-setup-notice.mjs';
|
|
19
19
|
import { createContextState } from '../tui/session/context-state.mjs';
|
|
20
|
+
import { onTodoChange, todoSnapshot } from '../runtime/agent/orchestrator/runtime-core/todo-list.mjs';
|
|
20
21
|
import { createSessionFlow } from '../tui/session/session-flow.mjs';
|
|
21
22
|
import { createRunTurn } from '../tui/session/turn.mjs';
|
|
22
23
|
import { createQuotaResumeLane } from '../tui/session/quota-resume.mjs';
|
|
@@ -147,6 +148,9 @@ export function createRuntimePulse({
|
|
|
147
148
|
const pulse = () => {
|
|
148
149
|
if (flags.disposed) return;
|
|
149
150
|
if (flags.pendingSessionReset) return;
|
|
151
|
+
// A closed conversation has no session to read: republishing would blank
|
|
152
|
+
// its last todo and Goal for anyone still viewing it.
|
|
153
|
+
if (flags.admission === 'terminal') return;
|
|
150
154
|
syncContextStats({ allowEstimated: true });
|
|
151
155
|
publishChanged({
|
|
152
156
|
...routeState(),
|
|
@@ -385,6 +389,12 @@ export async function createLocalSessionRuntime({
|
|
|
385
389
|
displayedExecutionNotificationKeys,
|
|
386
390
|
pushNotice,
|
|
387
391
|
itemIndexById,
|
|
392
|
+
// The status line's context gauge after an empty session's settings reconcile.
|
|
393
|
+
refreshContextStats: () => {
|
|
394
|
+
if (flags.disposed || flags.pendingSessionReset) return;
|
|
395
|
+
syncContextStats({ allowEstimated: true });
|
|
396
|
+
set({ stats: { ...getState().stats } });
|
|
397
|
+
},
|
|
388
398
|
});
|
|
389
399
|
lifecycle.unsubscribeRuntimeNotifications = subscribeRuntimeNotifications();
|
|
390
400
|
if (typeof runtime.onWorktreeSetup === 'function') {
|
|
@@ -400,6 +410,12 @@ export async function createLocalSessionRuntime({
|
|
|
400
410
|
});
|
|
401
411
|
}
|
|
402
412
|
|
|
413
|
+
// A todo call republishes the list at once, not on the next 2s pulse.
|
|
414
|
+
lifecycle.unsubscribeTodo = onTodoChange(({ sessionId }) => {
|
|
415
|
+
if (flags.disposed || flags.pendingSessionReset || !sessionId || sessionId !== runtime.id) return;
|
|
416
|
+
set({ todo: todoSnapshot(runtime.session) });
|
|
417
|
+
});
|
|
418
|
+
|
|
403
419
|
const { patchToolCardResult, flushToolResults } = createToolCardResults({
|
|
404
420
|
getState,
|
|
405
421
|
set,
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
// owner that never published, the newest candidate's exit and first stderr
|
|
5
5
|
// error — so the desktop error card's details name the cause, not only the
|
|
6
6
|
// symptom.
|
|
7
|
-
|
|
7
|
+
const DAEMON_UNAVAILABLE_MESSAGE = 'daemon session endpoint is unavailable';
|
|
8
8
|
|
|
9
9
|
function exitCodeText(code) {
|
|
10
10
|
// Windows reports NTSTATUS crash codes as large unsigned values.
|
|
@@ -12,6 +12,8 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
12
12
|
'agentDefinitionPresence',
|
|
13
13
|
'archivedAgentIdentities',
|
|
14
14
|
'getAgentDefinition',
|
|
15
|
+
'listInstructionFiles',
|
|
16
|
+
'getInstructionFile',
|
|
15
17
|
'getAgentAvatarImage',
|
|
16
18
|
'getAgentConnectors',
|
|
17
19
|
'getProjectConnectors',
|
|
@@ -82,6 +84,8 @@ export const SESSION_READ_ACTIONS = Object.freeze([
|
|
|
82
84
|
'getBranchMenu',
|
|
83
85
|
'getProjectBranchMenu',
|
|
84
86
|
'listWorktrees',
|
|
87
|
+
'previewWorktreeCleanup',
|
|
88
|
+
'getSessionWorktreeWork',
|
|
85
89
|
'hooksStatus',
|
|
86
90
|
'inheritancePreflight',
|
|
87
91
|
'listAgents',
|
|
@@ -136,6 +140,8 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
136
140
|
'deleteAgentDefinition',
|
|
137
141
|
'restoreAgentDefinition',
|
|
138
142
|
'purgeAgentDefinition',
|
|
143
|
+
'saveInstructionFile',
|
|
144
|
+
'resetInstructionFile',
|
|
139
145
|
'deleteHookRule',
|
|
140
146
|
'deleteMediaAsset',
|
|
141
147
|
'deleteMediaAssets',
|
|
@@ -149,6 +155,9 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
149
155
|
'checkCustomProviderKeyEnv',
|
|
150
156
|
'discoverCustomProviderModels',
|
|
151
157
|
'deleteSession',
|
|
158
|
+
// The desktop's auto-delete: configureSession routes it through the turn
|
|
159
|
+
// gate (session-action.mjs deleteIdleSession), never the generic lane.
|
|
160
|
+
'deleteSessionIfIdle',
|
|
152
161
|
'deleteWebhook',
|
|
153
162
|
'deleteWorkflow',
|
|
154
163
|
'enablePluginMcp',
|
|
@@ -293,6 +302,8 @@ export const SESSION_CONFIGURE_ACTIONS = Object.freeze([
|
|
|
293
302
|
'mergeWorkspace',
|
|
294
303
|
'removeWorktree',
|
|
295
304
|
'pruneWorktrees',
|
|
305
|
+
'deleteWorktree',
|
|
306
|
+
'setArchivedSessionWorktrees',
|
|
296
307
|
]);
|
|
297
308
|
|
|
298
309
|
export const SESSION_READ_ACTION_SET = new Set(SESSION_READ_ACTIONS);
|
|
@@ -4,21 +4,13 @@
|
|
|
4
4
|
// on the model it started on). The latest saved route wins. A thread no
|
|
5
5
|
// runtime hosts keeps its model until it is opened (the desktop refreshes it
|
|
6
6
|
// then, agent-home-sessions.ts).
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
AGENT_ROUTE_KEYS as ROUTE_KEYS,
|
|
9
|
+
subscribeAgentRouteChanges,
|
|
10
|
+
} from '../../session-runtime/agent-profile-changes.mjs';
|
|
8
11
|
import { agentHomeSessionId } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
9
12
|
import { roomMemberOfSession } from '../../runtime/agent/orchestrator/session/agent-room.mjs';
|
|
10
13
|
|
|
11
|
-
const ROUTE_KEYS = [
|
|
12
|
-
'provider',
|
|
13
|
-
'model',
|
|
14
|
-
'effort',
|
|
15
|
-
'fast',
|
|
16
|
-
'autoEffort',
|
|
17
|
-
'modelParameters',
|
|
18
|
-
'contextPercent',
|
|
19
|
-
'contextTokens',
|
|
20
|
-
];
|
|
21
|
-
|
|
22
14
|
/** The pick the session route API takes for a saved route. */
|
|
23
15
|
function sessionRoutePick(route) {
|
|
24
16
|
const pick = { sessionOnly: true };
|
|
@@ -41,29 +33,40 @@ export function createAgentRouteFollow({ sessionsById, sessionOwner, advance, pu
|
|
|
41
33
|
if (step.changed) publishStep(entry, step);
|
|
42
34
|
})
|
|
43
35
|
.catch((error) => {
|
|
44
|
-
// A route the runtime refuses (provider signed out) leaves the chat on
|
|
36
|
+
// A route the runtime refuses (provider signed out) leaves the chat on
|
|
37
|
+
// its model; the publication fails, so a retrying publisher sends it again.
|
|
45
38
|
log(`agent route change not applied to ${sessionId}: ${error?.message || error}`);
|
|
39
|
+
throw error;
|
|
46
40
|
});
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
function enqueue(sessionId, pick) {
|
|
50
44
|
const queued = (tails.get(sessionId) || Promise.resolve()).then(() => apply(sessionId, pick));
|
|
51
|
-
|
|
52
|
-
queued.
|
|
53
|
-
|
|
45
|
+
// A refused update never holds back the chat's later ones.
|
|
46
|
+
const tail = queued.catch(() => {});
|
|
47
|
+
tails.set(sessionId, tail);
|
|
48
|
+
tail.then(() => {
|
|
49
|
+
if (tails.get(sessionId) === tail) tails.delete(sessionId);
|
|
54
50
|
});
|
|
55
51
|
return queued;
|
|
56
52
|
}
|
|
57
53
|
|
|
58
|
-
// Every matching chat is queued before the first await: publications queue
|
|
59
|
-
|
|
54
|
+
// Every matching chat is queued before the first await: publications queue
|
|
55
|
+
// in order. Rejects once every chat settled when any refused the route.
|
|
56
|
+
async function follow(agentId, route) {
|
|
60
57
|
const home = agentHomeSessionId(agentId);
|
|
61
|
-
if (!home || !route?.provider || !route?.model) return
|
|
58
|
+
if (!home || !route?.provider || !route?.model) return;
|
|
62
59
|
const pick = sessionRoutePick(route);
|
|
63
60
|
const queued = [...sessionsById.keys()]
|
|
64
61
|
.filter((sessionId) => sessionId === home || roomMemberOfSession(sessionId)?.agentId === agentId)
|
|
65
62
|
.map((sessionId) => enqueue(sessionId, pick));
|
|
66
|
-
|
|
63
|
+
const failures = (await Promise.allSettled(queued)).filter((one) => one.status === 'rejected');
|
|
64
|
+
if (failures.length) {
|
|
65
|
+
throw new AggregateError(
|
|
66
|
+
failures.map((one) => one.reason),
|
|
67
|
+
`${failures.length} chat(s) of ${agentId} did not take the route`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
67
70
|
}
|
|
68
71
|
return subscribeAgentRouteChanges(follow);
|
|
69
72
|
}
|
|
@@ -6,6 +6,7 @@ import { createAgentChildFactory } from './agent-child.mjs';
|
|
|
6
6
|
import { partialHandoffTextFromSession } from '../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
|
|
7
7
|
import { attachmentsForIntake } from '../../../runtime/attachments/store.mjs';
|
|
8
8
|
import { producedFileLines } from '../../../runtime/shared/handoff-artifacts.mjs';
|
|
9
|
+
import { carryReportOnError, turnReportText } from '../../../runtime/agent/orchestrator/session/loop/turn-report.mjs';
|
|
9
10
|
import {
|
|
10
11
|
collectUnreportedWrites,
|
|
11
12
|
handoffContent,
|
|
@@ -79,7 +80,16 @@ export function createAgentTurns({
|
|
|
79
80
|
return error;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
async function runAgentTurn({
|
|
83
|
+
async function runAgentTurn({
|
|
84
|
+
session,
|
|
85
|
+
prompt,
|
|
86
|
+
context = null,
|
|
87
|
+
onToolResult,
|
|
88
|
+
onTerminalResult,
|
|
89
|
+
// The trusted skill-selection text of the turn (a routine executor's
|
|
90
|
+
// instructions); absent selects from the whole prompt, as any turn does.
|
|
91
|
+
skillSelection,
|
|
92
|
+
} = {}) {
|
|
83
93
|
await rehydrateAgentSessions();
|
|
84
94
|
const sessionId = String(session?.id || session || '').trim();
|
|
85
95
|
const cancelEpoch = registry.assertAdmission(sessionId);
|
|
@@ -116,11 +126,12 @@ export function createAgentTurns({
|
|
|
116
126
|
priority: 'next',
|
|
117
127
|
context,
|
|
118
128
|
transcriptMeta: agentTurnTranscriptMeta(content),
|
|
129
|
+
...(typeof skillSelection === 'string' ? { skillSelection } : {}),
|
|
119
130
|
...(entry.runtime.isWireSafe === true || typeof onToolResult !== 'function' ? {} : { onToolResult }),
|
|
120
131
|
};
|
|
121
132
|
const detail = await target.call(entry.runtime, content, options);
|
|
122
133
|
if (detail?.status === 'failed') {
|
|
123
|
-
throw new Error(String(detail.error || 'agent session turn failed'));
|
|
134
|
+
throw carryReportOnError(new Error(String(detail.error || 'agent session turn failed')), detail.carriedReport);
|
|
124
135
|
}
|
|
125
136
|
if (detail?.status === 'cancelled') {
|
|
126
137
|
const stop = takeWatchdogStop(sessionId) || new Error('agent session turn cancelled');
|
|
@@ -134,11 +145,12 @@ export function createAgentTurns({
|
|
|
134
145
|
const reason = String(detail?.reason || detail?.error || '').trim();
|
|
135
146
|
throw new Error(`agent turn ${status}${reason ? `: ${reason}` : ''}`);
|
|
136
147
|
}
|
|
137
|
-
|
|
138
|
-
// The
|
|
139
|
-
|
|
148
|
+
const { reportContent, ...settled } = detail?.result || { content: '' };
|
|
149
|
+
// The owner gets the turn's whole report (turn-report.mjs), with the
|
|
150
|
+
// files the turn produced.
|
|
151
|
+
const report = turnReportText({ ...settled, reportContent });
|
|
140
152
|
const files = await turnArtifactLines(entry.runtime, messageStart, descriptor, report);
|
|
141
|
-
|
|
153
|
+
const result = { ...settled, content: files.length ? [report, files.join('\n')].join('\n\n') : report };
|
|
142
154
|
descriptor.status = 'idle';
|
|
143
155
|
descriptor.stage = 'idle';
|
|
144
156
|
descriptor.lastHandoff = typeof result?.content === 'string' ? result.content : '';
|
|
@@ -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.
|