mixdog 1.3.1 → 1.3.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/README.md +8 -4
- package/package.json +8 -8
- package/scripts/native-release-status.mjs +238 -0
- package/scripts/verify-runtime-dependency-versions.mjs +158 -0
- package/src/agents/reviewer/AGENT.md +5 -7
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +9 -1
- package/src/defaults/skills/browser-use/SKILL.md +6 -3
- package/src/defaults/skills/local-provider/SKILL.md +33 -6
- package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
- package/src/defaults/skills/setup/SKILL.md +23 -1
- package/src/defaults/skills/setup/references/actions.md +50 -3
- package/src/defaults/skills/setup/references/surfaces.md +23 -3
- package/src/defaults/skills/setup-guide/SKILL.md +7 -3
- package/src/defaults/skills/visualize/SKILL.md +9 -6
- package/src/defaults/skills/visualize/references/craft.md +8 -1
- package/src/help.mjs +1 -1
- package/src/lib/keychain-cjs.cjs +4 -1
- package/src/lib/rules-builder.cjs +14 -7
- package/src/rules/agent-mode/AGENT_MODE.md +8 -5
- package/src/rules/agent-mode/MIXY.md +6 -8
- package/src/rules/lead/LEAD.md +7 -10
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/20-research.md +2 -0
- package/src/rules/shared/45-destructive.md +5 -1
- package/src/rules/shared/60-verification.md +6 -4
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
- package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
- package/src/runtime/agent/orchestrator/config.mjs +11 -0
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -5
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
- package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +84 -32
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +38 -11
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +15 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +84 -42
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +27 -8
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
- package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
- package/src/runtime/agent/orchestrator/providers/registry.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +13 -1
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
- package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +5 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +10 -1
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +4 -6
- package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +52 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +35 -13
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +8 -3
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -2
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +196 -45
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/continuation.mjs +15 -6
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +45 -19
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +44 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +185 -37
- package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
- package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +240 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +102 -35
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +19 -9
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +199 -109
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/empty-nudge.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +62 -13
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +22 -6
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +5 -5
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +33 -8
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/call-prep.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/manager/agent-listing-notice.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +27 -14
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +32 -1
- package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +115 -0
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +28 -9
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +4 -9
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +14 -1
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +52 -11
- package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +18 -3
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +126 -12
- package/src/runtime/agent/orchestrator/session/runtime-user-context.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +16 -3
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +140 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +15 -5
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +49 -1
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +80 -1
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +33 -1
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.d.mts +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +37 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +35 -5
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +42 -2
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +47 -14
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +127 -20
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +557 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +10 -12
- package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +42 -23
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
- package/src/runtime/attachments/attachment-reference.mjs +155 -0
- package/src/runtime/attachments/legacy-office.mjs +110 -0
- package/src/runtime/attachments/limits.mjs +5 -1
- package/src/runtime/attachments/office-extract.mjs +3 -6
- package/src/runtime/attachments/pdf-extract.mjs +84 -10
- package/src/runtime/attachments/prompt-restore.mjs +70 -0
- package/src/runtime/attachments/store.mjs +109 -33
- package/src/runtime/browser-bridge/client.mjs +73 -20
- package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +14 -7
- package/src/runtime/channels/lib/state-file.mjs +15 -15
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
- package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
- package/src/runtime/channels/lib/worker-main.mjs +3 -2
- package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
- package/src/runtime/effort-judge/judge-client.mjs +66 -16
- package/src/runtime/effort-judge/model-install.mjs +47 -7
- package/src/runtime/local-provider/asset-installer.mjs +10 -4
- package/src/runtime/local-provider/catalog.mjs +5 -2
- package/src/runtime/local-provider/registered-models.mjs +64 -27
- package/src/runtime/local-provider/server.mjs +2 -3
- package/src/runtime/media/adapters/image-api.mjs +89 -0
- package/src/runtime/media/auth.mjs +64 -1
- package/src/runtime/media/catalog.mjs +66 -4
- package/src/runtime/media/jobs.mjs +4 -0
- package/src/runtime/media/lanes.mjs +46 -5
- package/src/runtime/media/media-usage.mjs +17 -0
- package/src/runtime/media/renditions.mjs +15 -15
- package/src/runtime/media/store.mjs +36 -35
- package/src/runtime/media/tool.mjs +8 -1
- package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
- package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
- package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +14 -2
- package/src/runtime/memory/lib/pg/process.mjs +8 -4
- package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
- package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
- package/src/runtime/office/core/journal.mjs +7 -14
- package/src/runtime/office/design/library/design-library-core.mjs +4 -16
- package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
- package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
- package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
- package/src/runtime/office/pdf/pdf-render.mjs +30 -18
- package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +135 -29
- package/src/runtime/shared/agent-avatar-sprites.mjs +23 -8
- package/src/runtime/shared/agent-avatar.mjs +3 -2
- package/src/runtime/shared/agent-kind-migration.mjs +200 -0
- package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
- package/src/runtime/shared/agent-message-envelope.mjs +44 -0
- package/src/runtime/shared/agent-reap-state.d.mts +4 -0
- package/src/runtime/shared/agent-room-host.d.mts +31 -0
- package/src/runtime/shared/agent-room-host.mjs +58 -0
- package/src/runtime/shared/agent-store.mjs +24 -7
- package/src/runtime/shared/agent-task-starts.mjs +27 -0
- package/src/runtime/shared/atomic-file.d.mts +50 -0
- package/src/runtime/shared/atomic-file.mjs +394 -132
- package/src/runtime/shared/background-tasks.mjs +7 -4
- package/src/runtime/shared/bot-hops.mjs +35 -0
- package/src/runtime/shared/bot-split-migration.mjs +1 -1
- package/src/runtime/shared/bounded-download.mjs +4 -2
- package/src/runtime/shared/config.mjs +39 -9
- package/src/runtime/shared/defaults-separation.mjs +6 -2
- package/src/runtime/shared/delegated-approval-host.mjs +74 -0
- package/src/runtime/shared/err-text.mjs +4 -0
- package/src/runtime/shared/error-presentation.mjs +22 -4
- package/src/runtime/shared/file-has-data.mjs +28 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
- package/src/runtime/shared/pending-agent-work.mjs +54 -0
- package/src/runtime/shared/process-lifecycle.mjs +8 -12
- package/src/runtime/shared/projects.mjs +50 -41
- package/src/runtime/shared/provider-accounts.mjs +17 -12
- package/src/runtime/shared/redact-directories.mjs +18 -0
- package/src/runtime/shared/remove-directory.mjs +28 -0
- package/src/runtime/shared/routine-trigger.d.mts +6 -1
- package/src/runtime/shared/routine-trigger.mjs +14 -6
- package/src/runtime/shared/run-child.d.mts +3 -0
- package/src/runtime/shared/run-child.mjs +24 -3
- package/src/runtime/shared/session-baseline-store.mjs +8 -2
- package/src/runtime/shared/session-sidebar-host.d.mts +11 -2
- package/src/runtime/shared/session-sidebar-host.mjs +16 -3
- package/src/runtime/shared/singleton-owner.mjs +7 -6
- package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
- package/src/runtime/shared/staged-update.mjs +4 -2
- package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
- package/src/runtime/shared/tool-execution-contract.mjs +10 -0
- package/src/runtime/shared/tool-work-units.mjs +12 -9
- package/src/runtime/shared/transcript-metadata.mjs +28 -3
- package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
- package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
- package/src/runtime/shared/turn-snapshot.mjs +277 -124
- package/src/runtime/shared/user-cwd.mjs +9 -4
- package/src/runtime/shared/user-data-guard.mjs +92 -61
- package/src/runtime/shared/utf8-cut.mjs +10 -0
- package/src/runtime/shared/worktrees/activity-gate.mjs +251 -61
- package/src/runtime/shared/worktrees/contract.mjs +11 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +11 -2
- package/src/runtime/shared/worktrees/manager.mjs +419 -52
- package/src/runtime/shared/worktrees/registry.mjs +29 -27
- package/src/runtime/shared/worktrees/tool-host.mjs +39 -0
- package/src/runtime/tidy/core-install.mjs +26 -4
- package/src/runtime/tidy/install.mjs +91 -23
- package/src/runtime/tidy/process.mjs +41 -8
- package/src/runtime/tidy/resolve.mjs +10 -7
- package/src/runtime/web-search/lib/config.mjs +4 -16
- package/src/session-runtime/agent-home-delivery.mjs +542 -204
- package/src/session-runtime/agent-profile-changes.mjs +16 -0
- package/src/session-runtime/agent-room-delivery.mjs +81 -35
- package/src/session-runtime/agent-task-sessions.mjs +811 -179
- package/src/session-runtime/agent-tool-routing.mjs +1 -0
- package/src/session-runtime/boot/apis.mjs +48 -24
- package/src/session-runtime/boot/config.mjs +1 -0
- package/src/session-runtime/boot/facade.mjs +16 -7
- package/src/session-runtime/boot/infrastructure.mjs +14 -2
- package/src/session-runtime/boot/providers.mjs +2 -2
- package/src/session-runtime/boot/shared.mjs +12 -6
- package/src/session-runtime/boot/tools.mjs +23 -3
- package/src/session-runtime/bot-status.mjs +432 -0
- package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
- package/src/session-runtime/config-lifecycle.mjs +60 -55
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
- package/src/session-runtime/held-requests.mjs +31 -33
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +24 -26
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown.mjs +11 -3
- package/src/session-runtime/mcp-glue/connect.mjs +100 -186
- package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
- package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
- package/src/session-runtime/media-api.mjs +5 -2
- package/src/session-runtime/model-recency.mjs +1 -0
- package/src/session-runtime/model-route/route-tuning.mjs +4 -1
- package/src/session-runtime/model-route/set-route.mjs +61 -1
- package/src/session-runtime/owned-automation-run.mjs +8 -1
- package/src/session-runtime/provider-models/row-hydration.mjs +8 -1
- package/src/session-runtime/quick-model-rows/model-meta.mjs +2 -0
- package/src/session-runtime/quick-model-rows/provider-rows.mjs +7 -1
- package/src/session-runtime/route-resolution.mjs +16 -8
- package/src/session-runtime/route-state.mjs +1 -59
- package/src/session-runtime/routine-home-turn.mjs +5 -3
- package/src/session-runtime/runtime-bootstrap.mjs +5 -3
- package/src/session-runtime/runtime-paths.mjs +11 -5
- package/src/session-runtime/runtime-review-api.mjs +4 -1
- package/src/session-runtime/runtime-tunables.mjs +6 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
- package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
- package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +34 -19
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +25 -21
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +7 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +8 -5
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
- package/src/session-runtime/services/agent-tool.mjs +6 -0
- package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
- package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
- package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
- package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
- package/src/session-runtime/services/plugin-admin.mjs +26 -26
- package/src/session-runtime/services/provider-admin.mjs +26 -6
- package/src/session-runtime/services/schedule-access.mjs +33 -4
- package/src/session-runtime/services/seeds.mjs +4 -3
- package/src/session-runtime/services/usage-dashboard.mjs +1 -1
- package/src/session-runtime/services/usage-stats-model.mjs +2 -1
- package/src/session-runtime/services/worktree-access.mjs +27 -0
- package/src/session-runtime/session-create/materialize.mjs +2 -3
- package/src/session-runtime/session-create/session-options.mjs +15 -2
- package/src/session-runtime/session-hooks.mjs +9 -17
- package/src/session-runtime/settings-builtin-tools-api.mjs +65 -1
- package/src/session-runtime/settings-compaction-api.mjs +86 -39
- package/src/session-runtime/setup-tool/executor.mjs +12 -2
- package/src/session-runtime/setup-tool/settings-contract.mjs +34 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
- package/src/session-runtime/skills-api.mjs +12 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +349 -0
- package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
- package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
- package/src/session-runtime/tool-policy/policy-stage.mjs +183 -0
- package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
- package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
- package/src/session-runtime/tool-policy-refresh.mjs +48 -369
- package/src/session-runtime/tool-surface.mjs +10 -4
- package/src/session-runtime/turn/session-ops.mjs +8 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +95 -88
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +7 -2
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +527 -333
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +85 -63
- package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
- package/src/session-runtime/workspace/transition-steps.mjs +1 -18
- package/src/session-runtime/workspace/transitions.mjs +279 -67
- package/src/session-runtime/workspace/workspace-state.mjs +7 -6
- package/src/session-runtime/workspace/worktree-tool.mjs +194 -0
- package/src/standalone/daemon-agent-control.mjs +4 -1
- package/src/standalone/daemon-lag-profiler.mjs +3 -1
- package/src/standalone/daemon-session-control.mjs +173 -15
- package/src/standalone/daemon-telemetry.mjs +9 -0
- package/src/standalone/daemon.mjs +33 -10
- package/src/standalone/local-session-runtime.mjs +33 -16
- package/src/standalone/session-client.mjs +7 -2
- package/src/standalone/session-protocol.mjs +8 -0
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +2 -0
- package/src/standalone/session-service/agent-route-follow.mjs +69 -0
- package/src/standalone/session-service/session-calls/session-turns.mjs +33 -4
- package/src/standalone/session-service.mjs +21 -0
- package/src/standalone/session-state-projection.mjs +19 -9
- package/src/standalone/session-tool-output.mjs +36 -9
- package/src/standalone/staged-import.mjs +47 -0
- package/src/tui/App.jsx +2 -0
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
- package/src/tui/app/message-selector.mjs +15 -2
- package/src/tui/app/model-options.mjs +16 -2
- package/src/tui/app/model-picker.mjs +2 -1
- package/src/tui/app/route-pickers.mjs +3 -1
- package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
- package/src/tui/dist/index.mjs +617 -369
- package/src/tui/paste-attachments.mjs +0 -1
- package/src/tui/paste-text-policy.mjs +4 -5
- package/src/tui/prompt-history-store.mjs +16 -21
- package/src/tui/session/agent-job-feed/execution-delivery.mjs +4 -1
- package/src/tui/session/context-state.mjs +4 -0
- package/src/tui/session/notice-surface.mjs +3 -0
- package/src/tui/session/session-api/intake/abort.mjs +52 -18
- package/src/tui/session/session-api/intake/rewind.mjs +39 -4
- package/src/tui/session/session-api/media.mjs +2 -1
- package/src/tui/session/session-api/routes-agent-definitions.mjs +76 -0
- package/src/tui/session/session-api/routes-write.mjs +203 -0
- package/src/tui/session/session-api/routes.mjs +23 -247
- package/src/tui/session/session-api/settings.mjs +14 -1
- package/src/tui/session/session-flow/drain.mjs +28 -3
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
- package/src/tui/session/session-flow/steering.mjs +8 -3
- package/src/tui/session/tool-approval.mjs +142 -14
- package/src/tui/session/transcript-intake.mjs +2 -0
- package/src/tui/session/turn.mjs +23 -14
- package/src/tui/transcript-tool-failures.mjs +8 -2
- package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
- package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
- package/src/rules/agent-mode/ROUTINE.md +0 -6
- package/src/session-runtime/room-member-gate.mjs +0 -48
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Lead's managed-worktree operations behind the `git` tool
|
|
3
|
+
* (`action: "worktree"` and the mapped `git worktree …` commands), over the
|
|
4
|
+
* same workspace authority the desktop branch menu drives:
|
|
5
|
+
*
|
|
6
|
+
* - The caller's own session runs through this runtime's workspace API with
|
|
7
|
+
* `ownTurn` (the calling turn is tolerated; workers, background shells and
|
|
8
|
+
* other sessions in an affected folder are not).
|
|
9
|
+
* - Another session runs through session control (the daemon's
|
|
10
|
+
* `session.configure` lane): no `ownTurn`, so a target with a running turn,
|
|
11
|
+
* workers or background shells refuses (WORKTREE_BUSY_JOBS).
|
|
12
|
+
*
|
|
13
|
+
* Every failure keeps its typed WorktreeError (code, details); interactive
|
|
14
|
+
* refusals (WORKTREE_DIRTY_CHOICE, WORKTREE_LARGE_REPO_CONFIRM) carry what the
|
|
15
|
+
* caller needs to ask the user before it calls again.
|
|
16
|
+
*/
|
|
17
|
+
import { worktreeError, worktreeNameError } from '../../runtime/shared/worktrees/contract.mjs';
|
|
18
|
+
import { samePath } from '../../runtime/shared/worktrees/paths.mjs';
|
|
19
|
+
import { assertWorktreeMutationAllowed, worktreeCallerScope } from '../services/worktree-access.mjs';
|
|
20
|
+
|
|
21
|
+
const loadManager = () => import('../../runtime/shared/worktrees/manager.mjs');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @param {object} deps
|
|
25
|
+
* @param {() => any} deps.getSession The Lead session this runtime hosts (its trusted caller scope).
|
|
26
|
+
* @param {() => any} deps.getWorkspaceApi The runtime's workspace transitions (late-bound).
|
|
27
|
+
* @param {((args: object, context: object) => Promise<any>)|null} [deps.executeSessionControl] Cross-session lane.
|
|
28
|
+
* @param {object|null} [deps.manager] Managed-worktree backend override (tests).
|
|
29
|
+
*/
|
|
30
|
+
export function createWorktreeToolHost({
|
|
31
|
+
getSession,
|
|
32
|
+
getWorkspaceApi,
|
|
33
|
+
executeSessionControl = null,
|
|
34
|
+
manager = null,
|
|
35
|
+
}) {
|
|
36
|
+
const backend = () => (manager ? Promise.resolve(manager) : loadManager());
|
|
37
|
+
|
|
38
|
+
function workspaceApi() {
|
|
39
|
+
const api = getWorkspaceApi();
|
|
40
|
+
if (!api) throw new Error('git worktree: managed worktrees are unavailable in this runtime');
|
|
41
|
+
return api;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The workspace lane of `sessionId`: the caller's own (null/equal) or
|
|
46
|
+
* another session's, which carries the caller's trusted `scope` for the
|
|
47
|
+
* daemon to check again.
|
|
48
|
+
*/
|
|
49
|
+
function laneFor(sessionId, callerSessionId, scope) {
|
|
50
|
+
if (!sessionId || sessionId === callerSessionId) {
|
|
51
|
+
const api = workspaceApi();
|
|
52
|
+
return {
|
|
53
|
+
own: true,
|
|
54
|
+
menu: () => api.getBranchMenu(),
|
|
55
|
+
call: (method, input) => api[method](input, { ownTurn: true }),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (typeof executeSessionControl !== 'function') {
|
|
59
|
+
throw new Error("git worktree: another session's workspace is unavailable in this runtime");
|
|
60
|
+
}
|
|
61
|
+
const control = (method, input) =>
|
|
62
|
+
executeSessionControl(
|
|
63
|
+
{ action: 'worktree', session_id: sessionId, method, ...(input ? { input } : {}) },
|
|
64
|
+
{ callerSessionId, callerScope: scope }
|
|
65
|
+
);
|
|
66
|
+
return { own: false, menu: () => control('getBranchMenu'), call: control };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function enter(lane, request) {
|
|
70
|
+
if (request.branch) {
|
|
71
|
+
return lane.call('selectBranch', {
|
|
72
|
+
branch: request.branch,
|
|
73
|
+
create: request.create === true,
|
|
74
|
+
confirmLarge: request.confirmLarge === true,
|
|
75
|
+
txId: request.txId,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// A valid slug names the worktree; any other text is a hint the slug is made from.
|
|
79
|
+
const name = typeof request.name === 'string' ? request.name.trim() : '';
|
|
80
|
+
const slug = name && !worktreeNameError(name) ? name : null;
|
|
81
|
+
return lane.call('requestWorktree', {
|
|
82
|
+
provision: true,
|
|
83
|
+
name: slug,
|
|
84
|
+
prompt: slug ? '' : name,
|
|
85
|
+
...(request.carry ? { carryChanges: request.carry } : {}),
|
|
86
|
+
confirmLarge: request.confirmLarge === true,
|
|
87
|
+
txId: request.txId,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Back to the project folder (the branch checked out there); the worktree stays retained. */
|
|
92
|
+
async function back(lane, request) {
|
|
93
|
+
const menu = await lane.menu();
|
|
94
|
+
const workspace = menu.workspace;
|
|
95
|
+
if (!workspace.worktreeId && samePath(workspace.cwd, workspace.projectPath)) {
|
|
96
|
+
return { revision: workspace.revision, workspace, unchanged: true };
|
|
97
|
+
}
|
|
98
|
+
const projectBranch = menu.occupancy.find((row) => row.kind === 'current')?.branch ?? null;
|
|
99
|
+
if (!projectBranch) {
|
|
100
|
+
throw worktreeError(
|
|
101
|
+
'WORKTREE_UNSUPPORTED_REPO',
|
|
102
|
+
'The project folder has no checked-out branch to return to (detached HEAD).'
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return lane.call('selectBranch', { branch: projectBranch, expectedRevision: workspace.revision, txId: request.txId });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** The desktop's "merge": into the confirmed merge target, then the cleanup autoCleanup allows. */
|
|
109
|
+
async function merge(lane) {
|
|
110
|
+
const { workspace } = await lane.menu();
|
|
111
|
+
return lane.call('mergeWorkspace', {
|
|
112
|
+
confirmed: true,
|
|
113
|
+
target: workspace.mergeTarget ?? null,
|
|
114
|
+
expectedRevision: workspace.revision,
|
|
115
|
+
cleanup: true,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* `git worktree remove <path>`: the managed removal of whichever owner
|
|
121
|
+
* holds it — this session's snapshot, or the worktree a session retains
|
|
122
|
+
* (its own lane: the same guards as the desktop's removal).
|
|
123
|
+
*/
|
|
124
|
+
async function removePath(request, callerSessionId, scope) {
|
|
125
|
+
const entry = await (await backend()).getWorktreeByPath(request.path);
|
|
126
|
+
if (!entry) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`git worktree remove: ${request.path} is not a Mixdog-managed worktree; unmanaged worktrees are not removed through the git tool`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
if (entry.kind === 'snapshot') return workspaceApi().removeSnapshot({ path: entry.path, force: request.force });
|
|
132
|
+
if (!entry.ownerSessionId) {
|
|
133
|
+
throw new Error(
|
|
134
|
+
`git worktree remove: no session retains ${entry.path}; git worktree prune removes it once it is clean and merged`
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
const lane = laneFor(entry.ownerSessionId, callerSessionId, scope);
|
|
138
|
+
const menu = await lane.menu();
|
|
139
|
+
if (menu.retainedWorktree?.id !== entry.id) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
`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`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
return lane.call('removeWorktree', { force: request.force === true, expectedRevision: menu.workspace.revision });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @param {{ op: string } & Record<string, any>} request
|
|
149
|
+
* @param {{ callerSessionId: string }} context
|
|
150
|
+
*/
|
|
151
|
+
async function run(request, { callerSessionId }) {
|
|
152
|
+
// Trusted state of the calling Lead, never model input: every operation
|
|
153
|
+
// but `list` needs an attended conversation.
|
|
154
|
+
const scope = worktreeCallerScope(getSession());
|
|
155
|
+
if (request.op !== 'list') assertWorktreeMutationAllowed(scope, `git worktree ${request.op}`);
|
|
156
|
+
const lane = () => laneFor(request.sessionId, callerSessionId, scope);
|
|
157
|
+
switch (request.op) {
|
|
158
|
+
case 'enter':
|
|
159
|
+
return enter(lane(), request);
|
|
160
|
+
case 'return':
|
|
161
|
+
return back(lane(), request);
|
|
162
|
+
case 'merge':
|
|
163
|
+
return merge(lane());
|
|
164
|
+
case 'remove':
|
|
165
|
+
return lane().call('removeWorktree', { force: request.force === true });
|
|
166
|
+
case 'list':
|
|
167
|
+
return workspaceApi().listWorktrees({ includeSnapshots: true });
|
|
168
|
+
case 'prune':
|
|
169
|
+
return workspaceApi().pruneWorktrees({ repoCommonDir: request.repoCommonDir ?? null });
|
|
170
|
+
case 'add':
|
|
171
|
+
return workspaceApi().addBranchWorktree({
|
|
172
|
+
branch: request.branch,
|
|
173
|
+
create: request.create === true,
|
|
174
|
+
startPoint: request.startPoint ?? null,
|
|
175
|
+
confirmLarge: request.confirmLarge === true,
|
|
176
|
+
txId: request.txId,
|
|
177
|
+
repoCommonDir: request.repoCommonDir ?? null,
|
|
178
|
+
});
|
|
179
|
+
case 'snapshot':
|
|
180
|
+
return workspaceApi().createSnapshot({
|
|
181
|
+
commit: request.commit,
|
|
182
|
+
confirmLarge: request.confirmLarge === true,
|
|
183
|
+
txId: request.txId,
|
|
184
|
+
repoCommonDir: request.repoCommonDir ?? null,
|
|
185
|
+
});
|
|
186
|
+
case 'remove-path':
|
|
187
|
+
return removePath(request, callerSessionId, scope);
|
|
188
|
+
default:
|
|
189
|
+
throw new TypeError(`git worktree: unknown operation ${request.op}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return { run };
|
|
194
|
+
}
|
|
@@ -54,7 +54,10 @@ export function createCanonicalAgentControl({ getSessionService, getSessionRunti
|
|
|
54
54
|
ownerSessionId: sessionService.rootOwnerSessionId(parentSessionId),
|
|
55
55
|
};
|
|
56
56
|
if (String(args?.type || '') === '__close_all') {
|
|
57
|
-
await tool.closeAll?.(String(args?.reason || 'agent owner closed'), {
|
|
57
|
+
await tool.closeAll?.(String(args?.reason || 'agent owner closed'), {
|
|
58
|
+
callerSessionId: parentSessionId || null,
|
|
59
|
+
processExit: args?.processExit === true,
|
|
60
|
+
});
|
|
58
61
|
await sessionService.cancelAgentDescendants(parentSessionId, String(args?.reason || 'agent owner closed'));
|
|
59
62
|
return 'agent close all: ok';
|
|
60
63
|
}
|
|
@@ -20,7 +20,9 @@ export const LAG_PROFILE_KEEP = 10;
|
|
|
20
20
|
export const LAG_PROFILE_TOP = 15;
|
|
21
21
|
export const LAG_PROFILE_SAMPLING_US = 1000;
|
|
22
22
|
export const LAG_P99_THRESHOLD_MS = 1000;
|
|
23
|
-
|
|
23
|
+
// The owner lease's stall threshold: any window holding one logged
|
|
24
|
+
// `event loop stalled` line is kept.
|
|
25
|
+
export const LAG_MAX_THRESHOLD_MS = 1000;
|
|
24
26
|
|
|
25
27
|
const PROFILE_FILE_RE = /^daemon-lag-.+\.cpuprofile$/;
|
|
26
28
|
const SRC_ROOT = fileURLToPath(new URL('..', import.meta.url));
|
|
@@ -1,19 +1,85 @@
|
|
|
1
1
|
import { SESSION_ID_PATTERN } from '../runtime/agent/orchestrator/runtime-core/session-id.mjs';
|
|
2
2
|
import { sessionListOutput, sessionReadOutput, SESSION_TOOL_OUTPUT_BYTES } from './session-tool-output.mjs';
|
|
3
3
|
import { createAgentTaskSessions } from '../session-runtime/agent-task-sessions.mjs';
|
|
4
|
+
import { assertWorktreeMutationAllowed } from '../session-runtime/services/worktree-access.mjs';
|
|
5
|
+
import { createBotStatus, scanCatalog, scopedBot, sessionBotOf } from '../session-runtime/bot-status.mjs';
|
|
4
6
|
import { handoffContent } from '../session-runtime/handoff-attachments.mjs';
|
|
7
|
+
import { BOT_HOP_LIMIT_ERROR, MAX_BOT_HOPS } from '../runtime/shared/bot-hops.mjs';
|
|
8
|
+
import { rebindDelegation } from '../runtime/agent/orchestrator/session/human-gate/delegation.mjs';
|
|
9
|
+
import { isAgentOnlySession } from '../runtime/agent/orchestrator/session/store-summary-visibility.mjs';
|
|
10
|
+
import { readSessionSidebarState } from '../runtime/shared/session-sidebar-host.mjs';
|
|
11
|
+
import { agentRoomHost } from '../runtime/shared/agent-room-host.mjs';
|
|
12
|
+
import {
|
|
13
|
+
roomIdOfSession,
|
|
14
|
+
roomMemberOfSession,
|
|
15
|
+
roomSessionId,
|
|
16
|
+
} from '../runtime/agent/orchestrator/session/agent-room.mjs';
|
|
5
17
|
|
|
6
18
|
const TARGET_ACTIONS = new Set(['status', 'read', 'send', 'cancel', 'delete']);
|
|
7
19
|
const MUTATING_ACTIONS = new Set(['send', 'cancel', 'delete']);
|
|
20
|
+
// The workspace methods `worktree` reaches on another session (all on the
|
|
21
|
+
// session protocol's read/configure allowlists).
|
|
22
|
+
const WORKTREE_METHODS = new Set(['getBranchMenu', 'requestWorktree', 'selectBranch', 'mergeWorkspace', 'removeWorktree']);
|
|
23
|
+
// Why a send from a conversation that is no bot's reports nothing back.
|
|
24
|
+
const NOT_BOT_REASON = 'only a bot conversation gets session results reported back; check that session for the result';
|
|
25
|
+
|
|
26
|
+
/** The member a send to room log `sessionId` addresses, through the desktop
|
|
27
|
+
* room host: `{ host, agentId, sessionId, text }`; throws when no desktop is
|
|
28
|
+
* attached or no member resolves. */
|
|
29
|
+
async function roomAddressee(sessionId, args) {
|
|
30
|
+
let host;
|
|
31
|
+
try {
|
|
32
|
+
host = agentRoomHost();
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw new Error(`session: cannot send to ${sessionId}: ${error.message}`);
|
|
35
|
+
}
|
|
36
|
+
const member = await host.member(sessionId, { to: args.to, prompt: args.prompt }).catch((error) => {
|
|
37
|
+
throw new Error(`session: ${error?.message || error}`);
|
|
38
|
+
});
|
|
39
|
+
return { host, ...member };
|
|
40
|
+
}
|
|
8
41
|
|
|
9
42
|
/** Model-facing session operations over the same service used by desktop and TUI. */
|
|
10
43
|
export function createSessionControl({
|
|
11
44
|
getSessionService,
|
|
12
45
|
agentTasks = createAgentTaskSessions({ getSessionService }),
|
|
46
|
+
botStatus = createBotStatus({ getSessionService }),
|
|
13
47
|
}) {
|
|
48
|
+
/**
|
|
49
|
+
* Another session's workspace for the git tool's worktree operations
|
|
50
|
+
* (session-runtime/workspace/worktree-tool.mjs): one workspace method with
|
|
51
|
+
* one input, through the same configure / read lanes the desktop uses. No
|
|
52
|
+
* `ownTurn` ever crosses: the target must be idle. A change (anything but
|
|
53
|
+
* the menu read) needs the caller's trusted scope (`callerScope`, from
|
|
54
|
+
* worktree-access.mjs worktreeCallerScope) to be an attended conversation.
|
|
55
|
+
*/
|
|
56
|
+
async function worktreeControl(args, caller, callerScope) {
|
|
57
|
+
const sessionId = typeof args.session_id === 'string' ? args.session_id.trim() : '';
|
|
58
|
+
if (!SESSION_ID_PATTERN.test(sessionId)) throw new Error('session: session_id is required for action=worktree');
|
|
59
|
+
if (sessionId === caller) throw new Error('session: worktree control must target another session');
|
|
60
|
+
if (!WORKTREE_METHODS.has(args.method)) throw new Error(`session: unsupported worktree method "${args.method}"`);
|
|
61
|
+
if (args.method !== 'getBranchMenu') assertWorktreeMutationAllowed(callerScope, `session: worktree ${args.method}`);
|
|
62
|
+
const service = getSessionService();
|
|
63
|
+
if (!service) throw new Error('session: session service is unavailable');
|
|
64
|
+
if (args.method === 'getBranchMenu') {
|
|
65
|
+
return (await service.readSession({ sessionId, action: 'getBranchMenu', args: [] })).value;
|
|
66
|
+
}
|
|
67
|
+
const result = await service.configureSession(
|
|
68
|
+
{ sessionId, action: args.method, args: [args.input ?? {}] },
|
|
69
|
+
{ revision: 1 }
|
|
70
|
+
);
|
|
71
|
+
return result.value;
|
|
72
|
+
}
|
|
73
|
+
|
|
14
74
|
return async function executeSessionControl(args = {}, context = {}) {
|
|
15
75
|
const action = args.action;
|
|
16
|
-
if (
|
|
76
|
+
if (
|
|
77
|
+
action !== 'list' &&
|
|
78
|
+
action !== 'create' &&
|
|
79
|
+
action !== 'bots' &&
|
|
80
|
+
action !== 'worktree' &&
|
|
81
|
+
!TARGET_ACTIONS.has(action)
|
|
82
|
+
) {
|
|
17
83
|
throw new Error(`session: unsupported remote action "${action}"`);
|
|
18
84
|
}
|
|
19
85
|
const caller = context.callerSessionId;
|
|
@@ -22,8 +88,11 @@ export function createSessionControl({
|
|
|
22
88
|
}
|
|
23
89
|
// `callerAgentId`: set only for an attended agent conversation (workspace-tools.mjs).
|
|
24
90
|
if (action === 'create') return agentTasks.create(args, context);
|
|
91
|
+
if (action === 'worktree') return worktreeControl(args, caller, context.callerScope);
|
|
92
|
+
// `callerScope`: the caller's schedule-access scope (workspace-tools.mjs).
|
|
93
|
+
if (action === 'bots') return botStatus(args, context);
|
|
25
94
|
const sessionId = typeof args.session_id === 'string' ? args.session_id.trim() : '';
|
|
26
|
-
if (TARGET_ACTIONS.has(action) &&
|
|
95
|
+
if (TARGET_ACTIONS.has(action) && !SESSION_ID_PATTERN.test(sessionId)) {
|
|
27
96
|
throw new Error(`session: session_id is required for action=${action}`);
|
|
28
97
|
}
|
|
29
98
|
if (MUTATING_ACTIONS.has(action) && sessionId === caller) {
|
|
@@ -45,31 +114,121 @@ export function createSessionControl({
|
|
|
45
114
|
const service = getSessionService();
|
|
46
115
|
if (!service) throw new Error('session: session service is unavailable');
|
|
47
116
|
if (action === 'list') {
|
|
48
|
-
|
|
49
|
-
|
|
117
|
+
for (const flag of ['include_agents', 'include_archived']) {
|
|
118
|
+
if (args[flag] !== undefined && typeof args[flag] !== 'boolean') {
|
|
119
|
+
throw new Error(`session: ${flag} must be a boolean`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Scoped like bots (`callerScope`, bot-status.mjs): the human's sessions
|
|
123
|
+
// list everything, a bot (or its unattended run) only its own sessions,
|
|
124
|
+
// anything else the plain rows without previews. Sub-agent sessions (a
|
|
125
|
+
// parent finds its own through the agent tool) and archived ones (the
|
|
126
|
+
// desktop's flag) only on request; the scan pages past the rows left
|
|
127
|
+
// out, so a page is never short while more rows match.
|
|
128
|
+
const own = scopedBot(context.callerScope);
|
|
129
|
+
const archived = (await readSessionSidebarState())?.archived ?? {};
|
|
130
|
+
const keep = (row) =>
|
|
131
|
+
(!own || sessionBotOf(row) === own) &&
|
|
132
|
+
(args.include_agents === true || !isAgentOnlySession(row)) &&
|
|
133
|
+
(args.include_archived === true || !Object.hasOwn(archived, row.id));
|
|
134
|
+
// Bounded: past 10000 rows scanned with fewer than `limit` matching, the
|
|
135
|
+
// page ends (possibly empty) with a nextCursor to continue from.
|
|
136
|
+
const scan = await scanCatalog(service, keep, { cursor: args.cursor || null, want: limit, maxRows: 10_000 });
|
|
137
|
+
const sessions = scan.rows.map((row) => (Object.hasOwn(archived, row.id) ? { ...row, archived: true } : row));
|
|
138
|
+
return sessionListOutput({ sessions, nextCursor: scan.nextCursor }, limit, { rich: own !== null });
|
|
50
139
|
}
|
|
51
140
|
if (action === 'send') {
|
|
52
141
|
if (typeof args.prompt !== 'string' || !args.prompt.trim()) {
|
|
53
142
|
throw new Error('session: prompt is required for action=send');
|
|
54
143
|
}
|
|
144
|
+
// A room member's session is the room's to drive: a message goes to the
|
|
145
|
+
// room, naming the member.
|
|
146
|
+
if (roomMemberOfSession(sessionId)) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
`session: ${sessionId} is a group-room member's session; send to its room (session_id ${roomSessionId(roomMemberOfSession(sessionId).roomId)}) with to: <member>`
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
// A send to a room's log is a message to one member there (`to`, or a
|
|
152
|
+
// leading @name), run by the desktop room host; the member's turn in
|
|
153
|
+
// its member session is the turn that answers and reports.
|
|
154
|
+
const room = roomIdOfSession(sessionId) ? await roomAddressee(sessionId, args) : null;
|
|
155
|
+
if (room?.sessionId === caller) throw new Error('session: send must target another session');
|
|
55
156
|
// An agent conversation's send reports its turn back to the agent's
|
|
56
157
|
// home: a task session it created by its stored origin, any other
|
|
57
158
|
// session by an origin for this send only.
|
|
58
159
|
// Forwarded files ride along as stored attachment parts (workspace-tools.mjs).
|
|
59
|
-
const prompt = handoffContent(args.prompt, context.attachmentParts);
|
|
60
|
-
const
|
|
160
|
+
const prompt = handoffContent(room ? room.text : args.prompt, context.attachmentParts);
|
|
161
|
+
const turnSessionId = room ? room.sessionId : sessionId;
|
|
162
|
+
const from = { sessionId: caller, ...(context.callerAgentId ? { agentId: context.callerAgentId } : {}) };
|
|
163
|
+
// The member's turn carries the send's hop (`transcriptMeta.hop`), so a
|
|
164
|
+
// chain through the room counts on toward MAX_BOT_HOPS.
|
|
165
|
+
const submit = room
|
|
166
|
+
? async ({ id, onSettled, follow, transcriptMeta } = {}) => ({
|
|
167
|
+
accepted:
|
|
168
|
+
(await room.host.ask(sessionId, {
|
|
169
|
+
agentId: room.agentId,
|
|
170
|
+
prompt,
|
|
171
|
+
from,
|
|
172
|
+
...(id ? { id } : {}),
|
|
173
|
+
...(transcriptMeta?.hop > 0 ? { hop: transcriptMeta.hop } : {}),
|
|
174
|
+
...(onSettled ? { onSettled } : {}),
|
|
175
|
+
...(follow ? { follow } : {}),
|
|
176
|
+
})) === true,
|
|
177
|
+
})
|
|
178
|
+
: null;
|
|
179
|
+
const addressed = room ? { to: room.agentId } : {};
|
|
180
|
+
let origin = await agentTasks.reportOrigin(turnSessionId, context.callerAgentId, caller);
|
|
181
|
+
// A send made in a bot-descended turn (`callerHop` > 0), or by a bot to
|
|
182
|
+
// another session, extends the chain by one; a bot's own task session
|
|
183
|
+
// only continues it. Refused past the limit, whatever the target.
|
|
184
|
+
const turnHop = Number(context.callerHop) || 0;
|
|
185
|
+
const chained = (hop) => {
|
|
186
|
+
if (hop > MAX_BOT_HOPS) throw new Error(BOT_HOP_LIMIT_ERROR);
|
|
187
|
+
return hop;
|
|
188
|
+
};
|
|
61
189
|
if (origin) {
|
|
62
|
-
const
|
|
63
|
-
|
|
190
|
+
const hop = chained(origin.target === 'session' ? turnHop + 1 : turnHop);
|
|
191
|
+
if (hop > 0) origin = { ...origin, hop };
|
|
192
|
+
// The task session a bot created acts as the sending conversation does
|
|
193
|
+
// from now on (attended chat or run); another's session keeps its own.
|
|
194
|
+
if (origin.target !== 'session') await rebindDelegation(sessionId, caller);
|
|
195
|
+
const sent = await agentTasks.send(turnSessionId, prompt, origin, submit);
|
|
196
|
+
return { sessionId, ...addressed, ...sent, ...(hop > 0 ? { hop } : {}) };
|
|
64
197
|
}
|
|
65
|
-
const
|
|
198
|
+
const hop = turnHop > 0 ? chained(turnHop + 1) : 0;
|
|
199
|
+
let accepted;
|
|
200
|
+
if (submit) accepted = (await submit(hop > 0 ? { transcriptMeta: { hop } } : {})).accepted;
|
|
201
|
+
else {
|
|
202
|
+
// New work from this sender: a delegated target acts as the sender does.
|
|
203
|
+
await rebindDelegation(sessionId, caller);
|
|
204
|
+
const result = await service.submitSession({
|
|
205
|
+
sessionId,
|
|
206
|
+
prompt,
|
|
207
|
+
options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...(hop > 0 ? { hop } : {}) } },
|
|
208
|
+
});
|
|
209
|
+
accepted = result.accepted === true;
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
66
212
|
sessionId,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
213
|
+
...addressed,
|
|
214
|
+
accepted,
|
|
215
|
+
reportsBack: false,
|
|
216
|
+
...(accepted ? { reportsBackReason: NOT_BOT_REASON } : {}),
|
|
217
|
+
...(hop > 0 ? { hop } : {}),
|
|
218
|
+
};
|
|
71
219
|
}
|
|
72
220
|
if (action === 'cancel') {
|
|
221
|
+
// A room's exchange is run by the desktop room host, so its stop (the UI
|
|
222
|
+
// stop button) ends it; the log is not a session the service can abort.
|
|
223
|
+
if (roomIdOfSession(sessionId)) {
|
|
224
|
+
let host;
|
|
225
|
+
try {
|
|
226
|
+
host = agentRoomHost();
|
|
227
|
+
} catch (error) {
|
|
228
|
+
throw new Error(`session: cannot cancel ${sessionId}: ${error.message}`);
|
|
229
|
+
}
|
|
230
|
+
return { sessionId, aborted: host.stop(sessionId) === true };
|
|
231
|
+
}
|
|
73
232
|
const result = await service.abortSession({ sessionId });
|
|
74
233
|
return { sessionId, aborted: result.aborted === true };
|
|
75
234
|
}
|
|
@@ -91,7 +250,7 @@ export function createSessionControl({
|
|
|
91
250
|
});
|
|
92
251
|
const snapshot = result.full;
|
|
93
252
|
if (!snapshot) throw new Error(`session: ${sessionId} is unavailable`);
|
|
94
|
-
|
|
253
|
+
return {
|
|
95
254
|
sessionId,
|
|
96
255
|
title: snapshot.title ?? null,
|
|
97
256
|
cwd: snapshot.cwd ?? null,
|
|
@@ -100,6 +259,5 @@ export function createSessionControl({
|
|
|
100
259
|
busy: snapshot.busy === true,
|
|
101
260
|
quotaResume: snapshot.quotaResume ?? null,
|
|
102
261
|
};
|
|
103
|
-
return status;
|
|
104
262
|
};
|
|
105
263
|
}
|
|
@@ -184,6 +184,10 @@ export function createDaemonTelemetry({
|
|
|
184
184
|
log = () => {},
|
|
185
185
|
getWork = () => ({}),
|
|
186
186
|
onInterval = null,
|
|
187
|
+
// Runs once when the loop starts, before its first window: a probe that
|
|
188
|
+
// judges each window (the lag profiler) arms here so the first one covers
|
|
189
|
+
// boot instead of starting only at the first tick.
|
|
190
|
+
onStart = null,
|
|
187
191
|
now,
|
|
188
192
|
pid,
|
|
189
193
|
memoryUsage,
|
|
@@ -239,6 +243,11 @@ export function createDaemonTelemetry({
|
|
|
239
243
|
}, ms);
|
|
240
244
|
handle?.unref?.();
|
|
241
245
|
timer = handle;
|
|
246
|
+
try {
|
|
247
|
+
onStart?.();
|
|
248
|
+
} catch {
|
|
249
|
+
/* a start probe must not stop the sample loop */
|
|
250
|
+
}
|
|
242
251
|
return timer;
|
|
243
252
|
}
|
|
244
253
|
|
|
@@ -359,6 +359,11 @@ slowSpans.setLog(log);
|
|
|
359
359
|
daemonTelemetry = createDaemonTelemetry({
|
|
360
360
|
log,
|
|
361
361
|
getWork: inFlightWork,
|
|
362
|
+
// Arms the profiler at daemon-ready when lag-profile.on exists (a no-op
|
|
363
|
+
// without it), so the first window holds the startup stalls.
|
|
364
|
+
onStart() {
|
|
365
|
+
void lagProfiler.tick();
|
|
366
|
+
},
|
|
362
367
|
onInterval() {
|
|
363
368
|
// eventLoopDelay is reset at the end of every tick, so this status is the
|
|
364
369
|
// lag of the 30s window that just ended — the same window the lag
|
|
@@ -928,7 +933,14 @@ async function main() {
|
|
|
928
933
|
});
|
|
929
934
|
canonicalAgentControl = agentControl;
|
|
930
935
|
// Agents' cross-session sends and task sessions, and their report watches.
|
|
931
|
-
const agentTasks = createAgentTaskSessions({
|
|
936
|
+
const agentTasks = createAgentTaskSessions({
|
|
937
|
+
getSessionService: () => sessionService,
|
|
938
|
+
// A task session re-attached after a restart takes its agents' queued
|
|
939
|
+
// results through the owner runtime's notification bus.
|
|
940
|
+
deliverCompletion: (sessionId, text, meta) =>
|
|
941
|
+
sessionRuntimeHost?.notifySessionCompletion?.(sessionId, text, meta) === true,
|
|
942
|
+
settleAgentResults: async () => (await agentControl.canonicalAgentTool()).settleRestartFailures(),
|
|
943
|
+
});
|
|
932
944
|
const requestedRuntimeMode = String(process.env.MIXDOG_SESSION_RUNTIME_MODE || '')
|
|
933
945
|
.trim()
|
|
934
946
|
.toLowerCase();
|
|
@@ -990,15 +1002,26 @@ async function main() {
|
|
|
990
1002
|
busy: (sessionId) => sessionService.liveSessionBusy(sessionId),
|
|
991
1003
|
notice: (sessionId, notice) => sessionService.pushLiveSessionNotice(sessionId, notice),
|
|
992
1004
|
// A task session's result (session create): the agent relays it in one
|
|
993
|
-
// turn. Resolves
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1005
|
+
// turn. Resolves false when the turn was refused, else `{ settled }`, the
|
|
1006
|
+
// turn's end status ('done' when it finished).
|
|
1007
|
+
wake: async (sessionId, prompt, { id, hop = 0 } = {}) => {
|
|
1008
|
+
let settle = () => {};
|
|
1009
|
+
const settled = new Promise((resolveSettled) => {
|
|
1010
|
+
settle = resolveSettled;
|
|
1011
|
+
});
|
|
1012
|
+
const result = await sessionService.submitSession({
|
|
1013
|
+
sessionId,
|
|
1014
|
+
prompt,
|
|
1015
|
+
options: {
|
|
1016
|
+
mode: 'prompt',
|
|
1017
|
+
kickoff: true,
|
|
1018
|
+
...(id ? { id } : {}),
|
|
1019
|
+
...(hop > 0 ? { transcriptMeta: { hop } } : {}),
|
|
1020
|
+
onSettled: (detail) => settle(String(detail?.status || 'failed')),
|
|
1021
|
+
},
|
|
1022
|
+
});
|
|
1023
|
+
return result?.accepted === true ? { settled } : false;
|
|
1024
|
+
},
|
|
1002
1025
|
// A routine fire: one queued turn in its bot's thread (routine-home-turn.mjs).
|
|
1003
1026
|
submit: async (sessionId, prompt, options) =>
|
|
1004
1027
|
(await sessionService.submitSession({ sessionId, prompt, options }))?.accepted === true,
|
|
@@ -12,7 +12,7 @@ import { performance } from 'node:perf_hooks';
|
|
|
12
12
|
import { isDeepStrictEqual } from 'node:util';
|
|
13
13
|
import { bootProfile } from '../tui/session/boot-profile.mjs';
|
|
14
14
|
import { createGoalContinuation } from '../tui/session/goal-continuation.mjs';
|
|
15
|
-
import { createToolApproval } from '../tui/session/tool-approval.mjs';
|
|
15
|
+
import { createToolApproval, resolveToolApprovalTimeoutMs } from '../tui/session/tool-approval.mjs';
|
|
16
16
|
import { createToolCardResults } from '../tui/session/tool-card-results.mjs';
|
|
17
17
|
import { createAgentJobFeed } from '../tui/session/agent-job-feed.mjs';
|
|
18
18
|
import { createWorktreeSetupNotices } from '../tui/session/worktree-setup-notice.mjs';
|
|
@@ -41,13 +41,22 @@ import {
|
|
|
41
41
|
createTranscriptSpillBuffer,
|
|
42
42
|
sweepStaleTranscriptSpillDirsOnce,
|
|
43
43
|
} from '../tui/session/transcript-spill.mjs';
|
|
44
|
+
import { importInStages } from './staged-import.mjs';
|
|
44
45
|
|
|
45
46
|
const SESSION_RUNTIME_MODULE = '../mixdog-session-runtime.mjs';
|
|
47
|
+
// Its one module (only mixdog-session-runtime.mjs imports it): its boot
|
|
48
|
+
// modules are the graph's stages.
|
|
49
|
+
const SESSION_RUNTIME_CORE = '../session-runtime/runtime-core.mjs';
|
|
50
|
+
const importSessionRuntimeInStages = () =>
|
|
51
|
+
importInStages(
|
|
52
|
+
new URL(SESSION_RUNTIME_MODULE, import.meta.url).href,
|
|
53
|
+
new URL(SESSION_RUNTIME_CORE, import.meta.url).href
|
|
54
|
+
);
|
|
46
55
|
|
|
47
56
|
// Shared across create calls so concurrent session startups import the
|
|
48
57
|
// runtime graph once.
|
|
49
58
|
let sessionRuntimeModulePromise = null;
|
|
50
|
-
let sessionRuntimeImporter =
|
|
59
|
+
let sessionRuntimeImporter = importSessionRuntimeInStages;
|
|
51
60
|
function importSessionRuntimeModule() {
|
|
52
61
|
// A failed import is forgotten so the next caller retries lazily.
|
|
53
62
|
sessionRuntimeModulePromise ??= Promise.resolve()
|
|
@@ -79,14 +88,13 @@ export async function warmLocalSessionRuntime() {
|
|
|
79
88
|
|
|
80
89
|
/** Test seam: replace the dynamic import of the session-runtime module. */
|
|
81
90
|
export function setSessionRuntimeImporterForTest(importer) {
|
|
82
|
-
sessionRuntimeImporter = importer ||
|
|
91
|
+
sessionRuntimeImporter = importer || importSessionRuntimeInStages;
|
|
83
92
|
sessionRuntimeModulePromise = null;
|
|
84
93
|
}
|
|
85
94
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})();
|
|
95
|
+
// An approval waits until the user answers (Deny, Stop or a closing runtime
|
|
96
|
+
// settle it); MIXDOG_TOOL_APPROVAL_TIMEOUT_MS opts into a limit for tests/ops.
|
|
97
|
+
const TOOL_APPROVAL_TIMEOUT_MS = resolveToolApprovalTimeoutMs();
|
|
90
98
|
|
|
91
99
|
export {
|
|
92
100
|
cleanupStaleTranscriptSpillDirs,
|
|
@@ -306,15 +314,22 @@ export async function createLocalSessionRuntime({
|
|
|
306
314
|
pushItem,
|
|
307
315
|
replaceItems,
|
|
308
316
|
});
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
317
|
+
// A sub-agent's approvals also show in the top-level chat (human-gate/gate.mjs).
|
|
318
|
+
const { approvalSurface } = await import('../runtime/agent/orchestrator/session/human-gate/gate.mjs');
|
|
319
|
+
const {
|
|
320
|
+
presentNextToolApproval,
|
|
321
|
+
finishToolApproval,
|
|
322
|
+
denyAllToolApprovals,
|
|
323
|
+
requestToolApproval,
|
|
324
|
+
adoptDelegatedApprovals,
|
|
325
|
+
} = createToolApproval({
|
|
326
|
+
getState,
|
|
327
|
+
set,
|
|
328
|
+
nextId,
|
|
329
|
+
getDisposed: () => flags.disposed,
|
|
330
|
+
timeoutMs: TOOL_APPROVAL_TIMEOUT_MS,
|
|
331
|
+
surfaceOf: approvalSurface,
|
|
332
|
+
});
|
|
318
333
|
const runtimePulse = createRuntimePulse({
|
|
319
334
|
flags,
|
|
320
335
|
getState,
|
|
@@ -336,6 +351,8 @@ export async function createLocalSessionRuntime({
|
|
|
336
351
|
lifecycle.runtimePulseTimer = setInterval(() => {
|
|
337
352
|
headWatch.retarget();
|
|
338
353
|
runtimePulse();
|
|
354
|
+
// A sub-agent's approval made before this session loaded (or bound its id).
|
|
355
|
+
adoptDelegatedApprovals();
|
|
339
356
|
}, 2000);
|
|
340
357
|
lifecycle.runtimePulseTimer.unref?.();
|
|
341
358
|
|