mixdog 1.4.2 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/scripts/build-shipped-history.mjs +15 -5
- package/scripts/gate-local.mjs +65 -19
- package/scripts/graph-parity.mjs +8 -3
- package/scripts/lib/gate-scheduler.mjs +2 -1
- package/scripts/lib/run-node-tests.mjs +17 -5
- package/scripts/lib/test-failure-summary.mjs +1 -8
- package/scripts/lib/test-spawn-ledger.mjs +33 -2
- package/scripts/post-release-check.mjs +26 -16
- package/scripts/provider-pingpong-live.mjs +1 -1
- package/scripts/prune-embedding-runtime.mjs +3 -1
- package/scripts/release-paths.mjs +7 -1
- package/src/defaults/shipped-history.json +20 -0
- package/src/defaults/skills/setup/SKILL.md +2 -2
- package/src/defaults/skills/setup/references/actions.md +16 -3
- package/src/defaults/skills/setup/references/surfaces.md +3 -0
- package/src/defaults/skills/setup-guide/SKILL.md +6 -1
- package/src/lib/instruction-text.cjs +36 -0
- package/src/lib/rules-builder.cjs +34 -20
- package/src/orchestration/balanced.md +23 -0
- package/src/orchestration/focused.md +22 -0
- package/src/orchestration/none.md +5 -0
- package/src/orchestration/swarm.md +24 -0
- package/src/rules/agent-mode/AGENT_MODE.md +3 -1
- package/src/rules/agent-mode/MIXY.md +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +0 -1
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +4 -2
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +0 -9
- package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +4 -4
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -1
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +199 -46
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +3 -5
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +9 -3
- package/src/runtime/agent/orchestrator/mcp/client.mjs +3 -5
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
- package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
- package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +30 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
- package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
- package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
- package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -48
- package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
- package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +9 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
- package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +1 -2
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +57 -26
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +19 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +19 -10
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +42 -6
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +11 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
- package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
- package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
- package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +14 -5
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +7 -3
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +27 -9
- package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -4
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
- package/src/runtime/attachments/attachment-reference.mjs +1 -1
- package/src/runtime/attachments/pdf-extract.mjs +1 -1
- package/src/runtime/attachments/store.d.mts +1 -0
- package/src/runtime/attachments/store.mjs +2 -2
- package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
- package/src/runtime/channels/lib/scheduler.mjs +33 -0
- package/src/runtime/channels/lib/schedules-db.mjs +11 -4
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
- package/src/runtime/channels/lib/whisper-server.mjs +12 -12
- package/src/runtime/channels/lib/worker-main.mjs +9 -31
- package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
- package/src/runtime/connectors/connector-accounts-mcp.mjs +169 -33
- package/src/runtime/connectors/gmail-app-password.mjs +2 -2
- package/src/runtime/connectors/google-mcp.mjs +1 -1
- package/src/runtime/effort-judge/judge-client.mjs +2 -2
- package/src/runtime/effort-judge/judge-input.mjs +4 -4
- package/src/runtime/explore/explorer.mjs +0 -5
- package/src/runtime/explore/tool.mjs +3 -3
- package/src/runtime/local-provider/hardware.mjs +1 -1
- package/src/runtime/media/adapters/codex-image.mjs +3 -3
- package/src/runtime/media/adapters/gemini-video.mjs +1 -1
- package/src/runtime/media/media-usage.mjs +1 -1
- package/src/runtime/media/store.mjs +1 -1
- package/src/runtime/memory/index.mjs +11 -1
- package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
- package/src/runtime/memory/lib/memory-embed.mjs +83 -14
- package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
- package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
- package/src/runtime/memory/lib/memory.mjs +17 -0
- package/src/runtime/memory/lib/pg/process.mjs +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
- package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
- package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
- package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
- package/src/runtime/office/capabilities.mjs +1 -1
- package/src/runtime/office/core/office-core.mjs +1 -1
- package/src/runtime/office/design/content-model.mjs +3 -3
- package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
- package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
- package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
- package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
- package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
- package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +8 -6
- package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
- package/src/runtime/shared/atomic-file.d.mts +8 -0
- package/src/runtime/shared/background-tasks.mjs +22 -4
- package/src/runtime/shared/background-wait.mjs +66 -0
- package/src/runtime/shared/child-guardian.mjs +17 -7
- package/src/runtime/shared/config.mjs +313 -16
- package/src/runtime/shared/connector-catalog.d.mts +4 -5
- package/src/runtime/shared/connector-catalog.mjs +11 -1
- package/src/runtime/shared/file-lock.mjs +8 -3
- package/src/runtime/shared/git-runner.mjs +7 -2
- package/src/runtime/shared/idle-gc.mjs +30 -7
- package/src/runtime/shared/llm/http-agent.mjs +8 -5
- package/src/runtime/shared/llm/system-proxy.mjs +2 -1
- package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
- package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
- package/src/runtime/shared/maintenance-schedule.mjs +109 -0
- package/src/runtime/shared/process-runner.mjs +8 -4
- package/src/runtime/shared/routine-trigger.d.mts +13 -0
- package/src/runtime/shared/routine-trigger.mjs +34 -0
- package/src/runtime/shared/run-child.d.mts +2 -1
- package/src/runtime/shared/run-child.mjs +70 -18
- package/src/runtime/shared/session-scratch.mjs +14 -2
- package/src/runtime/shared/shipped-definitions.mjs +7 -1
- package/src/runtime/shared/tool-card-model.golden.json +3 -12
- package/src/runtime/shared/tool-execution-contract.mjs +2 -0
- package/src/runtime/shared/tool-work-units.mjs +31 -6
- package/src/runtime/shared/turn-snapshot.mjs +26 -4
- package/src/runtime/shared/turn-worktree-snapshot.mjs +6 -11
- package/src/runtime/shared/worker-requests.mjs +17 -3
- package/src/runtime/shared/worktrees/branch-management.mjs +1 -5
- package/src/runtime/shared/worktrees/contract.mjs +16 -6
- package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
- package/src/runtime/shared/worktrees/disk.mjs +79 -2
- package/src/runtime/shared/worktrees/git.mjs +44 -11
- package/src/runtime/shared/worktrees/include.mjs +6 -4
- package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
- package/src/runtime/shared/worktrees/manager.mjs +772 -75
- package/src/runtime/shared/worktrees/settings.mjs +33 -7
- package/src/runtime/shared/worktrees/test-support.mjs +5 -1
- package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
- package/src/runtime/tidy/process.mjs +2 -1
- package/src/runtime/web-search/index.mjs +3 -22
- package/src/runtime/web-search/lib/web-tools.mjs +2 -2
- package/src/runtime/web-search/tool-defs.mjs +17 -26
- package/src/session-runtime/agent-profile-changes.mjs +55 -4
- package/src/session-runtime/boot/apis.mjs +27 -4
- package/src/session-runtime/boot/begin.mjs +2 -0
- package/src/session-runtime/boot/config.mjs +10 -1
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/providers.mjs +70 -3
- package/src/session-runtime/boot/session.mjs +2 -0
- package/src/session-runtime/boot/tools.mjs +69 -25
- package/src/session-runtime/channel-config-api.mjs +1 -0
- package/src/session-runtime/config-change-effects.mjs +179 -0
- package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
- package/src/session-runtime/config-lifecycle.mjs +160 -24
- package/src/session-runtime/conversation-import/discovery.mjs +86 -7
- package/src/session-runtime/conversation-import/service.mjs +3 -2
- package/src/session-runtime/goal-facade-api.mjs +49 -3
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +3 -11
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +18 -4
- package/src/session-runtime/internal-tool-executor.mjs +12 -19
- package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
- package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
- package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +4 -4
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/server-catalog.mjs +14 -3
- package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
- package/src/session-runtime/model-route/set-route.mjs +40 -7
- package/src/session-runtime/native-web-search/routes.mjs +3 -3
- package/src/session-runtime/provider-auth/refresh.mjs +6 -3
- package/src/session-runtime/provider-auth/setup.mjs +1 -1
- package/src/session-runtime/provider-readiness.mjs +53 -4
- package/src/session-runtime/resource-api.mjs +1 -1
- package/src/session-runtime/resource-extension-sync.mjs +4 -8
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +5 -1
- package/src/session-runtime/resource-mcp-secrets.mjs +3 -3
- package/src/session-runtime/resource-plugins-api.mjs +4 -0
- package/src/session-runtime/routine-executor.mjs +152 -0
- package/src/session-runtime/routine-home-turn.mjs +46 -5
- package/src/session-runtime/runtime-facade.mjs +5 -0
- package/src/session-runtime/runtime-feature-gates.mjs +2 -11
- package/src/session-runtime/schedule-session-run.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +110 -6
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +24 -6
- package/src/session-runtime/services/agent-tool.mjs +51 -1
- package/src/session-runtime/services/channel-admin.mjs +18 -0
- package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
- package/src/session-runtime/services/plugin-admin.mjs +4 -0
- package/src/session-runtime/services/seeds.mjs +7 -0
- package/src/session-runtime/services/usage-stats-model.mjs +32 -11
- package/src/session-runtime/session-create/materialize.mjs +4 -2
- package/src/session-runtime/session-create/session-options.mjs +2 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +1 -9
- package/src/session-runtime/setup-tool/connector-widen-approval.mjs +1 -1
- package/src/session-runtime/setup-tool/executor.mjs +8 -1
- package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
- package/src/session-runtime/setup-tool/tool-defs.mjs +26 -1
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
- package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
- package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
- package/src/session-runtime/tool-policy-refresh.mjs +182 -5
- package/src/session-runtime/tool-surface.mjs +38 -1
- package/src/session-runtime/turn/agent-ops.mjs +10 -2
- package/src/session-runtime/turn/session-ops.mjs +2 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
- package/src/session-runtime/turn/turn-run.mjs +1 -1
- package/src/session-runtime/webhook-session-run.mjs +2 -0
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +1 -4
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +3 -10
- package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
- package/src/session-runtime/workflow-agents-api.mjs +2 -0
- package/src/session-runtime/workspace/project-branches.mjs +1 -1
- package/src/session-runtime/workspace/session-view.mjs +1 -1
- package/src/session-runtime/workspace/transitions.mjs +20 -4
- package/src/session-runtime/workspace/worktree-maintenance.mjs +126 -6
- package/src/session-runtime/workspace/worktree-setup.mjs +13 -1
- package/src/session-runtime/workspace/worktree-tool.mjs +16 -0
- package/src/standalone/daemon-agent-control.mjs +25 -8
- package/src/standalone/daemon-desktop-runtime.mjs +6 -2
- package/src/standalone/daemon-lag-profiler.mjs +7 -7
- package/src/standalone/daemon.mjs +54 -2
- package/src/standalone/local-session-runtime.mjs +16 -0
- package/src/standalone/session-client/daemon-unavailable.mjs +1 -1
- package/src/standalone/session-protocol.mjs +11 -0
- package/src/standalone/session-service/agent-route-follow.mjs +23 -20
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
- package/src/standalone/session-service/quota-resume.mjs +9 -0
- package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
- package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
- package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
- package/src/standalone/session-service/session-calls.mjs +2 -1
- package/src/tui/App.jsx +8 -0
- package/src/tui/app/clipboard.mjs +1 -1
- package/src/tui/app/create-app-pickers.mjs +2 -0
- package/src/tui/app/doctor.mjs +2 -2
- package/src/tui/app/panel-signature.mjs +1 -1
- package/src/tui/app/settings-picker.mjs +53 -8
- package/src/tui/app/shell-layout/row-budgets.mjs +2 -2
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +1 -1
- package/src/tui/app/use-prompt-queue-history.mjs +2 -2
- package/src/tui/app/use-transcript-activity.mjs +1 -1
- package/src/tui/app/use-transcript-window/geometry.mjs +1 -1
- package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
- package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
- package/src/tui/components/question-panel-model.mjs +4 -4
- package/src/tui/components/tool-execution/standard-card.jsx +3 -4
- package/src/tui/components/user-message-skills.mjs +1 -1
- package/src/tui/dist/index.mjs +309 -30
- package/src/tui/markdown/render-ansi.mjs +1 -1
- package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
- package/src/tui/session/agent-job-feed.mjs +2 -0
- package/src/tui/session/context-state.mjs +3 -0
- package/src/tui/session/quota-resume.mjs +1 -1
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
- package/src/tui/session/session-api/routes-agent-definitions.mjs +5 -0
- package/src/tui/session/session-api/worktree.mjs +13 -1
- package/src/tui/session/session-flow/drain.mjs +11 -14
- package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
- package/src/tui/session/turn-quiet.mjs +1 -1
- package/src/tui/session/turn.mjs +3 -0
- package/src/tui/session/worktree-setup-notice.mjs +1 -1
- package/src/tui/spinner-meta.mjs +3 -3
- package/src/tui/spinner-verbs.mjs +2 -2
- package/src/defaults/skills/goal-management/SKILL.md +0 -169
- package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
- package/src/session-runtime/goal-tasks.mjs +0 -1
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
gmailAppPasswordValue,
|
|
7
7
|
connectorAccountServers,
|
|
8
8
|
} from '../runtime/shared/connector-catalog.mjs';
|
|
9
|
-
import { forgetConnectorAccountHealth
|
|
9
|
+
import { forgetConnectorAccountHealth } from '../runtime/connectors/connector-accounts-mcp.mjs';
|
|
10
10
|
import { oauthCredentialOf } from './resource-mcp-servers.mjs';
|
|
11
11
|
|
|
12
12
|
/** Every config `servers` connects with, a multi-account server's accounts
|
|
@@ -73,13 +73,13 @@ export function createMcpServerSecrets({
|
|
|
73
73
|
await forgetUnusedGmailAppPassword(gmailAppPasswordAccount(cfg));
|
|
74
74
|
if (!cfg?.url || !cfg.oauthClientId) return;
|
|
75
75
|
const servers = expandedConfigs(resolveConfiguredMcpCatalog().servers);
|
|
76
|
-
if (!servers.some((other) => other.url === cfg.url && other.oauthClientId))
|
|
76
|
+
if (!servers.some((other) => other.url === cfg.url && other.oauthClientId))
|
|
77
|
+
await saveOAuthClientSecret(cfg.url, '');
|
|
77
78
|
};
|
|
78
79
|
// A removed account keeps no sign-in another configured server or account
|
|
79
80
|
// does not share: `{ signIn, revoked }` as removeMcpServer reports it.
|
|
80
81
|
const releaseAccount = async (accountCfg) => {
|
|
81
82
|
forgetConnectorAccountHealth(accountCfg.name);
|
|
82
|
-
retireConnectorAccount(accountCfg.connector, accountCfg.name);
|
|
83
83
|
const address = gmailAppPasswordAccount(accountCfg);
|
|
84
84
|
if (address) {
|
|
85
85
|
const forgotten = await forgetUnusedGmailAppPassword(address);
|
|
@@ -29,6 +29,7 @@ export function createPluginsResourceApi({ deps, sync, decorate }) {
|
|
|
29
29
|
pluginsStatus,
|
|
30
30
|
resolveMcpCatalog = () => ({ adoption: null }),
|
|
31
31
|
flushSkillsSave,
|
|
32
|
+
invalidateSkills,
|
|
32
33
|
} = deps;
|
|
33
34
|
const pluginData = () => cfgMod.getPluginData?.();
|
|
34
35
|
|
|
@@ -59,6 +60,9 @@ export function createPluginsResourceApi({ deps, sync, decorate }) {
|
|
|
59
60
|
return { plugin, status: pluginsStatus() };
|
|
60
61
|
},
|
|
61
62
|
async updatePlugin(plugin = {}) {
|
|
63
|
+
// Windows refuses to rename a directory holding an open recursive
|
|
64
|
+
// skill watch, so drop the watchers before the root is swapped.
|
|
65
|
+
invalidateSkills?.();
|
|
62
66
|
const updated = registryUpdatePlugin(pluginKey(plugin), { dataDir: pluginData() });
|
|
63
67
|
await adoptPluginServerCopies();
|
|
64
68
|
await sync.reconcilePluginsAndAnnounce();
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A routine (schedule or webhook) may name an executor: a workflow sub-agent
|
|
3
|
+
* (Worker, …) on its own configured route. Each fire is then carried out by
|
|
4
|
+
* that sub-agent first, headless and to its end, and only its final report
|
|
5
|
+
* goes to the owner bot's home thread, which relays it (routine-home-turn.mjs).
|
|
6
|
+
* No executor = the bot does the work itself, as before.
|
|
7
|
+
*
|
|
8
|
+
* The executor is a delegatable workflow agent: never a bot (contact agent) or
|
|
9
|
+
* Mixy, never one that is unknown or turned off — refused when the routine is
|
|
10
|
+
* saved (assertRoutineExecutor) and again when it fires (a sub-agent that
|
|
11
|
+
* disappeared or was turned off since fails the fire; nothing falls back).
|
|
12
|
+
*
|
|
13
|
+
* The run is unattended like the bot's own routine turn: it is created under a
|
|
14
|
+
* session id marked as that routine's run (held-requests.mjs markUnattendedRun)
|
|
15
|
+
* so the sub-agent's record carries the run stamp (human-gate/delegation.mjs):
|
|
16
|
+
* it never asks, payments and permanent deletes are refused
|
|
17
|
+
* (human-gate/run-policy.mjs). A sub-agent session has no `agent`, `session`
|
|
18
|
+
* or `ask_user` tool (AGENT_WORKER_DENIED_TOOLS), so it can start no task
|
|
19
|
+
* session and ask nobody.
|
|
20
|
+
*/
|
|
21
|
+
import { randomUUID } from 'node:crypto';
|
|
22
|
+
import { MIXY_AGENT_ID } from '../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
23
|
+
import {
|
|
24
|
+
BUILTIN_SLOT_AGENT_IDS,
|
|
25
|
+
normalizeWorkflowId,
|
|
26
|
+
} from '../runtime/agent/orchestrator/runtime-core/workflow-ids.mjs';
|
|
27
|
+
import { storeInlineDocumentPart, storeInlineImagePart } from '../runtime/attachments/store.mjs';
|
|
28
|
+
import { MIXY_BOT_ID } from '../runtime/shared/agent-store.mjs';
|
|
29
|
+
import { automationPromptContent } from '../runtime/shared/automation-attachments.mjs';
|
|
30
|
+
import { routineExecutorHeader } from '../runtime/shared/routine-trigger.mjs';
|
|
31
|
+
import { scheduleOwnerAgentId } from './agent-home-delivery.mjs';
|
|
32
|
+
import { markUnattendedRun } from './held-requests.mjs';
|
|
33
|
+
|
|
34
|
+
/** `routineExecutorProblem` codes and the error each one raises. */
|
|
35
|
+
export const ROUTINE_EXECUTOR_PROBLEMS = Object.freeze({
|
|
36
|
+
unknown: (id) => `executor agent "${id}" is not an available sub-agent: pick one from the workflow agents`,
|
|
37
|
+
'not-agent': (id) =>
|
|
38
|
+
`executor agent "${id}" is a bot, not a workflow sub-agent: pick a sub-agent such as Worker, or leave it unset`,
|
|
39
|
+
disabled: (id) => `executor agent "${id}" is turned off: turn it on in the workflow agents or pick another`,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
/** The stored form of an executor id: lower-cased with dashes; null for none. */
|
|
43
|
+
export function normalizeExecutorAgentId(value) {
|
|
44
|
+
const text = typeof value === 'string' ? value.trim() : '';
|
|
45
|
+
return text ? normalizeWorkflowId(text, text.toLowerCase()) : null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function defaultProbe(id) {
|
|
49
|
+
const [{ workflowHelpers }, { getPluginData, loadConfig }, { isAgentDisabled, isContactAgentId }] = await Promise.all(
|
|
50
|
+
[
|
|
51
|
+
import('./boot/shared.mjs'),
|
|
52
|
+
import('../runtime/agent/orchestrator/config.mjs'),
|
|
53
|
+
import('../runtime/shared/agent-route-config.mjs'),
|
|
54
|
+
]
|
|
55
|
+
);
|
|
56
|
+
const dataDir = getPluginData();
|
|
57
|
+
// The fresh scan: an agent made a moment ago counts.
|
|
58
|
+
const listed = workflowHelpers.listCustomAgentIds(dataDir).includes(id) && !BUILTIN_SLOT_AGENT_IDS.has(id);
|
|
59
|
+
const definition = listed ? workflowHelpers.loadAgentDefinition(dataDir, id) : null;
|
|
60
|
+
return {
|
|
61
|
+
listed: Boolean(definition),
|
|
62
|
+
contact: Boolean(definition) && isContactAgentId(id, definition.kind),
|
|
63
|
+
disabled: isAgentDisabled(loadConfig({ secrets: false }), id),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Why `id` (normalized) cannot execute a routine: a ROUTINE_EXECUTOR_PROBLEMS
|
|
68
|
+
* code, '' when it can. `probe(id)` → `{ listed, contact, disabled }`. */
|
|
69
|
+
export async function routineExecutorProblem(id, probe = defaultProbe) {
|
|
70
|
+
if (id === MIXY_AGENT_ID || id === MIXY_BOT_ID) return 'not-agent';
|
|
71
|
+
const facts = await probe(id);
|
|
72
|
+
if (!facts.listed) return 'unknown';
|
|
73
|
+
if (facts.contact) return 'not-agent';
|
|
74
|
+
return facts.disabled ? 'disabled' : '';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** The executor id to store for a save's `executorAgentId` (null/empty = none),
|
|
78
|
+
* or the error naming why it cannot be one. */
|
|
79
|
+
export async function assertRoutineExecutor(value, probe = defaultProbe) {
|
|
80
|
+
if (value == null) return null;
|
|
81
|
+
if (typeof value !== 'string') throw new Error('executorAgentId must be a sub-agent id (a string) or null');
|
|
82
|
+
const id = normalizeExecutorAgentId(value);
|
|
83
|
+
if (!id) return null;
|
|
84
|
+
const problem = await routineExecutorProblem(id, probe);
|
|
85
|
+
if (problem) throw new Error(ROUTINE_EXECUTOR_PROBLEMS[problem](id));
|
|
86
|
+
return id;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** An inline image/PDF/Office part as the stored reference part a sub-agent's
|
|
90
|
+
* prompt may carry (handoff-attachments.mjs admits references only). */
|
|
91
|
+
const referencePart = (part) => (part.type === 'image' ? storeInlineImagePart(part) : storeInlineDocumentPart(part));
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Carry out one fire of routine `name` with sub-agent `agentId` and resolve its
|
|
95
|
+
* final report (trimmed text). `prompt` is the routine's instructions (plus a
|
|
96
|
+
* webhook's fenced payload); `ownerAgentId` the bot whose run it is. Rejects
|
|
97
|
+
* when the executor is no longer valid, fails, is cancelled, or `signal` aborts.
|
|
98
|
+
*/
|
|
99
|
+
export async function runRoutineExecutor(
|
|
100
|
+
{
|
|
101
|
+
agentId,
|
|
102
|
+
kind,
|
|
103
|
+
name,
|
|
104
|
+
ownerAgentId = null,
|
|
105
|
+
prompt,
|
|
106
|
+
// The trusted part of `prompt` (the routine's instructions): the only text
|
|
107
|
+
// the executor's skills are selected from, never a webhook payload.
|
|
108
|
+
skillSelection = '',
|
|
109
|
+
attachments = null,
|
|
110
|
+
cwd = null,
|
|
111
|
+
signal = null,
|
|
112
|
+
},
|
|
113
|
+
{ surface, probe = defaultProbe } = {}
|
|
114
|
+
) {
|
|
115
|
+
const problem = await routineExecutorProblem(agentId, probe);
|
|
116
|
+
if (problem) throw new Error(`${kind} "${name}" cannot run: ${ROUTINE_EXECUTOR_PROBLEMS[problem](agentId)}`);
|
|
117
|
+
if (typeof surface?.runAgent !== 'function') throw new Error('routine run: the agent service is not running');
|
|
118
|
+
const header = routineExecutorHeader({ kind, name, project: cwd ? String(cwd) : '' });
|
|
119
|
+
const content = automationPromptContent(`${header}\n\n${prompt}`, attachments);
|
|
120
|
+
const parts = Array.isArray(content) ? content : [{ type: 'text', text: content }];
|
|
121
|
+
const attachmentParts = parts.slice(1).map(referencePart).filter(Boolean);
|
|
122
|
+
// The id the executor is created under: marked as this routine's unattended
|
|
123
|
+
// run for as long as it works (its record keeps the run stamp afterwards).
|
|
124
|
+
const parentSessionId = `routine_exec_${randomUUID()}`;
|
|
125
|
+
const unmark = markUnattendedRun(parentSessionId, {
|
|
126
|
+
kind,
|
|
127
|
+
agentId: scheduleOwnerAgentId({ ownerAgentId }),
|
|
128
|
+
name,
|
|
129
|
+
});
|
|
130
|
+
try {
|
|
131
|
+
const result = await surface.runAgent(
|
|
132
|
+
{
|
|
133
|
+
agent: agentId,
|
|
134
|
+
prompt: parts[0].text,
|
|
135
|
+
skillSelection: String(skillSelection ?? ''),
|
|
136
|
+
...(cwd ? { cwd: String(cwd) } : {}),
|
|
137
|
+
...(attachmentParts.length ? { attachmentParts } : {}),
|
|
138
|
+
},
|
|
139
|
+
{ callerSessionId: parentSessionId },
|
|
140
|
+
{ signal }
|
|
141
|
+
);
|
|
142
|
+
return String(result?.content ?? '').trim();
|
|
143
|
+
} catch (error) {
|
|
144
|
+
// The caller's own cancellation stays as it is.
|
|
145
|
+
if (signal?.aborted) throw error;
|
|
146
|
+
throw new Error(`${kind} "${name}": executor agent "${agentId}" failed: ${error?.message || error}`, {
|
|
147
|
+
cause: error,
|
|
148
|
+
});
|
|
149
|
+
} finally {
|
|
150
|
+
unmark();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
* (outbound actions are allowed within the bot's permissions; payments and
|
|
15
15
|
* permanent deletes are refused, human-gate/run-policy.mjs). Resolves with the
|
|
16
16
|
* reply once the turn ends; rejects when the turn fails, is cancelled, or the
|
|
17
|
-
* caller's `signal` aborts (which also aborts the turn once it runs).
|
|
17
|
+
* caller's `signal` aborts (which also aborts the turn once it runs). With an
|
|
18
|
+
* `executorAgentId` the fire is first carried out by that sub-agent
|
|
19
|
+
* (routine-executor.mjs) and the turn holds only its final report, which the
|
|
20
|
+
* bot relays; the quiet marker as the report wakes nobody and resolves it. A
|
|
18
21
|
* heartbeat turn past its wall-clock cap is aborted and resolves with no reply
|
|
19
22
|
* (`timedOut`).
|
|
20
23
|
*/
|
|
@@ -25,12 +28,16 @@ import { automationPromptContent } from '../runtime/shared/automation-attachment
|
|
|
25
28
|
import { ROUTINE_LIMITS } from '../runtime/shared/routine-limits.mjs';
|
|
26
29
|
import {
|
|
27
30
|
HEARTBEAT_TURN_LIMITS,
|
|
31
|
+
ROUTINE_QUIET,
|
|
28
32
|
isHeartbeatSession,
|
|
33
|
+
isRoutineQuietReply,
|
|
29
34
|
normalizeRoutineTrigger,
|
|
35
|
+
routineRelayHeader,
|
|
30
36
|
routineTriggerHeader,
|
|
31
37
|
} from '../runtime/shared/routine-trigger.mjs';
|
|
32
38
|
import { agentHomeLiveSurface, scheduleOwnerAgentId } from './agent-home-delivery.mjs';
|
|
33
39
|
import { markUnattendedRun, unattendedRunOf } from './held-requests.mjs';
|
|
40
|
+
import { runRoutineExecutor } from './routine-executor.mjs';
|
|
34
41
|
|
|
35
42
|
// Routine turns waiting or running per home thread.
|
|
36
43
|
const waiting = new Map();
|
|
@@ -72,6 +79,9 @@ export async function runRoutineTurn(
|
|
|
72
79
|
// thread and the routine trigger header.
|
|
73
80
|
sessionId = null,
|
|
74
81
|
header = null,
|
|
82
|
+
// A workflow sub-agent that carries the fire out first (routine-executor.mjs):
|
|
83
|
+
// the bot's turn then holds only its final report, for the bot to relay.
|
|
84
|
+
executorAgentId = null,
|
|
75
85
|
},
|
|
76
86
|
{
|
|
77
87
|
surface = agentHomeLiveSurface(),
|
|
@@ -79,9 +89,10 @@ export async function runRoutineTurn(
|
|
|
79
89
|
limit = ROUTINE_LIMITS.homeQueueLimit,
|
|
80
90
|
log = (line) => process.stderr.write(`mixdog routines: ${line}\n`),
|
|
81
91
|
timers = globalThis,
|
|
92
|
+
executor = runRoutineExecutor,
|
|
82
93
|
} = {}
|
|
83
94
|
) {
|
|
84
|
-
|
|
95
|
+
let body = String(prompt || '').trim();
|
|
85
96
|
if (!body) throw new Error(`${kind} "${name}" has no instructions`);
|
|
86
97
|
if (signal?.aborted) throw abortError(signal);
|
|
87
98
|
if (typeof surface?.submit !== 'function') throw new Error('routine run: the session service is not running');
|
|
@@ -91,12 +102,42 @@ export async function runRoutineTurn(
|
|
|
91
102
|
if (!home || home.closed === true) {
|
|
92
103
|
throw new Error(`the bot "${agentId}" has no chat yet: open it once in the app`);
|
|
93
104
|
}
|
|
105
|
+
let opening = header || routineTriggerHeader({ kind, name, project: cwd ? String(cwd) : '' });
|
|
106
|
+
let selection = String(skillSelection ?? body);
|
|
107
|
+
let turnAttachments = attachments;
|
|
108
|
+
if (executorAgentId) {
|
|
109
|
+
const report = String(
|
|
110
|
+
(await executor(
|
|
111
|
+
{
|
|
112
|
+
agentId: executorAgentId,
|
|
113
|
+
kind,
|
|
114
|
+
name,
|
|
115
|
+
ownerAgentId: agentId,
|
|
116
|
+
prompt: body,
|
|
117
|
+
skillSelection: selection,
|
|
118
|
+
attachments,
|
|
119
|
+
cwd,
|
|
120
|
+
signal,
|
|
121
|
+
},
|
|
122
|
+
{ surface }
|
|
123
|
+
)) ?? ''
|
|
124
|
+
).trim();
|
|
125
|
+
if (signal?.aborted) throw abortError(signal);
|
|
126
|
+
if (!report) throw new Error(`${kind} "${name}": executor agent "${executorAgentId}" returned no report`);
|
|
127
|
+
// Nothing to tell: the bot is not woken.
|
|
128
|
+
if (isRoutineQuietReply(report)) return { sessionId: homeId, result: ROUTINE_QUIET };
|
|
129
|
+
// The bot only relays the report: it is derived from whatever the executor
|
|
130
|
+
// read (a webhook's payload included), so it selects no skill.
|
|
131
|
+
body = report;
|
|
132
|
+
opening = routineRelayHeader({ kind, name, executor: executorAgentId, project: cwd ? String(cwd) : '' });
|
|
133
|
+
selection = '';
|
|
134
|
+
turnAttachments = null;
|
|
135
|
+
}
|
|
94
136
|
const queued = waiting.get(homeId) || 0;
|
|
95
137
|
if (queued >= limit) throw new Error(`${limit} routine runs already wait in this bot's chat`);
|
|
96
138
|
waiting.set(homeId, queued + 1);
|
|
97
139
|
const trigger = normalizeRoutineTrigger({ kind, name, event });
|
|
98
|
-
const
|
|
99
|
-
const content = automationPromptContent(`${opening}\n\n${body}`, attachments);
|
|
140
|
+
const content = automationPromptContent(`${opening}\n\n${body}`, turnAttachments);
|
|
100
141
|
return new Promise((resolve, reject) => {
|
|
101
142
|
let started = false;
|
|
102
143
|
let aborted = false;
|
|
@@ -150,7 +191,7 @@ export async function runRoutineTurn(
|
|
|
150
191
|
restorable: false,
|
|
151
192
|
// Esc ends this fire; it is never put back in the queue.
|
|
152
193
|
abortDiscardOnAbort: true,
|
|
153
|
-
skillSelection:
|
|
194
|
+
skillSelection: selection,
|
|
154
195
|
transcriptMeta: { routineTrigger: trigger },
|
|
155
196
|
onCommitted: () => {
|
|
156
197
|
if (started) return;
|
|
@@ -24,6 +24,7 @@ export function createRuntimeFacade({
|
|
|
24
24
|
getOrchestrationMode,
|
|
25
25
|
getOutputStyle,
|
|
26
26
|
getContextStatus,
|
|
27
|
+
getContextStatusSettled = async (options) => getContextStatus(options),
|
|
27
28
|
getContextStatusForSession,
|
|
28
29
|
renameSessionTitle,
|
|
29
30
|
}) {
|
|
@@ -144,6 +145,10 @@ export function createRuntimeFacade({
|
|
|
144
145
|
contextStatus(options) {
|
|
145
146
|
return getContextStatus(options);
|
|
146
147
|
},
|
|
148
|
+
/** The context status once an empty session took moved settings (async callers). */
|
|
149
|
+
contextStatusSettled(options) {
|
|
150
|
+
return getContextStatusSettled(options);
|
|
151
|
+
},
|
|
147
152
|
contextStatusForSession(session) {
|
|
148
153
|
return getContextStatusForSession(session);
|
|
149
154
|
},
|
|
@@ -6,13 +6,10 @@
|
|
|
6
6
|
// deps, so the runtime can hand them straight through.
|
|
7
7
|
import {
|
|
8
8
|
builtinFeatureActive,
|
|
9
|
-
featureDisallowedToolsFor,
|
|
10
9
|
localGitToolsActive,
|
|
11
10
|
} from '../runtime/agent/orchestrator/runtime-core/builtin-features.mjs';
|
|
12
11
|
import { recapEnabled } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
13
|
-
import {
|
|
14
|
-
import { computerBridgeAvailableSync } from '../runtime/computer-bridge/client.mjs';
|
|
15
|
-
import { terminalBridgeAvailableSync } from '../runtime/terminal-bridge/client.mjs';
|
|
12
|
+
import { liveFeatureDisallowedTools } from '../runtime/agent/orchestrator/runtime-core/tool-availability.mjs';
|
|
16
13
|
|
|
17
14
|
export function createRuntimeFeatureGates({ getConfig, getToolProfile }) {
|
|
18
15
|
return {
|
|
@@ -29,12 +26,6 @@ export function createRuntimeFeatureGates({ getConfig, getToolProfile }) {
|
|
|
29
26
|
tidyToolEnabledFn: () => builtinFeatureActive(getConfig(), 'tidy'),
|
|
30
27
|
// Browser/Computer activate on live desktop-bridge presence, so the probe
|
|
31
28
|
// runs per call instead of being captured at boot.
|
|
32
|
-
featureDisallowedTools: () =>
|
|
33
|
-
featureDisallowedToolsFor(getConfig(), {
|
|
34
|
-
browserAvailable: browserBridgeAvailableSync(),
|
|
35
|
-
computerAvailable: computerBridgeAvailableSync(),
|
|
36
|
-
terminalAvailable: terminalBridgeAvailableSync(),
|
|
37
|
-
toolProfile: getToolProfile(),
|
|
38
|
-
}),
|
|
29
|
+
featureDisallowedTools: () => liveFeatureDisallowedTools(getConfig(), { toolProfile: getToolProfile() }),
|
|
39
30
|
};
|
|
40
31
|
}
|
|
@@ -26,6 +26,7 @@ export async function runScheduleSession(
|
|
|
26
26
|
kind: 'schedule',
|
|
27
27
|
name: schedule.name,
|
|
28
28
|
ownerAgentId: schedule.ownerAgentId,
|
|
29
|
+
executorAgentId: schedule.executorAgentId || null,
|
|
29
30
|
prompt: body,
|
|
30
31
|
attachments: schedule.attachments,
|
|
31
32
|
cwd: schedule.cwd || null,
|
|
@@ -84,11 +84,16 @@ export function reconcileJobCancelled(job, value) {
|
|
|
84
84
|
} catch {}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
/** A turn that threw. `identity` is the owner-facing result shape: a failure
|
|
88
|
+
* after answers the turn went on past (error.carriedReport, turn-report.mjs)
|
|
89
|
+
* reports them with the failure. */
|
|
90
|
+
export function reconcileJobStreamStalled(job, error, identity = {}) {
|
|
88
91
|
if (!job?.taskId || job._terminalResultValue !== undefined) return;
|
|
92
|
+
const report = typeof error?.carriedReport === 'string' ? error.carriedReport : '';
|
|
89
93
|
try {
|
|
90
94
|
reconcileBackgroundTask(job.taskId, {
|
|
91
95
|
status: 'failed',
|
|
96
|
+
...(report ? { result: { ...identity, content: report } } : {}),
|
|
92
97
|
error,
|
|
93
98
|
terminalReason: 'agent-stream-stalled',
|
|
94
99
|
});
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import { resolveAgentWatchdogPolicy } from '../../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
|
|
5
5
|
import { buildAgentTaskProgressFields } from '../../agent-task-status.mjs';
|
|
6
6
|
import { getProgressWatchdogState } from '../../agent-watchdog-registry.mjs';
|
|
7
|
+
import { _liveSessions } from '../../../../runtime/agent/orchestrator/session/store/live-state.mjs';
|
|
8
|
+
import { todoProgress } from '../../../../runtime/agent/orchestrator/runtime-core/todo-list.mjs';
|
|
7
9
|
|
|
8
10
|
// Job statuses that can never progress again (mirrors TERMINAL_STATUSES in
|
|
9
11
|
// runtime/shared/background-tasks.mjs; 'canceled' accepted defensively).
|
|
@@ -46,6 +48,11 @@ export function terminalJobFrozenFields(status, now = Date.now()) {
|
|
|
46
48
|
* the diagnostics through renderJob/list directly. */
|
|
47
49
|
export function liveAgentStatusRow(row) {
|
|
48
50
|
if (!row || typeof row !== 'object') return row;
|
|
51
|
+
// The agent's own todo progress, from its live session only (an evicted
|
|
52
|
+
// idle worker is not re-read on every pulse).
|
|
53
|
+
const live = row.sessionId ? _liveSessions.get(row.sessionId) : null;
|
|
54
|
+
const todo = live ? todoProgress(live) : null;
|
|
55
|
+
if (todo) row = { ...row, todo };
|
|
49
56
|
const {
|
|
50
57
|
silent_for: _silentFor,
|
|
51
58
|
staleSeconds: _staleSeconds,
|
|
@@ -7,7 +7,20 @@ import {
|
|
|
7
7
|
watchdogPartialHandoffFromError,
|
|
8
8
|
watchdogStoppedHandoff,
|
|
9
9
|
} from '../../../runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs';
|
|
10
|
-
import {
|
|
10
|
+
import { reconcileAgentSession } from '../../../runtime/agent/orchestrator/agent-runtime/session-builder.mjs';
|
|
11
|
+
import {
|
|
12
|
+
agentPresetName,
|
|
13
|
+
clean,
|
|
14
|
+
normalizeAgentName,
|
|
15
|
+
presetKey,
|
|
16
|
+
readAgentFrontmatterPermission,
|
|
17
|
+
resolvePrompt,
|
|
18
|
+
} from './helpers.mjs';
|
|
19
|
+
import { normalizeAgentPermission } from '../../../runtime/shared/markdown-frontmatter.mjs';
|
|
20
|
+
import { resolveAgentSessionPermission } from '../../../runtime/agent/orchestrator/internal-agents.mjs';
|
|
21
|
+
import { resolveAgentSpawnPreset } from './spawn-preset.mjs';
|
|
22
|
+
import { flushPendingSessionConfigWrites } from '../../config-lifecycle/config-writers.mjs';
|
|
23
|
+
import { AGENT_ROUTE_KEYS } from '../../agent-profile-changes.mjs';
|
|
11
24
|
import { abnormalEmptyFinishError, renderResult } from './render.mjs';
|
|
12
25
|
import {
|
|
13
26
|
reconcileJobCancelled,
|
|
@@ -22,15 +35,38 @@ import { rebindDelegation } from '../../../runtime/agent/orchestrator/session/hu
|
|
|
22
35
|
import { settledWorkerStatus } from './worker-index/row-liveness.mjs';
|
|
23
36
|
import { whileTurnDispatched } from '../../../runtime/agent/orchestrator/session/manager/runtime-state.mjs';
|
|
24
37
|
import { takeStoppedShellJobs } from '../../../runtime/agent/orchestrator/session/manager/turn-reap.mjs';
|
|
38
|
+
import { turnReportText } from '../../../runtime/agent/orchestrator/session/loop/turn-report.mjs';
|
|
25
39
|
|
|
26
40
|
function workerResultIdentity({ session, tag, sessionId }) {
|
|
27
41
|
return { tag, sessionId, agent: session.agent || null, provider: session.provider, model: session.model };
|
|
28
42
|
}
|
|
29
43
|
|
|
44
|
+
/** A reused worker runs with the permission its agent's definition grants
|
|
45
|
+
* now, resolved as a spawn resolves it (spawn-plan.mjs). */
|
|
46
|
+
export function followAgentPermission(session, { dataDir, sourceRoot }) {
|
|
47
|
+
const agent = normalizeAgentName(session?.agent);
|
|
48
|
+
if (!agent || !dataDir) return;
|
|
49
|
+
const defined = normalizeAgentPermission(readAgentFrontmatterPermission(agent, dataDir, sourceRoot));
|
|
50
|
+
const permission = resolveAgentSessionPermission(agent, defined || null);
|
|
51
|
+
if (permission) session.permission = permission;
|
|
52
|
+
else delete session.permission;
|
|
53
|
+
}
|
|
54
|
+
|
|
30
55
|
// `send` to an existing worker: resolve the live session, run one follow-up
|
|
31
56
|
// turn under the progress watchdog, and reconcile the job/worker row. Busy
|
|
32
57
|
// sessions queue the prompt instead.
|
|
33
|
-
export function createSendFlow({
|
|
58
|
+
export function createSendFlow({
|
|
59
|
+
mgr,
|
|
60
|
+
cfgMod = null,
|
|
61
|
+
dataDir = null,
|
|
62
|
+
STANDALONE_SOURCE_ROOT = null,
|
|
63
|
+
defaultCwd,
|
|
64
|
+
sessionSurface,
|
|
65
|
+
canUseSessionSurface,
|
|
66
|
+
registry,
|
|
67
|
+
views,
|
|
68
|
+
spawnFlow,
|
|
69
|
+
}) {
|
|
34
70
|
async function prepareSend(args, context = {}) {
|
|
35
71
|
registry.refreshTagsFromSessions({ scanSessions: registry.wantsSessionScan(args), context });
|
|
36
72
|
const target = clean(args.tag || args.sessionId);
|
|
@@ -51,7 +87,7 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
51
87
|
const abnormalError = abnormalEmptyFinishError(result, session.agent || sendAgent);
|
|
52
88
|
return {
|
|
53
89
|
...workerResultIdentity({ session, tag, sessionId }),
|
|
54
|
-
content: result
|
|
90
|
+
content: turnReportText(result),
|
|
55
91
|
...(sessionSurface?.canonical === true ? { handoffOnly: true } : {}),
|
|
56
92
|
...(abnormalError ? { error: abnormalError } : {}),
|
|
57
93
|
};
|
|
@@ -82,6 +118,13 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
82
118
|
if (canUseSessionSurface(session)) {
|
|
83
119
|
return sessionSurface.runTurn({ session, prompt, context: args.context || null, cwd, ...turnHooks });
|
|
84
120
|
}
|
|
121
|
+
// An in-process session has no turn start of its own to reconcile it
|
|
122
|
+
// (a canonical child's runtime does, reconcileTurnSettings): bring its
|
|
123
|
+
// settings-gated tools, connectors, compaction, prompt settings and its
|
|
124
|
+
// agent's permission (as its definition stands: a narrowed one applies)
|
|
125
|
+
// to the settings now.
|
|
126
|
+
reconcileAgentSession(session);
|
|
127
|
+
followAgentPermission(session, { dataDir, sourceRoot: STANDALONE_SOURCE_ROOT });
|
|
85
128
|
return mgr.askSession(sessionId, prompt, args.context || null, null, cwd, null, turnHooks);
|
|
86
129
|
});
|
|
87
130
|
}
|
|
@@ -129,7 +172,7 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
129
172
|
handoffMsgStart = resolveHandoffMessageStartIndex(mgr.getSession(sessionId));
|
|
130
173
|
const turnHooks = buildTurnHooks({ sessionId, notifyContext, job, turnReview, completionValue });
|
|
131
174
|
const result = await runTurn(prepared, turnHooks);
|
|
132
|
-
//
|
|
175
|
+
// The early preview does not suppress the canonical body notification;
|
|
133
176
|
// notifyTaskCompletion fires once with output via resolve/reconcile.
|
|
134
177
|
const finalValue = completionValue(result);
|
|
135
178
|
if (job?.status === 'cancelled') {
|
|
@@ -162,7 +205,7 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
162
205
|
}
|
|
163
206
|
finalStatus = 'error';
|
|
164
207
|
noteStoppedShellJobsOnError(error, await takeStoppedShellJobs(sessionId));
|
|
165
|
-
reconcileJobStreamStalled(job, error);
|
|
208
|
+
reconcileJobStreamStalled(job, error, workerResultIdentity({ session, tag, sessionId }));
|
|
166
209
|
throw error;
|
|
167
210
|
} finally {
|
|
168
211
|
turnReview.complete();
|
|
@@ -204,8 +247,69 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
204
247
|
// `send` branch AND by the `spawn` branch when an explicit tag maps to a
|
|
205
248
|
// live session (reuse path). Busy sessions queue the prompt; idle ones run a
|
|
206
249
|
// background send job that continues the existing session (context kept).
|
|
250
|
+
// A worker that runs on its agent's configured route follows that route, as
|
|
251
|
+
// a bot's home chat does (agent-route-follow.mjs): a model picked for the
|
|
252
|
+
// agent since the spawn applies from this send. A worker started on an
|
|
253
|
+
// explicit model or preset keeps it.
|
|
254
|
+
async function agentRouteToFollow({ session }) {
|
|
255
|
+
const agent = normalizeAgentName(session?.agent);
|
|
256
|
+
if (!agent || !cfgMod?.loadConfig) return null;
|
|
257
|
+
await flushPendingSessionConfigWrites();
|
|
258
|
+
let current;
|
|
259
|
+
try {
|
|
260
|
+
current = resolveAgentSpawnPreset(cfgMod.loadConfig(), { agent });
|
|
261
|
+
} catch {
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
const spawnedOn = clean(session.presetName || session.preset);
|
|
265
|
+
const own = new Set([`agent-${agent}`, agentPresetName(agent), presetKey(current.preset), current.presetName]);
|
|
266
|
+
if (!spawnedOn || !own.has(spawnedOn)) return null;
|
|
267
|
+
const preset = current.preset;
|
|
268
|
+
if (!preset.provider || !preset.model) return null;
|
|
269
|
+
// Every route key the agent's route sets (an effort or Fast change alone
|
|
270
|
+
// included); a key it leaves unset is the route default either way.
|
|
271
|
+
const value = (key, source) => {
|
|
272
|
+
if (key === 'fast') return source?.fast === true;
|
|
273
|
+
if (key === 'autoEffort') return source?.autoEffort !== false;
|
|
274
|
+
return source?.[key] == null ? null : JSON.stringify(source[key]);
|
|
275
|
+
};
|
|
276
|
+
const set = AGENT_ROUTE_KEYS.filter(
|
|
277
|
+
(key) => key === 'fast' || key === 'autoEffort' || (preset[key] !== undefined && preset[key] !== null)
|
|
278
|
+
);
|
|
279
|
+
const matches = (target) => set.every((key) => value(key, preset) === value(key, target));
|
|
280
|
+
// Against the route the session's next turn runs on: one held for it
|
|
281
|
+
// (heldRoute, an in-process worker that was busy), else its own.
|
|
282
|
+
if (matches(session)) {
|
|
283
|
+
// Saved back to the running route: an earlier hold is obsolete.
|
|
284
|
+
if (session.heldRoute) mgr.holdSessionRoute?.(session.id, null);
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
if (session.heldRoute && matches({ ...session, ...session.heldRoute })) return null;
|
|
288
|
+
const route = {};
|
|
289
|
+
for (const key of set) {
|
|
290
|
+
if (key === 'fast') route.fast = preset.fast === true;
|
|
291
|
+
else if (key === 'autoEffort') {
|
|
292
|
+
if (preset.autoEffort === false) route.autoEffort = false;
|
|
293
|
+
} else route[key] = preset[key];
|
|
294
|
+
}
|
|
295
|
+
return route;
|
|
296
|
+
}
|
|
297
|
+
|
|
207
298
|
async function dispatchToExistingSession(requested, notifyContext, extras = {}) {
|
|
208
|
-
|
|
299
|
+
let followed = requested.route ? null : await agentRouteToFollow(requested);
|
|
300
|
+
if (followed && !canUseSessionSurface(requested.session)) {
|
|
301
|
+
// An in-process session takes the followed route in place, between
|
|
302
|
+
// turns; a running one finishes on the route it started on and holds
|
|
303
|
+
// the new one for its next turn, which runs the queued work.
|
|
304
|
+
if (!views.isSessionBusy(requested.sessionId)) {
|
|
305
|
+
const { session } = requested;
|
|
306
|
+
const crossProvider = followed.provider !== session.provider || followed.model !== session.model;
|
|
307
|
+
mgr.updateSessionRoute?.(requested.sessionId, followed, { session, crossProvider });
|
|
308
|
+
} else mgr.holdSessionRoute?.(requested.sessionId, followed);
|
|
309
|
+
followed = null;
|
|
310
|
+
}
|
|
311
|
+
const routed = followed ? { ...requested, route: followed } : requested;
|
|
312
|
+
const prepared = routed.route ? await applyRequestedRoute(routed) : routed;
|
|
209
313
|
const { session, sessionId, prompt } = prepared;
|
|
210
314
|
const tag = registry.tagForSession(sessionId);
|
|
211
315
|
if (canUseSessionSurface(session) && views.isSessionBusy(sessionId)) {
|
|
@@ -10,6 +10,7 @@ import { clean, terminalPidForContext } from '../helpers.mjs';
|
|
|
10
10
|
import { renderResult } from '../render.mjs';
|
|
11
11
|
import { closeManagedSession } from '../../../lifecycle/shared.mjs';
|
|
12
12
|
import { hopOf } from '../../../../runtime/shared/bot-hops.mjs';
|
|
13
|
+
import { notDoneReport } from '../../../../runtime/agent/orchestrator/runtime-core/todo-list.mjs';
|
|
13
14
|
|
|
14
15
|
/** The completion callback that hands a worker's result back to its caller session; null without a handoff. */
|
|
15
16
|
function handoffNotifier(handoffSessionId, notifySessionCompletion) {
|
|
@@ -86,6 +87,17 @@ export function createJobStarter({ mgr, notifyStatusChange, notifySessionComplet
|
|
|
86
87
|
}
|
|
87
88
|
},
|
|
88
89
|
});
|
|
90
|
+
// Success, failure or cancellation: the report names what the agent's own
|
|
91
|
+
// todo list leaves undone. The Lead never receives the list otherwise.
|
|
92
|
+
task.reportAppendix = () => {
|
|
93
|
+
const sessionId = task.meta?.sessionId || jobMeta?.sessionId;
|
|
94
|
+
if (!sessionId) return '';
|
|
95
|
+
try {
|
|
96
|
+
return notDoneReport(mgr.getSession(sessionId));
|
|
97
|
+
} catch {
|
|
98
|
+
return '';
|
|
99
|
+
}
|
|
100
|
+
};
|
|
89
101
|
// The model's tool call that started this job owns it (its result message
|
|
90
102
|
// carries the id: agent-task-starts.mjs).
|
|
91
103
|
recordAgentTaskStart(notifyContext?.toolCallId, task.taskId);
|
|
@@ -22,6 +22,7 @@ import { workspaceCwdLock } from '../../../workspace/admission-gate.mjs';
|
|
|
22
22
|
import { isContactAgentId } from '../../../../runtime/agent/orchestrator/runtime-core/workflow-ids.mjs';
|
|
23
23
|
import { assertBotChainTarget } from '../../../../runtime/shared/bot-hops.mjs';
|
|
24
24
|
import { actingAgentOf, delegationChainOf } from '../../../bot-chain.mjs';
|
|
25
|
+
import { flushPendingSessionConfigWrites } from '../../../config-lifecycle/config-writers.mjs';
|
|
25
26
|
|
|
26
27
|
export function createSpawnPlanner({
|
|
27
28
|
mgr = null,
|
|
@@ -36,6 +37,10 @@ export function createSpawnPlanner({
|
|
|
36
37
|
}) {
|
|
37
38
|
/** Shared spawn-prep validations (agent/preset/tag/cwd/prompt). */
|
|
38
39
|
async function resolveSpawnPlan(args, callerCwd, context, prepState) {
|
|
40
|
+
// A setting a runtime of this process adopted (an agent's model picked a
|
|
41
|
+
// moment ago) is written behind a debounce: drain it so the read below
|
|
42
|
+
// sees what the runtimes hold in memory.
|
|
43
|
+
await flushPendingSessionConfigWrites();
|
|
39
44
|
const config = cfgMod.loadConfig();
|
|
40
45
|
const agent = normalizeAgentName(args.agent);
|
|
41
46
|
if (!agent) throw new Error('agent spawn: agent is required');
|