mixdog 1.3.0 → 1.3.2
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/NOTICE.md +52 -9
- package/README.md +8 -4
- package/package.json +2 -2
- package/scripts/native-release-status.mjs +238 -0
- package/src/defaults/shipped-history.json +8 -1
- 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 +54 -4
- package/src/defaults/skills/setup/references/surfaces.md +23 -3
- package/src/defaults/skills/setup-guide/SKILL.md +17 -10
- 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/output-styles/common.md +13 -8
- package/src/rules/agent-mode/AGENT_MODE.md +9 -6
- package/src/rules/agent-mode/MIXY.md +11 -6
- package/src/rules/lead/LEAD.md +2 -2
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/20-research.md +2 -0
- 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 +81 -16
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -4
- 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 +80 -31
- 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 +67 -38
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +34 -16
- 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.mjs +11 -8
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +19 -1
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/lib/tool-call-wire-ids.mjs +65 -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-retry-profile.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +10 -2
- 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-responses-input.mjs +3 -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/provider-error-kind.mjs +14 -2
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +17 -0
- 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-storage.mjs +68 -22
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +5 -5
- 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 +12 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +17 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +41 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +2 -0
- 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 +21 -2
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +149 -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/execution-tail.mjs +14 -11
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +68 -18
- 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 +5 -1
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +1 -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 +230 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +156 -25
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +21 -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 +189 -105
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +111 -9
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +11 -14
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +38 -5
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +21 -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/loop/usage.mjs +46 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
- package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +99 -0
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -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/provider-replay.mjs +50 -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-lifecycle.mjs +62 -47
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +6 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +42 -10
- package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +35 -4
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +179 -16
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -1
- 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/sweep-record.mjs +8 -3
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +36 -1
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -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/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 +49 -14
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +134 -17
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +35 -13
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -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/lib/shell-job-records.mjs +6 -14
- 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 +34 -21
- 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/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/store.mjs +55 -30
- 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 +6 -3
- package/src/runtime/effort-judge/model-install.mjs +16 -8
- package/src/runtime/effort-judge/model-manifest.json +7 -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/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 +4 -0
- package/src/runtime/shared/agent-kind-migration.mjs +200 -0
- package/src/runtime/shared/agent-kind.mjs +152 -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-route-config.d.mts +1 -0
- package/src/runtime/shared/agent-route-config.mjs +22 -8
- package/src/runtime/shared/agent-store.mjs +149 -0
- 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 +30 -0
- package/src/runtime/shared/bot-split-migration.mjs +457 -0
- package/src/runtime/shared/bounded-download.mjs +4 -2
- package/src/runtime/shared/config-patch.mjs +20 -1
- package/src/runtime/shared/config.mjs +39 -9
- package/src/runtime/shared/connector-catalog.d.mts +1 -2
- package/src/runtime/shared/connector-catalog.mjs +2 -4
- package/src/runtime/shared/connector-triggers.mjs +2 -0
- 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 +7 -1
- package/src/runtime/shared/error-presentation.mjs +113 -10
- package/src/runtime/shared/file-has-data.mjs +28 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +20 -0
- package/src/runtime/shared/handoff-artifacts.mjs +61 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +6 -1
- package/src/runtime/shared/llm/usage-accounting.mjs +7 -1
- package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
- package/src/runtime/shared/model-route-fallback.mjs +79 -7
- package/src/runtime/shared/pending-agent-work.mjs +54 -0
- package/src/runtime/shared/plain-preview.mjs +22 -17
- 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/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/sensitive-path-rules.d.mts +15 -0
- package/src/runtime/shared/sensitive-path-rules.mjs +256 -0
- package/src/runtime/shared/session-baseline-store.mjs +8 -2
- 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 +6 -0
- 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 +44 -2
- package/src/runtime/shared/usage-readout-totals.mjs +15 -13
- package/src/runtime/shared/user-cwd.mjs +9 -4
- package/src/runtime/shared/user-data-guard.mjs +46 -44
- package/src/runtime/shared/utf8-cut.mjs +10 -0
- package/src/runtime/shared/worktrees/activity-gate.mjs +269 -61
- package/src/runtime/shared/worktrees/registry.mjs +26 -26
- package/src/runtime/tidy/core-install.mjs +26 -4
- package/src/runtime/tidy/install.mjs +91 -23
- package/src/runtime/web-search/lib/config.mjs +4 -16
- package/src/session-runtime/agent-home-delivery.mjs +859 -136
- package/src/session-runtime/agent-room-delivery.mjs +167 -19
- package/src/session-runtime/agent-task-sessions.mjs +831 -69
- package/src/session-runtime/agent-tool-routing.mjs +1 -0
- package/src/session-runtime/boot/apis.mjs +58 -24
- package/src/session-runtime/boot/config.mjs +1 -0
- package/src/session-runtime/boot/facade.mjs +11 -1
- package/src/session-runtime/boot/infrastructure.mjs +14 -2
- package/src/session-runtime/boot/providers.mjs +16 -6
- package/src/session-runtime/boot/shared.mjs +12 -6
- package/src/session-runtime/boot/tools.mjs +2 -2
- 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 +78 -32
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
- package/src/session-runtime/handoff-attachments.mjs +593 -0
- package/src/session-runtime/held-requests.mjs +36 -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 +45 -6
- 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-route/route-persist.mjs +2 -2
- package/src/session-runtime/model-route/route-tuning.mjs +11 -2
- package/src/session-runtime/model-route/set-route.mjs +82 -2
- package/src/session-runtime/native-web-search.mjs +2 -2
- package/src/session-runtime/new-session-config.mjs +6 -1
- package/src/session-runtime/owned-automation-run.mjs +8 -1
- package/src/session-runtime/room-member-gate.mjs +16 -3
- package/src/session-runtime/route-resolution.mjs +21 -19
- 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-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/helpers.mjs +24 -5
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +36 -24
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -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 +12 -6
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +5 -8
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- 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 +14 -4
- 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/session-create/materialize.mjs +2 -3
- package/src/session-runtime/session-create/session-options.mjs +15 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +63 -1
- package/src/session-runtime/settings-compaction-api.mjs +86 -39
- package/src/session-runtime/setup-tool/executor.mjs +20 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +19 -7
- package/src/session-runtime/setup-tool/settings-contract.mjs +37 -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 +265 -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 +165 -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 +47 -358
- package/src/session-runtime/tool-surface.mjs +5 -3
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +99 -81
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +2 -1
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +578 -301
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +113 -53
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +11 -4
- 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/workspace-state.mjs +7 -6
- package/src/standalone/daemon-agent-control.mjs +4 -1
- package/src/standalone/daemon-session-control.mjs +60 -11
- package/src/standalone/daemon.mjs +34 -4
- package/src/standalone/local-session-runtime.mjs +22 -14
- package/src/standalone/session-client.mjs +7 -2
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +46 -3
- package/src/standalone/session-service/agent-tree.mjs +4 -3
- package/src/standalone/session-service/session-calls/session-turns.mjs +19 -0
- package/src/standalone/session-service.mjs +11 -0
- package/src/standalone/session-state-projection.mjs +19 -9
- package/src/standalone/session-tool-output.mjs +35 -9
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
- 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 +599 -342
- package/src/tui/prompt-history-store.mjs +16 -21
- package/src/tui/session/context-state.mjs +4 -0
- package/src/tui/session/notice-surface.mjs +3 -4
- package/src/tui/session/session-api/intake/abort.mjs +19 -1
- package/src/tui/session/session-api/media.mjs +2 -1
- package/src/tui/session/session-api/routes-agent-definitions.mjs +75 -0
- package/src/tui/session/session-api/routes-write.mjs +203 -0
- package/src/tui/session/session-api/routes.mjs +23 -236
- 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 +185 -20
- package/src/tui/session/transcript-intake.mjs +4 -0
- package/src/tui/session/turn-live-call.mjs +11 -3
- package/src/tui/session/turn.mjs +36 -17
- 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
|
@@ -4,8 +4,22 @@ import { isHiddenAgent } from '../../runtime/agent/orchestrator/internal-agents.
|
|
|
4
4
|
import { normalizeWorkflowRoute } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
5
5
|
import { ensureProviderEnabled } from '../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
6
6
|
import { resolveRouteContextState, selectionFastCapable } from '../route-state.mjs';
|
|
7
|
-
import {
|
|
8
|
-
|
|
7
|
+
import {
|
|
8
|
+
canonicalizeAgentRouteStorage,
|
|
9
|
+
isAgentDisabled,
|
|
10
|
+
withAgentDisabled,
|
|
11
|
+
} from '../../runtime/shared/agent-route-config.mjs';
|
|
12
|
+
import { agentEditorId, resolveDataDir } from './shared.mjs';
|
|
13
|
+
import {
|
|
14
|
+
isStoreBot,
|
|
15
|
+
readBotRoute,
|
|
16
|
+
readMixyRoute,
|
|
17
|
+
writeBotRoute,
|
|
18
|
+
writeMixyRoute,
|
|
19
|
+
} from '../../runtime/shared/agent-store.mjs';
|
|
20
|
+
|
|
21
|
+
/** Mixy's runtime id (agent-home.mjs MIXY_AGENT_ID). */
|
|
22
|
+
const MIXY_RUNTIME_ID = 'lead';
|
|
9
23
|
import { routeChain, validateRouteChainProviders } from '../../runtime/shared/model-route-chain.mjs';
|
|
10
24
|
|
|
11
25
|
// Agent route persistence. Route-scope isolation: an agent route owns its
|
|
@@ -15,16 +29,86 @@ import { routeChain, validateRouteChainProviders } from '../../runtime/shared/mo
|
|
|
15
29
|
// lead preset, so an agent that reused it silently rewrote Main's effort/fast
|
|
16
30
|
// for the next session. The agent's own stored route is the fallback instead,
|
|
17
31
|
// and the bucket is never written here.
|
|
32
|
+
// Tuning-only edits keep the stored model's effort/fast/modelParameters;
|
|
33
|
+
// a model change starts from the resolved defaults. Fast is then clamped
|
|
34
|
+
// to what the selected model supports. The ONE normalizer of a chain entry:
|
|
35
|
+
// agents, bots, Mixy and the Lead's fallbacks all pass through it.
|
|
36
|
+
export async function resolveChainEntry(deps, requested, stored) {
|
|
37
|
+
const { getConfig, resolveRoute, lookupModelMeta, ensureProvidersReady } = deps;
|
|
38
|
+
let selectedRoute = resolveRoute(getConfig(), requested);
|
|
39
|
+
const sameModel =
|
|
40
|
+
clean(selectedRoute.provider) === clean(stored.provider) && clean(selectedRoute.model) === clean(stored.model);
|
|
41
|
+
const inheritedEffort = sameModel ? stored.effort || null : null;
|
|
42
|
+
const inheritedModelParameters = sameModel ? stored.modelParameters || {} : {};
|
|
43
|
+
// A requested percent replaces the stored exact window and requested
|
|
44
|
+
// tokens replace the stored percent.
|
|
45
|
+
const requestsPercent = requested.contextPercent !== undefined;
|
|
46
|
+
const requestsTokens = requested.contextTokens !== undefined;
|
|
47
|
+
const inheritedContextPercent = sameModel && !requestsTokens ? stored.contextPercent : undefined;
|
|
48
|
+
const inheritedContextTokens = sameModel && !requestsPercent ? stored.contextTokens : undefined;
|
|
49
|
+
selectedRoute = {
|
|
50
|
+
...selectedRoute,
|
|
51
|
+
effort: requested.effort !== undefined ? selectedRoute.effort : inheritedEffort,
|
|
52
|
+
fast: requested.fast !== undefined ? selectedRoute.fast === true : sameModel && stored.fast === true,
|
|
53
|
+
// Main's modelSettings bucket must not decide an agent's Auto effort.
|
|
54
|
+
autoEffort:
|
|
55
|
+
requested.autoEffort !== undefined ? requested.autoEffort !== false : !sameModel || stored.autoEffort !== false,
|
|
56
|
+
modelParameters: requested.modelParameters !== undefined ? selectedRoute.modelParameters : inheritedModelParameters,
|
|
57
|
+
// resolveRoute reads contextPercent from Main's modelSettings bucket;
|
|
58
|
+
// an agent route owns its own.
|
|
59
|
+
contextPercent: requestsPercent ? requested.contextPercent : inheritedContextPercent,
|
|
60
|
+
contextTokens: requestsTokens ? requested.contextTokens : inheritedContextTokens,
|
|
61
|
+
};
|
|
62
|
+
await ensureProvidersReady(ensureProviderEnabled(getConfig(), selectedRoute.provider));
|
|
63
|
+
const modelMeta = await lookupModelMeta(selectedRoute.provider, selectedRoute.model);
|
|
64
|
+
// Stored clamped, and not at all at the default window, as for Main.
|
|
65
|
+
const contextState = resolveRouteContextState(selectedRoute, modelMeta);
|
|
66
|
+
if (contextState.contextDefaultPercent !== undefined) selectedRoute.contextTokens = contextState.contextTokens;
|
|
67
|
+
const fastCapable = selectionFastCapable(
|
|
68
|
+
selectedRoute.provider,
|
|
69
|
+
modelMeta,
|
|
70
|
+
selectedRoute.effort,
|
|
71
|
+
selectedRoute.modelParameters
|
|
72
|
+
);
|
|
73
|
+
return { ...selectedRoute, fast: fastCapable ? selectedRoute.fast === true : false };
|
|
74
|
+
}
|
|
75
|
+
|
|
18
76
|
export function createAgentRouteApi(deps) {
|
|
19
|
-
const { getConfig, resolveRoute,
|
|
20
|
-
deps;
|
|
77
|
+
const { getConfig, resolveRoute, saveConfigAndAdopt, agentRouteFromConfig } = deps;
|
|
21
78
|
|
|
22
79
|
function saveDisabled(id, disabled) {
|
|
23
80
|
saveConfigAndAdopt(canonicalizeAgentRouteStorage(withAgentDisabled(getConfig(), id, disabled)));
|
|
24
81
|
}
|
|
25
82
|
|
|
83
|
+
// A bot of the store keeps its route in its own folder (agent-store.mjs);
|
|
84
|
+
// Mixy (`lead` here, its runtime id) keeps its own in bots/mixy — never the
|
|
85
|
+
// Lead's route, which the Main route setter owns.
|
|
86
|
+
const dataDir = () => (deps.cfgMod || deps.STANDALONE_DATA_DIR ? resolveDataDir(deps) : '');
|
|
87
|
+
const isMixy = (id) => id === MIXY_RUNTIME_ID && Boolean(dataDir());
|
|
88
|
+
const storeBot = (id) => isStoreBot(dataDir(), id);
|
|
89
|
+
function saveRoute(id, route, keepOff) {
|
|
90
|
+
if (isMixy(id)) {
|
|
91
|
+
writeMixyRoute(dataDir(), route);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (storeBot(id)) {
|
|
95
|
+
writeBotRoute(dataDir(), id, route);
|
|
96
|
+
saveDisabled(id, keepOff);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const nextConfig = withAgentDisabled(getConfig(), id, keepOff);
|
|
100
|
+
nextConfig.agents = { ...(nextConfig.agents || {}), [id]: route };
|
|
101
|
+
saveConfigAndAdopt(canonicalizeAgentRouteStorage(nextConfig));
|
|
102
|
+
}
|
|
103
|
+
|
|
26
104
|
// Only an explicitly empty provider removes an override: the agent inherits Main.
|
|
27
105
|
function clearOverride(id) {
|
|
106
|
+
if (isMixy(id) || storeBot(id)) {
|
|
107
|
+
if (isMixy(id)) writeMixyRoute(dataDir(), null);
|
|
108
|
+
else writeBotRoute(dataDir(), id, null);
|
|
109
|
+
const inherited = normalizeWorkflowRoute(resolveRoute(getConfig(), {}));
|
|
110
|
+
return { ...(inherited || {}), inherited: true };
|
|
111
|
+
}
|
|
28
112
|
const nextConfig = { ...getConfig() };
|
|
29
113
|
const agents = { ...(nextConfig.agents || {}) };
|
|
30
114
|
const hadOverride = Object.hasOwn(agents, id);
|
|
@@ -35,55 +119,25 @@ export function createAgentRouteApi(deps) {
|
|
|
35
119
|
return { ...(inherited || {}), inherited: true };
|
|
36
120
|
}
|
|
37
121
|
|
|
38
|
-
// Tuning-only edits keep the stored model's effort/fast/modelParameters;
|
|
39
|
-
// a model change starts from the resolved defaults. Fast is then clamped
|
|
40
|
-
// to what the selected model supports.
|
|
41
|
-
async function resolveSelectedRoute(requested, stored) {
|
|
42
|
-
let selectedRoute = resolveRoute(getConfig(), requested);
|
|
43
|
-
const sameModel =
|
|
44
|
-
clean(selectedRoute.provider) === clean(stored.provider) && clean(selectedRoute.model) === clean(stored.model);
|
|
45
|
-
const inheritedEffort = sameModel ? stored.effort || null : null;
|
|
46
|
-
const inheritedModelParameters = sameModel ? stored.modelParameters || {} : {};
|
|
47
|
-
// A requested percent replaces the stored exact window and requested
|
|
48
|
-
// tokens replace the stored percent.
|
|
49
|
-
const requestsPercent = requested.contextPercent !== undefined;
|
|
50
|
-
const requestsTokens = requested.contextTokens !== undefined;
|
|
51
|
-
const inheritedContextPercent = sameModel && !requestsTokens ? stored.contextPercent : undefined;
|
|
52
|
-
const inheritedContextTokens = sameModel && !requestsPercent ? stored.contextTokens : undefined;
|
|
53
|
-
selectedRoute = {
|
|
54
|
-
...selectedRoute,
|
|
55
|
-
effort: requested.effort !== undefined ? selectedRoute.effort : inheritedEffort,
|
|
56
|
-
fast: requested.fast !== undefined ? selectedRoute.fast === true : sameModel && stored.fast === true,
|
|
57
|
-
// Main's modelSettings bucket must not decide an agent's Auto effort.
|
|
58
|
-
autoEffort:
|
|
59
|
-
requested.autoEffort !== undefined ? requested.autoEffort !== false : !sameModel || stored.autoEffort !== false,
|
|
60
|
-
modelParameters:
|
|
61
|
-
requested.modelParameters !== undefined ? selectedRoute.modelParameters : inheritedModelParameters,
|
|
62
|
-
// resolveRoute reads contextPercent from Main's modelSettings bucket;
|
|
63
|
-
// an agent route owns its own.
|
|
64
|
-
contextPercent: requestsPercent ? requested.contextPercent : inheritedContextPercent,
|
|
65
|
-
contextTokens: requestsTokens ? requested.contextTokens : inheritedContextTokens,
|
|
66
|
-
};
|
|
67
|
-
await ensureProvidersReady(ensureProviderEnabled(getConfig(), selectedRoute.provider));
|
|
68
|
-
const modelMeta = await lookupModelMeta(selectedRoute.provider, selectedRoute.model);
|
|
69
|
-
// Stored clamped, and not at all at the default window, as for Main.
|
|
70
|
-
const contextState = resolveRouteContextState(selectedRoute, modelMeta);
|
|
71
|
-
if (contextState.contextDefaultPercent !== undefined) selectedRoute.contextTokens = contextState.contextTokens;
|
|
72
|
-
const fastCapable = selectionFastCapable(
|
|
73
|
-
selectedRoute.provider,
|
|
74
|
-
modelMeta,
|
|
75
|
-
selectedRoute.effort,
|
|
76
|
-
selectedRoute.modelParameters
|
|
77
|
-
);
|
|
78
|
-
return { ...selectedRoute, fast: fastCapable ? selectedRoute.fast === true : false };
|
|
79
|
-
}
|
|
80
|
-
|
|
81
122
|
async function setAgentRoute(agentId, next) {
|
|
82
123
|
const id = agentEditorId(agentId);
|
|
83
124
|
if (!id) throw new Error(`unknown agent "${agentId}"`);
|
|
84
125
|
if (isHiddenAgent(id)) throw new Error(`agent "${id}" is internal and has no configurable route`);
|
|
85
126
|
const requested = { ...(next || {}) };
|
|
86
|
-
|
|
127
|
+
// Compare-and-set: fill the route only while the agent has none. A route
|
|
128
|
+
// picked while the model resolved below stays (answered with `skipped`).
|
|
129
|
+
const onlyIfEmpty = requested.onlyIfEmpty === true;
|
|
130
|
+
delete requested.onlyIfEmpty;
|
|
131
|
+
const readStored = () => {
|
|
132
|
+
if (isMixy(id)) return readMixyRoute(dataDir()) || {};
|
|
133
|
+
if (storeBot(id)) return readBotRoute(dataDir(), id) || {};
|
|
134
|
+
return agentRouteFromConfig(getConfig(), id) || {};
|
|
135
|
+
};
|
|
136
|
+
const kept = () => ({ ...readStored(), id, skipped: true });
|
|
137
|
+
const stored = readStored();
|
|
138
|
+
if (onlyIfEmpty && clean(stored.provider)) return kept();
|
|
139
|
+
// Mixy is never off: its route request is a model pick alone.
|
|
140
|
+
if (isMixy(id)) delete requested.disabled;
|
|
87
141
|
// Off is an explicit state, stored apart from the route so the model the
|
|
88
142
|
// user picked survives and comes back when the agent is switched on. An
|
|
89
143
|
// off request that also carries a model saves that model and stays off.
|
|
@@ -121,16 +175,22 @@ export function createAgentRouteApi(deps) {
|
|
|
121
175
|
const previous = storedChain.find(
|
|
122
176
|
(candidate) => candidate.provider === entry.provider && candidate.model === entry.model
|
|
123
177
|
);
|
|
124
|
-
resolved.push(await
|
|
178
|
+
resolved.push(await resolveChainEntry(deps, entry, previous || {}));
|
|
125
179
|
}
|
|
126
180
|
const [primary, ...fallbacks] = resolved;
|
|
127
181
|
const routeToSave = normalizeWorkflowRoute({ ...primary, fallbacks });
|
|
128
182
|
if (!routeToSave) throw new Error('agent route requires provider and model');
|
|
183
|
+
// No await from here to the write: the emptiness checked is the emptiness
|
|
184
|
+
// written over. An off agent stays off when it was only back-filled.
|
|
185
|
+
// A store bot's or Mixy's route is read from its folder on disk right here.
|
|
186
|
+
// An agent routed in the config file may have been written by another
|
|
187
|
+
// process whose change notification is still pending: re-read it first.
|
|
188
|
+
if (onlyIfEmpty && !isMixy(id) && !storeBot(id)) deps.reloadFullConfig?.();
|
|
189
|
+
if (onlyIfEmpty && clean(readStored().provider)) return kept();
|
|
190
|
+
const stayOff = onlyIfEmpty ? isAgentDisabled(getConfig(), id) : keepOff;
|
|
129
191
|
// Picking a model is also the "on" switch unless the request keeps it off.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
saveConfigAndAdopt(canonicalizeAgentRouteStorage(nextConfig));
|
|
133
|
-
return keepOff ? { ...routeToSave, id, disabled: true } : routeToSave;
|
|
192
|
+
saveRoute(id, routeToSave, stayOff);
|
|
193
|
+
return stayOff ? { ...routeToSave, id, disabled: true } : routeToSave;
|
|
134
194
|
}
|
|
135
195
|
|
|
136
196
|
return { setAgentRoute };
|
|
@@ -25,6 +25,7 @@ function applyWorkflowSlots(workflowInput, draft) {
|
|
|
25
25
|
if (!normalized) continue;
|
|
26
26
|
draft.presets = upsertWorkflowPreset(draft.presets, 'lead', normalized);
|
|
27
27
|
draft.defaultPreset = workflowPresetId('lead');
|
|
28
|
+
draft.leadRoute = normalized;
|
|
28
29
|
} else if (slot === 'agent') {
|
|
29
30
|
if (normalized) draft.agentRoutes.worker = normalized;
|
|
30
31
|
else delete draft.agentRoutes.worker;
|
|
@@ -72,10 +73,13 @@ export function createOnboardingApi(deps) {
|
|
|
72
73
|
presets: Array.isArray(nextConfig.presets) ? nextConfig.presets.slice() : [],
|
|
73
74
|
defaultPreset: nextConfig.default,
|
|
74
75
|
agentRoutes: { ...(nextConfig.agents || {}) },
|
|
76
|
+
// The Lead route this save writes, from `defaultRoute` or `workflowRoutes.lead`.
|
|
77
|
+
leadRoute: null,
|
|
75
78
|
};
|
|
76
79
|
if (defaultRoute) {
|
|
77
80
|
draft.presets = upsertWorkflowPreset(draft.presets, 'lead', defaultRoute);
|
|
78
81
|
draft.defaultPreset = workflowPresetId('lead');
|
|
82
|
+
draft.leadRoute = defaultRoute;
|
|
79
83
|
}
|
|
80
84
|
const workflowInput =
|
|
81
85
|
payload.workflowRoutes && typeof payload.workflowRoutes === 'object' ? payload.workflowRoutes : {};
|
|
@@ -104,12 +108,15 @@ export function createOnboardingApi(deps) {
|
|
|
104
108
|
}
|
|
105
109
|
|
|
106
110
|
saveConfigAndAdopt(canonicalizeAgentRouteStorage(nextConfig));
|
|
107
|
-
|
|
111
|
+
// Whatever wrote the Lead route also moves the runtime Main route, in the
|
|
112
|
+
// same synchronous step as the save: a pending conditional backfill then
|
|
113
|
+
// finds a route that is not empty instead of overwriting this choice.
|
|
114
|
+
if (draft.leadRoute) {
|
|
108
115
|
setRouteState(
|
|
109
116
|
resolveRoute(getConfig(), {
|
|
110
|
-
provider:
|
|
111
|
-
model:
|
|
112
|
-
effort:
|
|
117
|
+
provider: draft.leadRoute.provider,
|
|
118
|
+
model: draft.leadRoute.model,
|
|
119
|
+
effort: draft.leadRoute.effort,
|
|
113
120
|
})
|
|
114
121
|
);
|
|
115
122
|
deps.invalidatePreSessionToolSurface?.();
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { oneLine } from '../../runtime/shared/clean.mjs';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
normalizeAgentId,
|
|
4
|
+
normalizeWorkflowId,
|
|
5
|
+
normalizeWorkflowRoute,
|
|
6
|
+
} from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
3
7
|
|
|
4
8
|
export function resolveDataDir({ cfgMod, STANDALONE_DATA_DIR }) {
|
|
5
9
|
return cfgMod.getPluginData?.() || STANDALONE_DATA_DIR;
|
|
@@ -35,10 +35,23 @@ export function createStyleAndModeApi(deps) {
|
|
|
35
35
|
return { ...freshStatus, appliedToCurrentSession };
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
// `{ scope: 'session' }` (the composer's selector in a session), like
|
|
39
|
+
// setWorkflow: a session with a conversation switches alone
|
|
40
|
+
// (switchSessionOrchestrationMode; deferred to its next turn while one
|
|
41
|
+
// runs) and the configured mode — the default for new sessions — stays.
|
|
42
|
+
// Otherwise the choice becomes the configured mode and an empty session
|
|
43
|
+
// picks it up in place.
|
|
44
|
+
async function setOrchestrationMode(mode, options = {}) {
|
|
39
45
|
if (!ORCHESTRATION_MODES.includes(mode)) {
|
|
40
46
|
throw new Error(`orchestration mode must be one of ${ORCHESTRATION_MODES.join(', ')}`);
|
|
41
47
|
}
|
|
48
|
+
if (options?.scope === 'session') {
|
|
49
|
+
const switched = await deps.switchSessionOrchestrationMode?.(mode);
|
|
50
|
+
if (switched) {
|
|
51
|
+
invalidateContextStatusCache();
|
|
52
|
+
return switched;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
42
55
|
saveConfigAndAdopt({ ...getConfig(), orchestrationMode: mode });
|
|
43
56
|
const applied = await deps.refreshEmptySessionToolPolicy?.();
|
|
44
57
|
deps.invalidatePreSessionToolSurface?.();
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
-
import { existsSync, mkdirSync, rmSync
|
|
2
|
+
import { existsSync, mkdirSync, rmSync } from 'node:fs';
|
|
3
|
+
import { writeFileAtomicSync } from '../../runtime/shared/atomic-file.mjs';
|
|
3
4
|
import { serializeFrontmatterDoc } from '../../runtime/shared/markdown-frontmatter.mjs';
|
|
4
5
|
import {
|
|
5
6
|
normalizeWorkflowId,
|
|
@@ -44,6 +45,7 @@ export function createWorkflowPacksApi(deps) {
|
|
|
44
45
|
name: workflow.name,
|
|
45
46
|
description: workflow.description,
|
|
46
47
|
source: workflow.source,
|
|
48
|
+
...(workflow.overridesBuiltIn ? { overridesBuiltIn: true } : {}),
|
|
47
49
|
active: workflow.id === active,
|
|
48
50
|
}));
|
|
49
51
|
}
|
|
@@ -106,9 +108,10 @@ export function createWorkflowPacksApi(deps) {
|
|
|
106
108
|
if (!absorbed) {
|
|
107
109
|
const dir = join(dataDir, 'workflows', id);
|
|
108
110
|
mkdirSync(dir, { recursive: true });
|
|
109
|
-
|
|
111
|
+
writeFileAtomicSync(
|
|
110
112
|
join(dir, 'WORKFLOW.md'),
|
|
111
|
-
serializeFrontmatterDoc({ id, name, ...(description ? { description } : {}) }, body)
|
|
113
|
+
serializeFrontmatterDoc({ id, name, ...(description ? { description } : {}) }, body),
|
|
114
|
+
{ backup: true, mode: 0o644 }
|
|
112
115
|
);
|
|
113
116
|
}
|
|
114
117
|
return getWorkflowPack(id);
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* resume (missing worktree → recovery), and carrying the Project's memory
|
|
5
5
|
* identity into a new worktree.
|
|
6
6
|
*/
|
|
7
|
-
import { existsSync,
|
|
8
|
-
import {
|
|
7
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { holdsNoData, writeFileAtomicSync } from '../../runtime/shared/atomic-file.mjs';
|
|
9
10
|
import { isWorktreeBound, nextRevision, normalizeSessionWorkspace } from '../../runtime/shared/worktrees/contract.mjs';
|
|
10
11
|
import { isWithin, samePath } from '../../runtime/shared/worktrees/paths.mjs';
|
|
11
12
|
import { resolveProjectId } from '../../runtime/memory/lib/project-id-resolver.mjs';
|
|
@@ -103,10 +104,10 @@ export function restoreWorkspaceAfterResume(session) {
|
|
|
103
104
|
*/
|
|
104
105
|
export function copyProjectIdentity(projectPath, worktreePath) {
|
|
105
106
|
const target = join(worktreePath, '.mixdog', 'project.id');
|
|
106
|
-
|
|
107
|
+
// An id file with no data (empty, or NUL-filled by a crash) is missing.
|
|
108
|
+
if (existsSync(target) && !holdsNoData(readFileSync(target))) return false;
|
|
107
109
|
const id = resolveProjectId(projectPath);
|
|
108
|
-
if (!id) return false;
|
|
109
|
-
|
|
110
|
-
writeFileSync(target, `${id}\n`, 'utf8');
|
|
110
|
+
if (!id || holdsNoData(id)) return false;
|
|
111
|
+
writeFileAtomicSync(target, `${id}\n`, { mode: 0o644 });
|
|
111
112
|
return true;
|
|
112
113
|
}
|
|
@@ -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
|
}
|
|
@@ -1,18 +1,25 @@
|
|
|
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 { createBotStatus, scanCatalog, scopedBot, sessionBotOf } from '../session-runtime/bot-status.mjs';
|
|
5
|
+
import { handoffContent } from '../session-runtime/handoff-attachments.mjs';
|
|
6
|
+
import { BOT_HOP_LIMIT_ERROR, MAX_BOT_HOPS } from '../runtime/shared/bot-hops.mjs';
|
|
7
|
+
import { rebindDelegation } from '../runtime/agent/orchestrator/session/human-gate/delegation.mjs';
|
|
4
8
|
|
|
5
9
|
const TARGET_ACTIONS = new Set(['status', 'read', 'send', 'cancel', 'delete']);
|
|
6
10
|
const MUTATING_ACTIONS = new Set(['send', 'cancel', 'delete']);
|
|
11
|
+
// Why a send from a conversation that is no bot's reports nothing back.
|
|
12
|
+
const NOT_BOT_REASON = 'only a bot conversation gets session results reported back; check that session for the result';
|
|
7
13
|
|
|
8
14
|
/** Model-facing session operations over the same service used by desktop and TUI. */
|
|
9
15
|
export function createSessionControl({
|
|
10
16
|
getSessionService,
|
|
11
17
|
agentTasks = createAgentTaskSessions({ getSessionService }),
|
|
18
|
+
botStatus = createBotStatus({ getSessionService }),
|
|
12
19
|
}) {
|
|
13
20
|
return async function executeSessionControl(args = {}, context = {}) {
|
|
14
21
|
const action = args.action;
|
|
15
|
-
if (action !== 'list' && action !== 'create' && !TARGET_ACTIONS.has(action)) {
|
|
22
|
+
if (action !== 'list' && action !== 'create' && action !== 'bots' && !TARGET_ACTIONS.has(action)) {
|
|
16
23
|
throw new Error(`session: unsupported remote action "${action}"`);
|
|
17
24
|
}
|
|
18
25
|
const caller = context.callerSessionId;
|
|
@@ -21,8 +28,10 @@ export function createSessionControl({
|
|
|
21
28
|
}
|
|
22
29
|
// `callerAgentId`: set only for an attended agent conversation (workspace-tools.mjs).
|
|
23
30
|
if (action === 'create') return agentTasks.create(args, context);
|
|
31
|
+
// `callerScope`: the caller's schedule-access scope (workspace-tools.mjs).
|
|
32
|
+
if (action === 'bots') return botStatus(args, context);
|
|
24
33
|
const sessionId = typeof args.session_id === 'string' ? args.session_id.trim() : '';
|
|
25
|
-
if (TARGET_ACTIONS.has(action) &&
|
|
34
|
+
if (TARGET_ACTIONS.has(action) && !SESSION_ID_PATTERN.test(sessionId)) {
|
|
26
35
|
throw new Error(`session: session_id is required for action=${action}`);
|
|
27
36
|
}
|
|
28
37
|
if (MUTATING_ACTIONS.has(action) && sessionId === caller) {
|
|
@@ -44,22 +53,63 @@ export function createSessionControl({
|
|
|
44
53
|
const service = getSessionService();
|
|
45
54
|
if (!service) throw new Error('session: session service is unavailable');
|
|
46
55
|
if (action === 'list') {
|
|
56
|
+
// Scoped like bots (`callerScope`, bot-status.mjs): the human's sessions
|
|
57
|
+
// list everything, a bot (or its unattended run) only its own sessions,
|
|
58
|
+
// anything else the plain rows without previews.
|
|
59
|
+
const own = scopedBot(context.callerScope);
|
|
60
|
+
if (own) {
|
|
61
|
+
const scan = await scanCatalog(service, (row) => sessionBotOf(row) === own, {
|
|
62
|
+
cursor: args.cursor || null,
|
|
63
|
+
want: limit,
|
|
64
|
+
});
|
|
65
|
+
return sessionListOutput({ sessions: scan.rows, nextCursor: scan.nextCursor }, limit);
|
|
66
|
+
}
|
|
47
67
|
const page = await service.listSessionCatalog({ page: { limit, cursor: args.cursor || null } });
|
|
48
|
-
return sessionListOutput(page, limit);
|
|
68
|
+
return sessionListOutput(page, limit, { rich: own === '' });
|
|
49
69
|
}
|
|
50
70
|
if (action === 'send') {
|
|
51
71
|
if (typeof args.prompt !== 'string' || !args.prompt.trim()) {
|
|
52
72
|
throw new Error('session: prompt is required for action=send');
|
|
53
73
|
}
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
74
|
+
// An agent conversation's send reports its turn back to the agent's
|
|
75
|
+
// home: a task session it created by its stored origin, any other
|
|
76
|
+
// session by an origin for this send only.
|
|
77
|
+
// Forwarded files ride along as stored attachment parts (workspace-tools.mjs).
|
|
78
|
+
const prompt = handoffContent(args.prompt, context.attachmentParts);
|
|
79
|
+
let origin = await agentTasks.reportOrigin(sessionId, context.callerAgentId, caller);
|
|
80
|
+
// A send made in a bot-descended turn (`callerHop` > 0), or by a bot to
|
|
81
|
+
// another session, extends the chain by one; a bot's own task session
|
|
82
|
+
// only continues it. Refused past the limit, whatever the target.
|
|
83
|
+
const turnHop = Number(context.callerHop) || 0;
|
|
84
|
+
const chained = (hop) => {
|
|
85
|
+
if (hop > MAX_BOT_HOPS) throw new Error(BOT_HOP_LIMIT_ERROR);
|
|
86
|
+
return hop;
|
|
87
|
+
};
|
|
88
|
+
if (origin) {
|
|
89
|
+
const hop = chained(origin.target === 'session' ? turnHop + 1 : turnHop);
|
|
90
|
+
if (hop > 0) origin = { ...origin, hop };
|
|
91
|
+
// The task session a bot created acts as the sending conversation does
|
|
92
|
+
// from now on (attended chat or run); another's session keeps its own.
|
|
93
|
+
if (origin.target !== 'session') await rebindDelegation(sessionId, caller);
|
|
94
|
+
const sent = await agentTasks.send(sessionId, prompt, origin);
|
|
95
|
+
return { sessionId, ...sent, ...(hop > 0 ? { hop } : {}) };
|
|
96
|
+
}
|
|
97
|
+
const hop = turnHop > 0 ? chained(turnHop + 1) : 0;
|
|
98
|
+
// New work from this sender: a delegated target acts as the sender does.
|
|
99
|
+
await rebindDelegation(sessionId, caller);
|
|
57
100
|
const result = await service.submitSession({
|
|
58
101
|
sessionId,
|
|
59
|
-
prompt
|
|
60
|
-
options: { mode: 'prompt', transcriptMeta: { sender: 'lead' } },
|
|
102
|
+
prompt,
|
|
103
|
+
options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...(hop > 0 ? { hop } : {}) } },
|
|
61
104
|
});
|
|
62
|
-
|
|
105
|
+
const accepted = result.accepted === true;
|
|
106
|
+
return {
|
|
107
|
+
sessionId,
|
|
108
|
+
accepted,
|
|
109
|
+
reportsBack: false,
|
|
110
|
+
...(accepted ? { reportsBackReason: NOT_BOT_REASON } : {}),
|
|
111
|
+
...(hop > 0 ? { hop } : {}),
|
|
112
|
+
};
|
|
63
113
|
}
|
|
64
114
|
if (action === 'cancel') {
|
|
65
115
|
const result = await service.abortSession({ sessionId });
|
|
@@ -83,7 +133,7 @@ export function createSessionControl({
|
|
|
83
133
|
});
|
|
84
134
|
const snapshot = result.full;
|
|
85
135
|
if (!snapshot) throw new Error(`session: ${sessionId} is unavailable`);
|
|
86
|
-
|
|
136
|
+
return {
|
|
87
137
|
sessionId,
|
|
88
138
|
title: snapshot.title ?? null,
|
|
89
139
|
cwd: snapshot.cwd ?? null,
|
|
@@ -92,6 +142,5 @@ export function createSessionControl({
|
|
|
92
142
|
busy: snapshot.busy === true,
|
|
93
143
|
quotaResume: snapshot.quotaResume ?? null,
|
|
94
144
|
};
|
|
95
|
-
return status;
|
|
96
145
|
};
|
|
97
146
|
}
|
|
@@ -96,6 +96,7 @@ import { createChannelsRuntimeLoader } from './daemon-channels-loader.mjs';
|
|
|
96
96
|
import { createDesktopRuntime } from './daemon-desktop-runtime.mjs';
|
|
97
97
|
import { createCanonicalAgentControl } from './daemon-agent-control.mjs';
|
|
98
98
|
import { createSessionControl } from './daemon-session-control.mjs';
|
|
99
|
+
import { createAgentTaskSessions } from '../session-runtime/agent-task-sessions.mjs';
|
|
99
100
|
import { flushAllIndexWrites } from '../session-runtime/services/agent-tool/index-write-queue.mjs';
|
|
100
101
|
import {
|
|
101
102
|
compareRuntimeVersions,
|
|
@@ -926,6 +927,15 @@ async function main() {
|
|
|
926
927
|
cwd: CWD,
|
|
927
928
|
});
|
|
928
929
|
canonicalAgentControl = agentControl;
|
|
930
|
+
// Agents' cross-session sends and task sessions, and their report watches.
|
|
931
|
+
const agentTasks = createAgentTaskSessions({
|
|
932
|
+
getSessionService: () => sessionService,
|
|
933
|
+
// A task session re-attached after a restart takes its agents' queued
|
|
934
|
+
// results through the owner runtime's notification bus.
|
|
935
|
+
deliverCompletion: (sessionId, text, meta) =>
|
|
936
|
+
sessionRuntimeHost?.notifySessionCompletion?.(sessionId, text, meta) === true,
|
|
937
|
+
settleAgentResults: async () => (await agentControl.canonicalAgentTool()).settleRestartFailures(),
|
|
938
|
+
});
|
|
929
939
|
const requestedRuntimeMode = String(process.env.MIXDOG_SESSION_RUNTIME_MODE || '')
|
|
930
940
|
.trim()
|
|
931
941
|
.toLowerCase();
|
|
@@ -939,7 +949,7 @@ async function main() {
|
|
|
939
949
|
log,
|
|
940
950
|
measureBootPhase: bootPhases.measure,
|
|
941
951
|
executeAgentControl: agentControl.execute,
|
|
942
|
-
executeSessionControl: createSessionControl({ getSessionService: () => sessionService }),
|
|
952
|
+
executeSessionControl: createSessionControl({ getSessionService: () => sessionService, agentTasks }),
|
|
943
953
|
});
|
|
944
954
|
// Codex-style runtime: daemon routing and independent async session actors
|
|
945
955
|
// share one V8 isolate and module graph. CPU-heavy work stays in bounded
|
|
@@ -986,9 +996,27 @@ async function main() {
|
|
|
986
996
|
setAgentHomeLiveSurface({
|
|
987
997
|
busy: (sessionId) => sessionService.liveSessionBusy(sessionId),
|
|
988
998
|
notice: (sessionId, notice) => sessionService.pushLiveSessionNotice(sessionId, notice),
|
|
989
|
-
// A task session's result (session create): the agent relays it in one
|
|
990
|
-
|
|
991
|
-
|
|
999
|
+
// A task session's result (session create): the agent relays it in one
|
|
1000
|
+
// turn. Resolves false when the turn was refused, else `{ settled }`, the
|
|
1001
|
+
// turn's end status ('done' when it finished).
|
|
1002
|
+
wake: async (sessionId, prompt, { id, hop = 0 } = {}) => {
|
|
1003
|
+
let settle = () => {};
|
|
1004
|
+
const settled = new Promise((resolveSettled) => {
|
|
1005
|
+
settle = resolveSettled;
|
|
1006
|
+
});
|
|
1007
|
+
const result = await sessionService.submitSession({
|
|
1008
|
+
sessionId,
|
|
1009
|
+
prompt,
|
|
1010
|
+
options: {
|
|
1011
|
+
mode: 'prompt',
|
|
1012
|
+
kickoff: true,
|
|
1013
|
+
...(id ? { id } : {}),
|
|
1014
|
+
...(hop > 0 ? { transcriptMeta: { hop } } : {}),
|
|
1015
|
+
onSettled: (detail) => settle(String(detail?.status || 'failed')),
|
|
1016
|
+
},
|
|
1017
|
+
});
|
|
1018
|
+
return result?.accepted === true ? { settled } : false;
|
|
1019
|
+
},
|
|
992
1020
|
// A routine fire: one queued turn in its bot's thread (routine-home-turn.mjs).
|
|
993
1021
|
submit: async (sessionId, prompt, options) =>
|
|
994
1022
|
(await sessionService.submitSession({ sessionId, prompt, options }))?.accepted === true,
|
|
@@ -997,6 +1025,8 @@ async function main() {
|
|
|
997
1025
|
// Results queued before a restart are posted now; results a finished run
|
|
998
1026
|
// could not queue (kept on its routine's record) are queued again.
|
|
999
1027
|
recoverScheduleResults().catch((error) => log(`routine results recovery failed: ${error?.message || error}`));
|
|
1028
|
+
// Agents' sends whose report an earlier process had not queued yet.
|
|
1029
|
+
agentTasks.recover().catch((error) => log(`agent task report recovery failed: ${error?.message || error}`));
|
|
1000
1030
|
recoverRoutineDeliveries().catch((error) => log(`routine delivery recovery failed: ${error?.message || error}`));
|
|
1001
1031
|
sessionTransport = createSessionTransport({
|
|
1002
1032
|
// ctx carries the CLIENT token: the session service refcounts views across
|
|
@@ -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';
|
|
@@ -83,10 +83,9 @@ export function setSessionRuntimeImporterForTest(importer) {
|
|
|
83
83
|
sessionRuntimeModulePromise = null;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})();
|
|
86
|
+
// An approval waits until the user answers (Deny, Stop or a closing runtime
|
|
87
|
+
// settle it); MIXDOG_TOOL_APPROVAL_TIMEOUT_MS opts into a limit for tests/ops.
|
|
88
|
+
const TOOL_APPROVAL_TIMEOUT_MS = resolveToolApprovalTimeoutMs();
|
|
90
89
|
|
|
91
90
|
export {
|
|
92
91
|
cleanupStaleTranscriptSpillDirs,
|
|
@@ -306,15 +305,22 @@ export async function createLocalSessionRuntime({
|
|
|
306
305
|
pushItem,
|
|
307
306
|
replaceItems,
|
|
308
307
|
});
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
308
|
+
// A sub-agent's approvals also show in the top-level chat (human-gate/gate.mjs).
|
|
309
|
+
const { approvalSurface } = await import('../runtime/agent/orchestrator/session/human-gate/gate.mjs');
|
|
310
|
+
const {
|
|
311
|
+
presentNextToolApproval,
|
|
312
|
+
finishToolApproval,
|
|
313
|
+
denyAllToolApprovals,
|
|
314
|
+
requestToolApproval,
|
|
315
|
+
adoptDelegatedApprovals,
|
|
316
|
+
} = createToolApproval({
|
|
317
|
+
getState,
|
|
318
|
+
set,
|
|
319
|
+
nextId,
|
|
320
|
+
getDisposed: () => flags.disposed,
|
|
321
|
+
timeoutMs: TOOL_APPROVAL_TIMEOUT_MS,
|
|
322
|
+
surfaceOf: approvalSurface,
|
|
323
|
+
});
|
|
318
324
|
const runtimePulse = createRuntimePulse({
|
|
319
325
|
flags,
|
|
320
326
|
getState,
|
|
@@ -336,6 +342,8 @@ export async function createLocalSessionRuntime({
|
|
|
336
342
|
lifecycle.runtimePulseTimer = setInterval(() => {
|
|
337
343
|
headWatch.retarget();
|
|
338
344
|
runtimePulse();
|
|
345
|
+
// A sub-agent's approval made before this session loaded (or bound its id).
|
|
346
|
+
adoptDelegatedApprovals();
|
|
339
347
|
}, 2000);
|
|
340
348
|
lifecycle.runtimePulseTimer.unref?.();
|
|
341
349
|
|
|
@@ -148,12 +148,12 @@ function request({
|
|
|
148
148
|
}
|
|
149
149
|
);
|
|
150
150
|
req.on('timeout', () => {
|
|
151
|
-
req.destroy(
|
|
151
|
+
req.destroy(sessionTimeoutError(method, urlPath));
|
|
152
152
|
});
|
|
153
153
|
req.on('error', reject);
|
|
154
154
|
if (deadlineMs > 0) {
|
|
155
155
|
deadlineTimer = setTimeout(() => {
|
|
156
|
-
const error =
|
|
156
|
+
const error = sessionTimeoutError(method, urlPath);
|
|
157
157
|
reject(error);
|
|
158
158
|
req.destroy(error);
|
|
159
159
|
}, deadlineMs);
|
|
@@ -163,6 +163,11 @@ function request({
|
|
|
163
163
|
});
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
+
/** No answer within the request's bound: the daemon may be busy with it, not gone. */
|
|
167
|
+
function sessionTimeoutError(method, urlPath) {
|
|
168
|
+
return Object.assign(new Error(`session timeout: ${method} ${urlPath}`), { code: 'ESESSIONTIMEOUT' });
|
|
169
|
+
}
|
|
170
|
+
|
|
166
171
|
/** /health within `timeoutMs` of total duration; null when it does not answer. */
|
|
167
172
|
export async function probeSessionHealth({ port, token, timeoutMs = 800 } = {}) {
|
|
168
173
|
try {
|