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
|
@@ -33,7 +33,7 @@ function quotedName(name, fallback) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
/** How much of a PDF reads as text, in words the model can act on. */
|
|
36
|
-
|
|
36
|
+
function textLayerLabel(pageCount, textPages) {
|
|
37
37
|
const pages = Number(pageCount);
|
|
38
38
|
const withText = Number(textPages);
|
|
39
39
|
if (!(pages > 0) || !Number.isFinite(withText) || withText < 0) return 'text layer not checked';
|
|
@@ -81,7 +81,7 @@ export const PDF_INTAKE_TIMEOUT_MS = 60_000;
|
|
|
81
81
|
// least this many non-whitespace characters. A scan often keeps a stamped page
|
|
82
82
|
// number or a few stray glyphs; those alone do not make its content readable
|
|
83
83
|
// as text, so such a page still needs its image (or OCR).
|
|
84
|
-
|
|
84
|
+
const PDF_TEXT_LAYER_MIN_CHARS = 16;
|
|
85
85
|
|
|
86
86
|
/** Whether one page's extracted text is a real text layer (see above). */
|
|
87
87
|
export function pageHasTextLayer(text) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export function readAttachmentBuffer(value: string | { attachmentRef?: string }): Buffer;
|
|
2
|
+
export function attachmentBlobSize(value: string | { attachmentRef?: string }, claimed?: number): number;
|
|
2
3
|
export function isPermanentAttachmentError(error: unknown): boolean;
|
|
3
4
|
export function isAttachmentReference(value: unknown): boolean;
|
|
4
5
|
export interface MessageAttachment {
|
|
@@ -298,7 +298,7 @@ const ATTACHMENT_INTEGRITY = 'ATTACHMENT_INTEGRITY';
|
|
|
298
298
|
|
|
299
299
|
// A referenced blob that is gone from disk (retention, manual cleanup, a
|
|
300
300
|
// copied session) surfaces from readAttachmentBuffer as the stat ENOENT.
|
|
301
|
-
|
|
301
|
+
function isMissingAttachmentError(error) {
|
|
302
302
|
return error?.code === 'ENOENT';
|
|
303
303
|
}
|
|
304
304
|
|
|
@@ -316,7 +316,7 @@ export function readAttachmentBase64(value) {
|
|
|
316
316
|
// Real on-disk size of a referenced blob. Caps must never trust the client's
|
|
317
317
|
// claimed sizeBytes; a blob that is not on disk cannot be read later either, so
|
|
318
318
|
// only then does the claimed size stand.
|
|
319
|
-
function attachmentBlobSize(value, claimed = 0) {
|
|
319
|
+
export function attachmentBlobSize(value, claimed = 0) {
|
|
320
320
|
try {
|
|
321
321
|
return statSync(attachmentPath(typeof value === 'string' ? value : value?.attachmentRef)).size;
|
|
322
322
|
} catch (error) {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// The channels worker's config hot reload (schedules, webhooks, events, voice).
|
|
2
|
+
// It rides the shared config-change subscription: that watches the data
|
|
3
|
+
// directory, so the atomic rename of every write never orphans it, it recovers
|
|
4
|
+
// from watcher errors, and it carries in-process writes and keychain changes.
|
|
5
|
+
// A reload restarts the webhook server and hook tunnel, so only a change of
|
|
6
|
+
// the sections the worker reads (channels: webhook, events, …; voice) reloads;
|
|
7
|
+
// schedules arrive through the reload_config IPC, never through this watch.
|
|
8
|
+
import { readSection, subscribeConfigChange } from '../../shared/config.mjs';
|
|
9
|
+
|
|
10
|
+
function channelsConfigSnapshot() {
|
|
11
|
+
return JSON.stringify([readSection('channels') ?? null, readSection('voice') ?? null]);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function createConfigReloadWatch(reload, { snapshot = channelsConfigSnapshot } = {}) {
|
|
15
|
+
let unsubscribe = null;
|
|
16
|
+
let applied = null;
|
|
17
|
+
const read = () => {
|
|
18
|
+
try {
|
|
19
|
+
return snapshot();
|
|
20
|
+
} catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
start() {
|
|
26
|
+
if (unsubscribe) return;
|
|
27
|
+
applied = read();
|
|
28
|
+
unsubscribe = subscribeConfigChange(() => {
|
|
29
|
+
const next = read();
|
|
30
|
+
if (next !== null && next === applied) return;
|
|
31
|
+
applied = next;
|
|
32
|
+
Promise.resolve()
|
|
33
|
+
.then(reload)
|
|
34
|
+
.catch(() => {});
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
stop() {
|
|
38
|
+
unsubscribe?.();
|
|
39
|
+
unsubscribe = null;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { loadConfig } from '../config.mjs';
|
|
2
2
|
|
|
3
|
-
export function createConfigReloader({
|
|
3
|
+
export function createConfigReloader({
|
|
4
|
+
state,
|
|
5
|
+
getConfig,
|
|
6
|
+
setConfig,
|
|
7
|
+
getBridgeRuntimeConnected,
|
|
8
|
+
scheduler,
|
|
9
|
+
services,
|
|
10
|
+
load = loadConfig,
|
|
11
|
+
}) {
|
|
12
|
+
// Reloads overlap (no debounce), so a slower load of an older config must not
|
|
13
|
+
// be applied over a newer one: only the newest started reload applies, and an
|
|
14
|
+
// older caller waits for it instead.
|
|
15
|
+
let latestStarted = 0;
|
|
16
|
+
let latestReload = null;
|
|
4
17
|
function reloadScheduler() {
|
|
5
18
|
// The scheduler must be RE-ARMED by the reload whenever it is supposed to
|
|
6
19
|
// be running: `restart: false` only destroys the cron/one-shot bindings and
|
|
@@ -12,13 +25,20 @@ export function createConfigReloader({ state, getConfig, setConfig, getBridgeRun
|
|
|
12
25
|
restart: state.automationRunning || getBridgeRuntimeConnected(),
|
|
13
26
|
});
|
|
14
27
|
}
|
|
15
|
-
return
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
return function reloadRuntimeConfig() {
|
|
29
|
+
const ticket = ++latestStarted;
|
|
30
|
+
const run = (async () => {
|
|
31
|
+
const loaded = await load();
|
|
32
|
+
if (ticket !== latestStarted) return latestReload;
|
|
33
|
+
setConfig(loaded);
|
|
34
|
+
reloadScheduler();
|
|
35
|
+
if (getBridgeRuntimeConnected() || state.automationRunning) {
|
|
36
|
+
services.syncWebhookAndEventRuntime({ reload: true });
|
|
37
|
+
} else {
|
|
38
|
+
await services.stopWebhookAndEventRuntime();
|
|
39
|
+
}
|
|
40
|
+
})();
|
|
41
|
+
latestReload = run;
|
|
42
|
+
return run;
|
|
23
43
|
};
|
|
24
44
|
}
|
|
@@ -9,6 +9,7 @@ import { isPidAlive } from '../../shared/pid-liveness.mjs';
|
|
|
9
9
|
import {
|
|
10
10
|
advanceScheduleCursor,
|
|
11
11
|
claimScheduleRun,
|
|
12
|
+
getSchedule,
|
|
12
13
|
markFired,
|
|
13
14
|
markDone,
|
|
14
15
|
markScheduleFailure,
|
|
@@ -76,6 +77,14 @@ function isCronExpression(time) {
|
|
|
76
77
|
return false;
|
|
77
78
|
}
|
|
78
79
|
}
|
|
80
|
+
// Two one-shot times name the same instant. The database hands back a new
|
|
81
|
+
// Date on every read, so identity would call an unchanged schedule changed.
|
|
82
|
+
function sameInstant(left, right) {
|
|
83
|
+
if (left == null || right == null) return (left ?? null) === (right ?? null);
|
|
84
|
+
const at = (value) => (value instanceof Date ? value.getTime() : Date.parse(value));
|
|
85
|
+
const [a, b] = [at(left), at(right)];
|
|
86
|
+
return Number.isNaN(a) || Number.isNaN(b) ? String(left) === String(right) : a === b;
|
|
87
|
+
}
|
|
79
88
|
// True when this fire (started at `since`) ended in an overlap skip.
|
|
80
89
|
function skippedSince(schedule, since) {
|
|
81
90
|
const at = schedule.lastSkippedAt ? new Date(schedule.lastSkippedAt).getTime() : 0;
|
|
@@ -616,6 +625,30 @@ class Scheduler {
|
|
|
616
625
|
}
|
|
617
626
|
// ── Fire timed schedule ─────────────────────────────────────────────
|
|
618
627
|
async fireTimed(schedule, opts = {}) {
|
|
628
|
+
// The armed copy may be stale (a reload that failed or has not arrived):
|
|
629
|
+
// the stored row decides whether, and with what prompt, it still fires.
|
|
630
|
+
let row;
|
|
631
|
+
try {
|
|
632
|
+
row = await getSchedule(schedule.name);
|
|
633
|
+
} catch (err) {
|
|
634
|
+
logSchedule(`${schedule.name}: not fired — schedule unreadable: ${err?.message || err}\n`);
|
|
635
|
+
this.notifyFailure(schedule, 'schedule unreadable — fire skipped');
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
const sameCron = (row?.whenCron ?? null) === (schedule.whenCron ?? null);
|
|
639
|
+
if (
|
|
640
|
+
!row ||
|
|
641
|
+
row.enabled === false ||
|
|
642
|
+
row.status === 'done' ||
|
|
643
|
+
!sameInstant(row.whenAt, schedule.whenAt) ||
|
|
644
|
+
!sameCron
|
|
645
|
+
) {
|
|
646
|
+
logSchedule(`${schedule.name}: not fired — deleted or changed since it was armed\n`);
|
|
647
|
+
// A skip, not a failed run: the callers record no failure on its row.
|
|
648
|
+
schedule.lastSkippedAt = new Date().toISOString();
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
651
|
+
schedule.prompt = row.prompt;
|
|
619
652
|
const prompt = this.resolvePrompt(schedule);
|
|
620
653
|
if (!prompt) {
|
|
621
654
|
process.stderr.write(`mixdog scheduler: prompt not found for "${schedule.name}"
|
|
@@ -60,6 +60,9 @@ ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS last_skipped_at timesta
|
|
|
60
60
|
ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS owner_agent_id text NOT NULL DEFAULT 'lead';
|
|
61
61
|
-- Legacy columns model, workflow and run_as_agent are no longer read or written (kept, not dropped, to avoid a risky migration).
|
|
62
62
|
ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS run_as_agent boolean NOT NULL DEFAULT false;
|
|
63
|
+
-- The workflow sub-agent that carries out each fire first (its final report is
|
|
64
|
+
-- what the owner bot relays); NULL = the owner bot does the work itself.
|
|
65
|
+
ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS executor_agent_id text;
|
|
63
66
|
-- Failed runs in a row: a success or switching it back on resets it; at
|
|
64
67
|
-- ROUTINE_LIMITS.pauseAfterFailures the schedule switches itself off.
|
|
65
68
|
ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS consecutive_failures integer NOT NULL DEFAULT 0;
|
|
@@ -101,6 +104,7 @@ function rowToDef(row) {
|
|
|
101
104
|
lastFailedAt: row.last_failed_at,
|
|
102
105
|
lastSkippedAt: row.last_skipped_at,
|
|
103
106
|
ownerAgentId: row.owner_agent_id || 'lead',
|
|
107
|
+
executorAgentId: row.executor_agent_id || null,
|
|
104
108
|
consecutiveFailures: Number(row.consecutive_failures) || 0,
|
|
105
109
|
resultDelivery: row.result_delivery || null,
|
|
106
110
|
nextFireAt: row.next_fire_at,
|
|
@@ -136,7 +140,7 @@ function hasRequiredTargetColumn(db) {
|
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
const COLS =
|
|
139
|
-
'name, description, when_at, when_cron, timezone, cwd, attachments, delivery, prompt, enabled, status, last_fired_at, last_scheduled_at, last_started_at, last_success_at, last_failed_at, last_skipped_at, owner_agent_id, consecutive_failures, result_delivery, next_fire_at, deferred_until, skipped_until, created_at, updated_at';
|
|
143
|
+
'name, description, when_at, when_cron, timezone, cwd, attachments, delivery, prompt, enabled, status, last_fired_at, last_scheduled_at, last_started_at, last_success_at, last_failed_at, last_skipped_at, owner_agent_id, executor_agent_id, consecutive_failures, result_delivery, next_fire_at, deferred_until, skipped_until, created_at, updated_at';
|
|
140
144
|
|
|
141
145
|
// ---------------------------------------------------------------------------
|
|
142
146
|
// Public API
|
|
@@ -176,6 +180,7 @@ export async function upsertSchedule(def, { dataDir } = {}) {
|
|
|
176
180
|
def.status ?? 'active',
|
|
177
181
|
def.nextFireAt ?? null,
|
|
178
182
|
def.ownerAgentId || 'lead',
|
|
183
|
+
def.executorAgentId || null,
|
|
179
184
|
];
|
|
180
185
|
let legacyTarget = '';
|
|
181
186
|
let legacyTargetValue = '';
|
|
@@ -186,10 +191,11 @@ export async function upsertSchedule(def, { dataDir } = {}) {
|
|
|
186
191
|
}
|
|
187
192
|
const { rows } = await db.query(
|
|
188
193
|
`INSERT INTO scheduler.schedules
|
|
189
|
-
(name, description, when_at, when_cron, timezone, cwd, attachments, delivery, prompt, enabled, status, next_fire_at, owner_agent_id${legacyTarget})
|
|
190
|
-
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13${legacyTargetValue})
|
|
194
|
+
(name, description, when_at, when_cron, timezone, cwd, attachments, delivery, prompt, enabled, status, next_fire_at, owner_agent_id, executor_agent_id${legacyTarget})
|
|
195
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14${legacyTargetValue})
|
|
191
196
|
ON CONFLICT (name) DO UPDATE SET
|
|
192
197
|
owner_agent_id = EXCLUDED.owner_agent_id,
|
|
198
|
+
executor_agent_id = EXCLUDED.executor_agent_id,
|
|
193
199
|
description = EXCLUDED.description,
|
|
194
200
|
when_at = EXCLUDED.when_at,
|
|
195
201
|
when_cron = EXCLUDED.when_cron,
|
|
@@ -235,7 +241,7 @@ export async function renameSchedule(oldName, def, { timingChanged = false, data
|
|
|
235
241
|
const { rows } = await db.query(
|
|
236
242
|
`UPDATE scheduler.schedules SET
|
|
237
243
|
name = $2, description = $3, when_at = $4, when_cron = $5, timezone = $6, cwd = $7,
|
|
238
|
-
attachments = $8, prompt = $9, enabled = $10, owner_agent_id = $11,
|
|
244
|
+
attachments = $8, prompt = $9, enabled = $10, owner_agent_id = $11, executor_agent_id = $13,
|
|
239
245
|
next_fire_at = CASE WHEN $12::boolean THEN $4::timestamptz ELSE next_fire_at END,
|
|
240
246
|
status = CASE WHEN $12::boolean THEN 'active' ELSE status END,
|
|
241
247
|
deferred_until = CASE WHEN $12::boolean THEN NULL ELSE deferred_until END,
|
|
@@ -258,6 +264,7 @@ export async function renameSchedule(oldName, def, { timingChanged = false, data
|
|
|
258
264
|
def.enabled ?? true,
|
|
259
265
|
def.ownerAgentId || 'lead',
|
|
260
266
|
timingChanged === true,
|
|
267
|
+
def.executorAgentId || null,
|
|
261
268
|
]
|
|
262
269
|
);
|
|
263
270
|
return rowToDef(rows[0]);
|
|
@@ -96,6 +96,8 @@ function createWebhookSessionDispatcher({ getBridgeDispatch, store = { recordEnd
|
|
|
96
96
|
endpoint: name,
|
|
97
97
|
// The bot whose chat the run is a turn in.
|
|
98
98
|
owner: extra.owner || null,
|
|
99
|
+
// The sub-agent that carries the run out first, if the endpoint names one.
|
|
100
|
+
executor: extra.executor || null,
|
|
99
101
|
deliveryId,
|
|
100
102
|
event: extra.event || null,
|
|
101
103
|
},
|
|
@@ -108,7 +110,7 @@ function createWebhookSessionDispatcher({ getBridgeDispatch, store = { recordEnd
|
|
|
108
110
|
|
|
109
111
|
async function dispatchEndpoint({ name, body, headers, res, deliveryId, endpoint }) {
|
|
110
112
|
try {
|
|
111
|
-
const { instructions, cwd, attachments, delivery, ownerAgentId } = endpoint;
|
|
113
|
+
const { instructions, cwd, attachments, delivery, ownerAgentId, executorAgentId } = endpoint;
|
|
112
114
|
const run = webhookRunPrompt(instructions, body, headers);
|
|
113
115
|
if (!getBridgeDispatch()) throw new Error(`[webhook] session dispatch requires bridgeDispatch`);
|
|
114
116
|
// Kept for the app's "Run now", which re-runs the latest event. Losing
|
|
@@ -118,6 +120,7 @@ function createWebhookSessionDispatcher({ getBridgeDispatch, store = { recordEnd
|
|
|
118
120
|
);
|
|
119
121
|
await dispatchSessionRun(name, run.prompt, deliveryId, res, {
|
|
120
122
|
owner: ownerAgentId || null,
|
|
123
|
+
executor: executorAgentId || null,
|
|
121
124
|
cwd: cwd || null,
|
|
122
125
|
event: webhookEventSummary(headers, body),
|
|
123
126
|
attachments: attachments || null,
|
|
@@ -45,6 +45,9 @@ ALTER TABLE webhooks.endpoints ALTER COLUMN role SET DEFAULT '';
|
|
|
45
45
|
ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS owner_agent_id text NOT NULL DEFAULT 'lead';
|
|
46
46
|
-- Legacy columns model, workflow and run_as_agent are no longer read or written (kept, not dropped, to avoid a risky migration).
|
|
47
47
|
ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS run_as_agent boolean NOT NULL DEFAULT false;
|
|
48
|
+
-- The workflow sub-agent that carries out each run first (its final report is
|
|
49
|
+
-- what the owner bot relays); NULL = the owner bot does the work itself.
|
|
50
|
+
ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS executor_agent_id text;
|
|
48
51
|
-- The latest received event (its payload kept for a manual re-run) and the
|
|
49
52
|
-- outcome stamps of the runs it started.
|
|
50
53
|
ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS last_event_at timestamptz;
|
|
@@ -86,7 +89,7 @@ const getDb = createPgSchemaDb({
|
|
|
86
89
|
// The stored payload itself is never projected here (readEndpointLastPayload
|
|
87
90
|
// is its only read path); rows carry a presence flag.
|
|
88
91
|
const ENDPOINT_COLS =
|
|
89
|
-
'name, description, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, last_event_at, last_success_at, last_failed_at, last_skipped_at, consecutive_failures, result_delivery, (last_payload IS NOT NULL) AS has_last_payload, created_at, updated_at';
|
|
92
|
+
'name, description, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, executor_agent_id, last_event_at, last_success_at, last_failed_at, last_skipped_at, consecutive_failures, result_delivery, (last_payload IS NOT NULL) AS has_last_payload, created_at, updated_at';
|
|
90
93
|
|
|
91
94
|
function rowToEndpoint(row) {
|
|
92
95
|
if (!row) return null;
|
|
@@ -104,6 +107,7 @@ function rowToEndpoint(row) {
|
|
|
104
107
|
instructions: row.instructions,
|
|
105
108
|
enabled: row.enabled,
|
|
106
109
|
ownerAgentId: row.owner_agent_id || 'lead',
|
|
110
|
+
executorAgentId: row.executor_agent_id || null,
|
|
107
111
|
lastEventAt: row.last_event_at || null,
|
|
108
112
|
lastSuccessAt: row.last_success_at || null,
|
|
109
113
|
lastFailedAt: row.last_failed_at || null,
|
|
@@ -187,15 +191,17 @@ export async function upsertEndpoint(def, { dataDir } = {}) {
|
|
|
187
191
|
def.instructions ?? '',
|
|
188
192
|
def.enabled ?? true,
|
|
189
193
|
def.ownerAgentId || 'lead',
|
|
194
|
+
def.executorAgentId || null,
|
|
190
195
|
];
|
|
191
196
|
// The last event and run stamps survive an edit: they describe deliveries,
|
|
192
197
|
// not the definition.
|
|
193
198
|
const { rows } = await db.query(
|
|
194
199
|
`INSERT INTO webhooks.endpoints
|
|
195
|
-
(name, description, role, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id)
|
|
196
|
-
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)
|
|
200
|
+
(name, description, role, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, executor_agent_id)
|
|
201
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)
|
|
197
202
|
ON CONFLICT (name) DO UPDATE SET
|
|
198
203
|
owner_agent_id = EXCLUDED.owner_agent_id,
|
|
204
|
+
executor_agent_id = EXCLUDED.executor_agent_id,
|
|
199
205
|
description = EXCLUDED.description,
|
|
200
206
|
role = EXCLUDED.role,
|
|
201
207
|
parser = EXCLUDED.parser,
|
|
@@ -40,6 +40,7 @@ import fs from 'node:fs';
|
|
|
40
40
|
import { spawn, spawnSync } from 'node:child_process';
|
|
41
41
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
42
42
|
import { windowsSystemRoot } from '../../agent/orchestrator/tools/builtin/windows-roots.mjs';
|
|
43
|
+
import { killProcessTrees } from '../../agent/orchestrator/mcp/child-tree.mjs';
|
|
43
44
|
import { selectWhisperPort, whisperListenerOwned } from './whisper-port.mjs';
|
|
44
45
|
|
|
45
46
|
// ── Tunables (deterministic; no ranges) ──────────────────────────────────────
|
|
@@ -217,16 +218,13 @@ function isOwnedWhisperServer(pid, { modelPath, port } = {}) {
|
|
|
217
218
|
return modelMatch || portMatch;
|
|
218
219
|
}
|
|
219
220
|
|
|
220
|
-
|
|
221
|
+
// `aliveAt`: when `pid` was last known to be the process meant (a live child
|
|
222
|
+
// handle: now; a proven stale child: before its proof). Windows has no graceful
|
|
223
|
+
// stop for a console server, so both steps run the shared tree kill.
|
|
224
|
+
async function killPid(pid, force, aliveAt = Date.now()) {
|
|
221
225
|
if (!pid) return;
|
|
222
226
|
if (IS_WIN) {
|
|
223
|
-
|
|
224
|
-
if (force) args.push('/F');
|
|
225
|
-
try {
|
|
226
|
-
spawnSync('taskkill', args, { windowsHide: true });
|
|
227
|
-
} catch {
|
|
228
|
-
/* best-effort */
|
|
229
|
-
}
|
|
227
|
+
await killProcessTrees([pid], { aliveAt });
|
|
230
228
|
return;
|
|
231
229
|
}
|
|
232
230
|
try {
|
|
@@ -325,10 +323,10 @@ async function teardown(reason) {
|
|
|
325
323
|
resolve();
|
|
326
324
|
}
|
|
327
325
|
});
|
|
328
|
-
killPid(pid, false);
|
|
326
|
+
void killPid(pid, false);
|
|
329
327
|
const raced = await Promise.race([exited, delay(STOP_GRACE_MS, 'timeout')]);
|
|
330
328
|
if (raced === 'timeout') {
|
|
331
|
-
killPid(pid, true); // escalate
|
|
329
|
+
void killPid(pid, true); // escalate
|
|
332
330
|
await Promise.race([exited, delay(STOP_GRACE_MS, 'timeout')]);
|
|
333
331
|
}
|
|
334
332
|
}
|
|
@@ -384,11 +382,13 @@ async function startServer(contract) {
|
|
|
384
382
|
// Prefer the recorded meta's own contract fields; fall back to the contract we
|
|
385
383
|
// are about to start. A non-positive match → never kill (fail closed).
|
|
386
384
|
const ownArgs = { modelPath: meta?.modelPath ?? modelPath, port: meta?.port ?? FIXED_PORT };
|
|
385
|
+
const provenAt = Date.now();
|
|
387
386
|
if (meta && isOwnedWhisperServer(meta.pid, ownArgs)) {
|
|
388
|
-
killPid(meta.pid, false);
|
|
387
|
+
await killPid(meta.pid, false, provenAt);
|
|
389
388
|
await delay(500);
|
|
389
|
+
const reprovenAt = Date.now();
|
|
390
390
|
if (isOwnedWhisperServer(meta.pid, ownArgs)) {
|
|
391
|
-
killPid(meta.pid, true);
|
|
391
|
+
await killPid(meta.pid, true, reprovenAt);
|
|
392
392
|
await delay(500);
|
|
393
393
|
}
|
|
394
394
|
clearPidMeta();
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
cleanupInstanceRuntimeFiles,
|
|
19
19
|
clearServerPid,
|
|
20
20
|
} from './runtime-paths.mjs';
|
|
21
|
-
import {
|
|
21
|
+
import { createConfigReloadWatch } from './config-reload-watch.mjs';
|
|
22
22
|
import { bootProfile, utcTimestamp } from './boot-profile.mjs';
|
|
23
23
|
import {
|
|
24
24
|
isChannelsDegraded,
|
|
@@ -121,9 +121,6 @@ function writeBridgeState(active) {
|
|
|
121
121
|
function isChannelBridgeActive() {
|
|
122
122
|
return channelBridgeActive;
|
|
123
123
|
}
|
|
124
|
-
// Config hot-reload watcher (installed by start(); torn down by stop()).
|
|
125
|
-
let _configWatcher = null;
|
|
126
|
-
let _reloadDebounce = null;
|
|
127
124
|
const STATUS_FILE = getStatusPath(INSTANCE_ID);
|
|
128
125
|
const statusState = new JsonStateFile(STATUS_FILE, {});
|
|
129
126
|
statusState.ensure();
|
|
@@ -201,6 +198,7 @@ function wireWebhookHandlers() {
|
|
|
201
198
|
const run = await runWebhookSession({
|
|
202
199
|
name: context?.endpoint || 'webhook',
|
|
203
200
|
ownerAgentId: context?.owner || null,
|
|
201
|
+
executorAgentId: context?.executor || null,
|
|
204
202
|
cwd: cwd || null,
|
|
205
203
|
attachments: attachments || null,
|
|
206
204
|
event: context?.event || '',
|
|
@@ -252,24 +250,14 @@ const { handleToolCall } = createToolDispatch({
|
|
|
252
250
|
}),
|
|
253
251
|
},
|
|
254
252
|
});
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
try {
|
|
258
|
-
_configWatcher = fs.watch(path.join(DATA_DIR, 'mixdog-config.json'), () => {
|
|
259
|
-
invalidateConfigReadCache();
|
|
260
|
-
if (_reloadDebounce) clearTimeout(_reloadDebounce);
|
|
261
|
-
_reloadDebounce = setTimeout(() => {
|
|
262
|
-
reloadRuntimeConfig().catch(() => {});
|
|
263
|
-
}, 500);
|
|
264
|
-
});
|
|
265
|
-
} catch {}
|
|
266
|
-
}
|
|
253
|
+
// Config hot reload (started by start(); stopped by stop()).
|
|
254
|
+
const configReloadWatch = createConfigReloadWatch(reloadRuntimeConfig);
|
|
267
255
|
async function start(options = {}) {
|
|
268
256
|
if (options?.bridge === false) {
|
|
269
257
|
channelBridgeActive = false;
|
|
270
258
|
writeBridgeState(false);
|
|
271
259
|
await startAutomationRuntime();
|
|
272
|
-
|
|
260
|
+
configReloadWatch.start();
|
|
273
261
|
return;
|
|
274
262
|
}
|
|
275
263
|
channelBridgeActive = true;
|
|
@@ -283,10 +271,9 @@ async function start(options = {}) {
|
|
|
283
271
|
} catch {
|
|
284
272
|
// Non-fatal: owned-runtime start errors degrade to automation-only mode.
|
|
285
273
|
}
|
|
286
|
-
// Hot-reload config on
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
ensureConfigWatcher();
|
|
274
|
+
// Hot-reload config on change (schedules/webhooks/events), in both bridge
|
|
275
|
+
// and automation-only daemon modes.
|
|
276
|
+
configReloadWatch.start();
|
|
290
277
|
// Pre-warm the whisper-server manager once at owner startup so the first
|
|
291
278
|
// voice transcription does not pay cold-start cost. Non-blocking: failures
|
|
292
279
|
// (e.g. runtime not installed) are swallowed; per-request ensureReady retries.
|
|
@@ -314,16 +301,7 @@ async function stop() {
|
|
|
314
301
|
} catch {}
|
|
315
302
|
await stopOwnedRuntime('unified server stop');
|
|
316
303
|
cleanupInstanceRuntimeFiles(INSTANCE_ID);
|
|
317
|
-
|
|
318
|
-
clearTimeout(_reloadDebounce);
|
|
319
|
-
_reloadDebounce = null;
|
|
320
|
-
}
|
|
321
|
-
if (_configWatcher) {
|
|
322
|
-
try {
|
|
323
|
-
_configWatcher.close();
|
|
324
|
-
} catch {}
|
|
325
|
-
_configWatcher = null;
|
|
326
|
-
}
|
|
304
|
+
configReloadWatch.stop();
|
|
327
305
|
}
|
|
328
306
|
// ── IPC worker mode ──────────────────────────────────────────────
|
|
329
307
|
// Skipped under the machine-global host (MIXDOG_DAEMON_HOST=1): the daemon
|
|
@@ -10,25 +10,25 @@ import fs from 'node:fs';
|
|
|
10
10
|
import path from 'node:path';
|
|
11
11
|
import { isForegroundWindowCapture, requiredCapabilities } from './linux-action-capabilities.mjs';
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
const UINPUT_HINT =
|
|
14
14
|
'input_unavailable: Wayland input needs write access to /dev/uinput; add the udev rule `KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"`, add your user to the input group, then sign in again';
|
|
15
15
|
export const INPUT_GROUP_SECURITY_NOTE =
|
|
16
16
|
'Security note: membership of the input group lets every program you run read and inject keyboard and mouse input system-wide. Grant it only on a machine and account you trust.';
|
|
17
17
|
export const GNOME_EXTENSION_UUID = 'mixdog-windows@mixdog.io';
|
|
18
18
|
/** The oldest helper interface this app can use (2 added Screenshot and StopRequested, 3 the in-shell indicator). */
|
|
19
19
|
export const MIN_WINDOW_HELPER_VERSION = 3;
|
|
20
|
-
|
|
20
|
+
const WINDOW_HELPER_RELOGIN_HINT =
|
|
21
21
|
'wayland_window_control_unavailable: the Mixdog Windows GNOME extension is installed and enabled but GNOME Shell has not loaded it yet; the user must sign out and sign in again once';
|
|
22
|
-
|
|
22
|
+
const WINDOW_HELPER_ENABLE_HINT =
|
|
23
23
|
'wayland_window_control_unavailable: the Mixdog Windows GNOME extension is not enabled; it could not be enabled automatically (run gnome-extensions enable mixdog-windows@mixdog.io)';
|
|
24
|
-
|
|
24
|
+
const WINDOW_CONTROL_UNSUPPORTED_HINT =
|
|
25
25
|
'wayland_window_control_unavailable: this desktop offers no window control to other programs (supported: GNOME with the Mixdog Windows extension, sway, Hyprland, or an X11 session); screen, pointer, keyboard and clipboard still work';
|
|
26
|
-
|
|
26
|
+
const ACCESSIBILITY_HINT = 'accessibility_unavailable: the AT-SPI bus is not running; install at-spi2-core';
|
|
27
27
|
export const TESSERACT_HINT =
|
|
28
28
|
'ocr_unavailable: install Tesseract (for example `sudo apt install tesseract-ocr tesseract-ocr-kor`) to read text from pixels';
|
|
29
29
|
export const CLIPBOARD_HINT =
|
|
30
30
|
'clipboard_unavailable: install wl-clipboard (`wl-copy`/`wl-paste`) for clipboard access on Wayland';
|
|
31
|
-
|
|
31
|
+
const DISPLAY_HINT =
|
|
32
32
|
'display_unavailable: no graphical session to drive; run inside a desktop session with DISPLAY (X11) or WAYLAND_DISPLAY set';
|
|
33
33
|
|
|
34
34
|
/** Stable code of the whole refusal; the per-capability codes are the native ones. */
|
|
@@ -301,14 +301,10 @@ function capabilityIssue(name, readiness) {
|
|
|
301
301
|
return { code: 'display_unavailable', message: DISPLAY_HINT };
|
|
302
302
|
// Semantic actions fail on whichever of their two prerequisites is missing.
|
|
303
303
|
const gnomeWayland = readiness.session === 'wayland' && readiness.desktop === 'gnome';
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
: 'windows'
|
|
309
|
-
: name === 'capture' && gnomeWayland
|
|
310
|
-
? 'windows'
|
|
311
|
-
: name;
|
|
304
|
+
let target = name;
|
|
305
|
+
if (name === 'semanticActions')
|
|
306
|
+
target = readiness.capabilities.windows.state === 'ready' ? 'accessibility' : 'windows';
|
|
307
|
+
else if (name === 'capture' && gnomeWayland) target = 'windows';
|
|
312
308
|
const capability = readiness.capabilities[target];
|
|
313
309
|
switch (target) {
|
|
314
310
|
case 'windows':
|