mixdog 1.2.5 → 1.3.0
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/LICENSES/simple-icons-CC0-1.0.txt +30 -0
- package/NOTICE.md +19 -0
- package/package.json +4 -1
- package/scripts/check-model-recommendations.mjs +89 -0
- package/scripts/gate-local.mjs +7 -0
- package/scripts/lib/gate-scheduler.mjs +2 -2
- package/scripts/lib/isolated-test-env.mjs +16 -0
- package/scripts/lib/run-node-tests.mjs +5 -14
- package/scripts/provider-pingpong-live.mjs +9 -9
- package/src/agents/advisor/AGENT.md +4 -4
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +5 -4
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +17 -0
- package/src/defaults/skills/browser-use/SKILL.md +7 -1
- package/src/defaults/skills/computer-use/SKILL.md +3 -1
- package/src/defaults/skills/memory-management/SKILL.md +4 -1
- package/src/defaults/skills/setup/references/actions.md +11 -4
- package/src/defaults/skills/setup-guide/SKILL.md +175 -0
- package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
- package/src/defaults/skills/visualize/SKILL.md +3 -2
- package/src/lib/rules-builder.cjs +56 -7
- package/src/output-styles/common.md +22 -6
- package/src/output-styles/detailed.md +7 -5
- package/src/output-styles/minimal.md +7 -3
- package/src/output-styles/simple.md +2 -3
- package/src/rules/agent/AGENT.md +7 -1
- package/src/rules/agent-mode/AGENT_MODE.md +24 -0
- package/src/rules/agent-mode/MIXY.md +21 -0
- package/src/rules/agent-mode/ROUTINE.md +6 -0
- package/src/rules/lead/LEAD.md +9 -4
- package/src/rules/shared/10-tool-workflow.md +2 -1
- package/src/rules/shared/60-verification.md +4 -5
- package/src/rules/shared/70-delivery.md +3 -0
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -1
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
- package/src/runtime/agent/orchestrator/config.mjs +6 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +182 -13
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +5 -3
- package/src/runtime/agent/orchestrator/internal-agents.mjs +10 -0
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +215 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +58 -64
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
- package/src/runtime/agent/orchestrator/mcp/client.mjs +122 -15
- package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +2 -3
- package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
- package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +41 -19
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +11 -5
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/catalog-deadline.mjs +163 -0
- package/src/runtime/agent/orchestrator/providers/catalog-failures.mjs +34 -0
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +38 -14
- package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +100 -26
- package/src/runtime/agent/orchestrator/providers/lib/send-callbacks.mjs +24 -0
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +49 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +11 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +45 -16
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-connect.mjs +196 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +74 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-login.mjs +194 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth-tokens.mjs +353 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +293 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +33 -100
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +23 -14
- package/src/runtime/agent/orchestrator/providers/registry.mjs +41 -27
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +98 -4
- package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
- package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +15 -8
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +10 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +4 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +50 -20
- package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
- package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
- package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +15 -3
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +162 -0
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +641 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +74 -13
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +8 -2
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +165 -0
- package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
- package/src/runtime/agent/orchestrator/session/lifecycle-scan.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +39 -2
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +82 -33
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +11 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +7 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +13 -5
- package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +10 -7
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -22
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +23 -1
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +81 -34
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -5
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +55 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +24 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
- package/src/runtime/agent/orchestrator/session/request-fork.mjs +47 -0
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +70 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +277 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/side-question.mjs +5 -43
- package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +73 -6
- package/src/runtime/agent/orchestrator/session/store/load-session.mjs +40 -0
- package/src/runtime/agent/orchestrator/session/store/save-fault.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-header.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +258 -43
- package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +325 -0
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +84 -21
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +46 -30
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
- package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +144 -45
- package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +32 -13
- package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +364 -38
- package/src/runtime/agent/orchestrator/session/store.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/task-wait-control.mjs +43 -12
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +23 -6
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +44 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -6
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +13 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/bashism-rewrite.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/benign-exit.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +40 -7
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +37 -34
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +0 -4
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +6 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +29 -27
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/find-files-tool.mjs +28 -11
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +12 -3
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +203 -101
- package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.mjs +90 -41
- package/src/runtime/agent/orchestrator/tools/builtin/lib/list-helpers.mjs +17 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-delivery.mjs +199 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +165 -39
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +25 -13
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +7 -6
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +19 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-line-collector.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-render.mjs +25 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-render.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +12 -5
- package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +61 -22
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +32 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +193 -19
- package/src/runtime/agent/orchestrator/tools/builtin/shell-direct-exe.mjs +57 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +123 -32
- package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +26 -1
- package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +13 -28
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +90 -11
- package/src/runtime/agent/orchestrator/tools/builtin/wait-budgets.mjs +23 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +54 -10
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +22 -28
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +11 -7
- package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +126 -9
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +15 -6
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +64 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +10 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promotion-results.mjs +13 -3
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +8 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +104 -55
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +7 -2
- package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +39 -23
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
- package/src/runtime/attachments/office-extract.mjs +11 -9
- package/src/runtime/browser-bridge/client.mjs +24 -0
- package/src/runtime/channels/lib/scheduler.mjs +40 -12
- package/src/runtime/channels/lib/schedules-db.mjs +71 -12
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
- package/src/runtime/channels/lib/webhook.mjs +0 -1
- package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
- package/src/runtime/channels/lib/worker-main.mjs +17 -20
- package/src/runtime/computer-bridge/client.mjs +28 -1
- package/src/runtime/connectors/gmail-app-password.mjs +690 -0
- package/src/runtime/connectors/google-mcp.mjs +446 -0
- package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
- package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
- package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
- package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
- package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
- package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
- package/src/runtime/memory/lib/embedding-tokenizer.mjs +32 -18
- package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
- package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
- package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
- package/src/runtime/memory/lib/memory.mjs +7 -1
- package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
- package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -1
- package/src/runtime/memory/lib/tool-call-handler.mjs +9 -5
- package/src/runtime/memory/tool-defs.mjs +5 -0
- package/src/runtime/office/authoring/pptx-script-normalize.mjs +11 -8
- package/src/runtime/office/core/tabular.mjs +1 -1
- package/src/runtime/office/design/library/design-template-inspect.mjs +7 -4
- package/src/runtime/office/portable/docx-formatting.mjs +1 -1
- package/src/runtime/office/portable/docx-runs.mjs +1 -1
- package/src/runtime/office/portable/docx-tracked-edits.mjs +2 -2
- package/src/runtime/office/portable/portable-docx-edits.mjs +11 -10
- package/src/runtime/office/portable/portable-docx-operations.mjs +21 -17
- package/src/runtime/office/portable/portable-docx-parts.mjs +15 -9
- package/src/runtime/office/portable/portable-docx-styles.mjs +4 -1
- package/src/runtime/office/portable/portable-docx-xml.mjs +9 -9
- package/src/runtime/office/portable/portable-opc.mjs +27 -13
- package/src/runtime/office/portable/portable-pivot.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-chart.mjs +3 -3
- package/src/runtime/office/portable/portable-pptx-charts.mjs +24 -18
- package/src/runtime/office/portable/portable-pptx-core.mjs +5 -5
- package/src/runtime/office/portable/portable-pptx-deck.mjs +8 -4
- package/src/runtime/office/portable/portable-pptx-package.mjs +7 -4
- package/src/runtime/office/portable/portable-pptx-shapes.mjs +18 -9
- package/src/runtime/office/portable/portable-sheet-parts.mjs +9 -3
- package/src/runtime/office/portable/portable-sheet-xml.mjs +5 -5
- package/src/runtime/office/portable/portable-xlsx-charts.mjs +4 -1
- package/src/runtime/office/portable/portable-xlsx-drawings.mjs +10 -6
- package/src/runtime/office/portable/portable-xlsx-operations.mjs +8 -5
- package/src/runtime/office/portable/portable-xlsx-pivot-ops.mjs +1 -1
- package/src/runtime/office/portable/portable-xlsx-reference-shift.mjs +11 -7
- package/src/runtime/office/portable/portable-xlsx-sheet-edits.mjs +6 -3
- package/src/runtime/office/portable/portable-xml.mjs +1 -1
- package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
- package/src/runtime/shared/agent-avatar.d.mts +64 -0
- package/src/runtime/shared/agent-avatar.mjs +320 -0
- package/src/runtime/shared/agent-route-config.d.mts +3 -0
- package/src/runtime/shared/agent-route-config.mjs +16 -0
- package/src/runtime/shared/atomic-file.mjs +36 -14
- package/src/runtime/shared/background-tasks.mjs +60 -20
- package/src/runtime/shared/child-spawn-gate.mjs +26 -16
- package/src/runtime/shared/config.mjs +8 -11
- package/src/runtime/shared/connector-accounts.mjs +15 -0
- package/src/runtime/shared/connector-catalog.d.mts +52 -0
- package/src/runtime/shared/connector-catalog.mjs +230 -0
- package/src/runtime/shared/connector-triggers.d.mts +3 -0
- package/src/runtime/shared/connector-triggers.mjs +43 -0
- package/src/runtime/shared/file-lock.mjs +7 -1
- package/src/runtime/shared/file-permissions-worker.mjs +38 -0
- package/src/runtime/shared/file-permissions.d.mts +19 -4
- package/src/runtime/shared/file-permissions.mjs +310 -4
- package/src/runtime/shared/git-runner-worker.mjs +6 -78
- package/src/runtime/shared/google-oauth-client.mjs +24 -0
- package/src/runtime/shared/held-request-host.d.mts +12 -0
- package/src/runtime/shared/held-request-host.mjs +71 -0
- package/src/runtime/shared/llm/http-agent.mjs +7 -3
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +10 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +2 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +32 -3
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +12 -5
- package/src/runtime/shared/llm/usage-ledger-worker.mjs +1 -1
- package/src/runtime/shared/llm/usage-ledger.mjs +20 -5
- package/src/runtime/shared/memory-snapshot.mjs +5 -1
- package/src/runtime/shared/notify-trace.mjs +8 -1
- package/src/runtime/shared/plain-preview.d.mts +1 -0
- package/src/runtime/shared/plain-preview.mjs +28 -0
- package/src/runtime/shared/pristine-execution-contract.json +5 -1
- package/src/runtime/shared/process-runner-worker.mjs +7 -0
- package/src/runtime/shared/process-runner.mjs +38 -0
- package/src/runtime/shared/provider-accounts.mjs +2 -1
- package/src/runtime/shared/provider-api-key.mjs +0 -1
- package/src/runtime/shared/read-row-numbers.mjs +1 -1
- package/src/runtime/shared/resource-admission.mjs +60 -18
- package/src/runtime/shared/routine-limits.d.mts +11 -0
- package/src/runtime/shared/routine-limits.mjs +21 -0
- package/src/runtime/shared/routine-trigger.d.mts +10 -0
- package/src/runtime/shared/routine-trigger.mjs +44 -0
- package/src/runtime/shared/run-child.mjs +84 -0
- package/src/runtime/shared/schedule-model-ref.mjs +9 -10
- package/src/runtime/shared/session-activity-signal.mjs +23 -0
- package/src/runtime/shared/shell-output-summary.mjs +23 -0
- package/src/runtime/shared/singleton-owner.mjs +126 -42
- package/src/runtime/shared/slow-span.mjs +4 -12
- package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
- package/src/runtime/shared/tool-output-limit.mjs +4 -2
- package/src/runtime/shared/tool-output-marker.mjs +58 -0
- package/src/runtime/shared/transcript-metadata.mjs +10 -0
- package/src/runtime/shared/turn-changes.mjs +0 -8
- package/src/runtime/shared/usage-readout-totals.mjs +56 -0
- package/src/runtime/shared/user-data-guard.mjs +131 -34
- package/src/runtime/shared/worktrees/activity-gate.mjs +33 -8
- package/src/runtime/shared/worktrees/git-head.mjs +20 -2
- package/src/runtime/shared/worktrees/lock.mjs +3 -2
- package/src/runtime/terminal-bridge/tool-defs.mjs +1 -1
- package/src/runtime/tidy/runners/biome.mjs +3 -1
- package/src/runtime/tidy/shadow.mjs +2 -1
- package/src/runtime/web-search/index.mjs +5 -7
- package/src/runtime/web-search/lib/formatter.mjs +42 -6
- package/src/runtime/web-search/tool-defs.mjs +6 -1
- package/src/session-runtime/agent-home-delivery.mjs +459 -0
- package/src/session-runtime/agent-profile-changes.mjs +21 -0
- package/src/session-runtime/agent-room-delivery.mjs +92 -0
- package/src/session-runtime/agent-task-sessions.mjs +200 -0
- package/src/session-runtime/boot/apis.mjs +50 -18
- package/src/session-runtime/boot/facade.mjs +5 -8
- package/src/session-runtime/boot/infrastructure.mjs +28 -17
- package/src/session-runtime/boot/tools.mjs +3 -0
- package/src/session-runtime/channel-config-api.mjs +53 -5
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
- package/src/session-runtime/held-requests.mjs +228 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +31 -2
- package/src/session-runtime/internal-tool-executor.mjs +2 -0
- package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
- package/src/session-runtime/lifecycle/session-switch/context-switch.mjs +4 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +11 -4
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +3 -3
- package/src/session-runtime/lifecycle/shared.mjs +25 -2
- package/src/session-runtime/lifecycle/teardown/session-close.mjs +2 -0
- package/src/session-runtime/lifecycle/teardown.mjs +5 -2
- package/src/session-runtime/lifecycle-api.mjs +3 -1
- package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
- package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +112 -15
- package/src/session-runtime/model-route/set-route.mjs +14 -3
- package/src/session-runtime/owned-automation-run.mjs +229 -0
- package/src/session-runtime/provider-auth/login.mjs +10 -6
- package/src/session-runtime/provider-auth/setup.mjs +19 -2
- package/src/session-runtime/provider-catalog-cache.mjs +101 -25
- package/src/session-runtime/provider-models/catalog-load.mjs +14 -3
- package/src/session-runtime/provider-models/row-hydration.mjs +4 -0
- package/src/session-runtime/provider-models.mjs +76 -10
- package/src/session-runtime/provider-readiness.mjs +4 -0
- package/src/session-runtime/resource-api.mjs +5 -0
- package/src/session-runtime/resource-mcp-api.mjs +107 -13
- package/src/session-runtime/resource-skills-api.mjs +12 -0
- package/src/session-runtime/room-member-gate.mjs +48 -0
- package/src/session-runtime/routine-home-turn.mjs +156 -0
- package/src/session-runtime/routine-owner.mjs +48 -0
- package/src/session-runtime/schedule-session-run.mjs +30 -64
- package/src/session-runtime/services/agent-tool/close-flow.mjs +2 -1
- package/src/session-runtime/services/agent-tool/helpers.mjs +10 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +10 -2
- package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +13 -4
- package/src/session-runtime/services/agent-tool/notify.mjs +15 -4
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +134 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/deferred-spawn.mjs +2 -1
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -1
- package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +8 -3
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +4 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +44 -10
- package/src/session-runtime/services/agent-tool.mjs +20 -0
- package/src/session-runtime/services/channel-admin.mjs +93 -24
- package/src/session-runtime/services/memory-access.mjs +37 -0
- package/src/session-runtime/services/provider-admin.mjs +166 -59
- package/src/session-runtime/services/schedule-access.mjs +91 -0
- package/src/session-runtime/services/usage-dashboard-model.mjs +2 -2
- package/src/session-runtime/services/usage-dashboard.mjs +27 -69
- package/src/session-runtime/session-create/session-options.mjs +34 -7
- package/src/session-runtime/session-hooks.mjs +16 -8
- package/src/session-runtime/setup-tool/executor.mjs +68 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +72 -14
- package/src/session-runtime/setup-tool/settings-contract.mjs +8 -6
- package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
- package/src/session-runtime/skills-api.mjs +16 -1
- package/src/session-runtime/tool-policy-refresh.mjs +238 -29
- package/src/session-runtime/turn/session-ops.mjs +10 -3
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +11 -2
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +3 -0
- package/src/session-runtime/usage-stats-api.mjs +6 -1
- package/src/session-runtime/webhook-session-run.mjs +49 -67
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +556 -22
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
- package/src/session-runtime/workflow-agents-api.mjs +4 -1
- package/src/standalone/channel-transport/http-routes.mjs +10 -9
- package/src/standalone/daemon-agent-control.mjs +1 -8
- package/src/standalone/daemon-desktop-runtime.mjs +20 -7
- package/src/standalone/daemon-owner.mjs +117 -25
- package/src/standalone/daemon-session-control.mjs +11 -2
- package/src/standalone/daemon.mjs +61 -17
- package/src/standalone/session-call-cache.mjs +6 -0
- package/src/standalone/session-protocol.mjs +28 -1
- package/src/standalone/session-service/retention/busy.mjs +7 -2
- package/src/standalone/session-service/session-calls/session-turns.mjs +9 -0
- package/src/standalone/session-service.mjs +19 -0
- package/src/standalone/session-transport/routes.mjs +7 -6
- package/src/tui/app/model-options.mjs +39 -2
- package/src/tui/app/model-picker.mjs +16 -2
- package/src/tui/app/provider-setup-picker.mjs +1 -2
- package/src/tui/app/slash-commands.mjs +20 -0
- package/src/tui/dist/index.mjs +487 -128
- package/src/tui/session/context-state.mjs +6 -1
- package/src/tui/session/notice-surface.mjs +35 -4
- package/src/tui/session/notice-text.mjs +0 -1
- package/src/tui/session/queue-helpers.mjs +2 -1
- package/src/tui/session/session-api/extensions.mjs +4 -0
- package/src/tui/session/session-api/intake/submission.mjs +12 -13
- package/src/tui/session/session-api/integrations.mjs +9 -5
- package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
- package/src/tui/session/session-api/lifecycle.mjs +17 -1
- package/src/tui/session/session-api/routes.mjs +48 -3
- package/src/tui/session/session-flow/drain.mjs +20 -3
- package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
- package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
- package/src/tui/session/session-flow/steering.mjs +104 -24
- package/src/tui/session/session-flow.mjs +2 -0
- package/src/tui/session/tool-approval.mjs +26 -5
- package/src/tui/session/transcript-intake.mjs +6 -2
- package/src/tui/session/transcript-spill.mjs +5 -1
- package/src/tui/session/tui-steering-persist.mjs +65 -42
- package/src/tui/session/turn-live-call.mjs +56 -0
- package/src/tui/session/turn-stream.mjs +33 -0
- package/src/tui/session/turn.mjs +50 -7
- package/src/ui/statusline.mjs +1 -6
- package/src/ui/streaming-markdown-heal.mjs +24 -7
- package/src/vendor/statusline/bin/statusline-route.mjs +0 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +0 -1
- package/src/workflows/default/WORKFLOW.md +9 -13
- package/src/session-runtime/automation-agents.mjs +0 -94
- package/src/session-runtime/automation-workflow.mjs +0 -59
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// A group-room member's tool calls (session/agent-room.mjs). Reads run freely;
|
|
2
|
+
// anything that can change files or state asks the user through the ordinary
|
|
3
|
+
// approval flow, whatever the agent's own permission or hook rules say — even
|
|
4
|
+
// an agent that normally runs auto-approved. A hook's deny still wins.
|
|
5
|
+
import { analyzeShellCommandEffects } from '../runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs';
|
|
6
|
+
|
|
7
|
+
const READ_ONLY_TOOLS = new Set([
|
|
8
|
+
'read',
|
|
9
|
+
'grep',
|
|
10
|
+
'glob',
|
|
11
|
+
'find',
|
|
12
|
+
'list',
|
|
13
|
+
'code_graph',
|
|
14
|
+
'load_tool',
|
|
15
|
+
'skill',
|
|
16
|
+
'Skill',
|
|
17
|
+
'recall',
|
|
18
|
+
'search_memories',
|
|
19
|
+
'web_search',
|
|
20
|
+
'web_fetch',
|
|
21
|
+
'local_fetch',
|
|
22
|
+
'image_fetch',
|
|
23
|
+
'ask_user',
|
|
24
|
+
]);
|
|
25
|
+
|
|
26
|
+
export const ROOM_APPROVAL_REASON = 'Group-room members need your approval before changing anything.';
|
|
27
|
+
|
|
28
|
+
/** Whether `name(args)` only reads: a read-only tool, or a shell command whose
|
|
29
|
+
* every stage the shell analysis classifies as non-mutating. */
|
|
30
|
+
export async function isReadOnlyRoomCall({ name, args, cwd }, analyze = analyzeShellCommandEffects) {
|
|
31
|
+
if (READ_ONLY_TOOLS.has(name)) return true;
|
|
32
|
+
if (name !== 'shell' || typeof args?.command !== 'string') return false;
|
|
33
|
+
try {
|
|
34
|
+
return (await analyze(args.command, cwd))?.mutationMode === 'none';
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The PreToolUse decision for a room member's call: the hook's own `decision`
|
|
41
|
+
* when it denies or the call only reads; otherwise an approval ask that keeps
|
|
42
|
+
* any rewrite the hook made. */
|
|
43
|
+
export async function roomMemberToolDecision(call, decision, analyze) {
|
|
44
|
+
const action = String(decision?.action || decision?.decision || '').toLowerCase();
|
|
45
|
+
if (action === 'deny' || action === 'block') return decision;
|
|
46
|
+
if (await isReadOnlyRoomCall(call, analyze)) return decision;
|
|
47
|
+
return { ...(decision && typeof decision === 'object' ? decision : {}), action: 'ask', reason: ROOM_APPROVAL_REASON };
|
|
48
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A routine fire (schedule or webhook) is a TURN in its owner bot's home
|
|
3
|
+
* thread (`sess_home_<agentId>`): the routine's instructions are delivered
|
|
4
|
+
* there as a queued turn the bot handles itself — doing it or delegating as
|
|
5
|
+
* in any turn — and its reply in the chat is the result. Nothing else is
|
|
6
|
+
* created: no run session, no result card.
|
|
7
|
+
*
|
|
8
|
+
* The turn waits behind the thread's own work (a user turn, another routine):
|
|
9
|
+
* it rides the thread's queue as its own `routine` entry (one per turn, never
|
|
10
|
+
* merged or steered into another), shows as a routine marker row, and selects
|
|
11
|
+
* skills only from the routine's instructions (`skillSelection`), never from a
|
|
12
|
+
* webhook payload. While it runs the thread counts as unattended, so its
|
|
13
|
+
* approvals are held for the owner (held-requests.mjs). Resolves with the
|
|
14
|
+
* reply once the turn ends; rejects when the turn fails, is cancelled, or the
|
|
15
|
+
* caller's `signal` aborts (which also aborts the turn once it runs).
|
|
16
|
+
*/
|
|
17
|
+
import { randomUUID } from 'node:crypto';
|
|
18
|
+
import { agentHomeSessionId } from '../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
19
|
+
import { routineHumanNeededText } from '../runtime/agent/orchestrator/session/routine-result.mjs';
|
|
20
|
+
import { automationPromptContent } from '../runtime/shared/automation-attachments.mjs';
|
|
21
|
+
import { ROUTINE_LIMITS } from '../runtime/shared/routine-limits.mjs';
|
|
22
|
+
import { normalizeRoutineTrigger, routineTriggerHeader } from '../runtime/shared/routine-trigger.mjs';
|
|
23
|
+
import { agentHomeLiveSurface, scheduleOwnerAgentId } from './agent-home-delivery.mjs';
|
|
24
|
+
import { markUnattendedRun, unattendedRunOf } from './held-requests.mjs';
|
|
25
|
+
|
|
26
|
+
// Routine turns waiting or running per home thread.
|
|
27
|
+
const waiting = new Map();
|
|
28
|
+
|
|
29
|
+
const abortError = (signal) =>
|
|
30
|
+
signal?.reason instanceof Error ? signal.reason : new Error(String(signal?.reason || 'routine run aborted'));
|
|
31
|
+
|
|
32
|
+
async function defaultLoadSession(sessionId) {
|
|
33
|
+
const { loadSession } = await import('../runtime/agent/orchestrator/session/store.mjs');
|
|
34
|
+
return loadSession(sessionId);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function settledError(detail) {
|
|
38
|
+
if (detail?.status === 'cancelled') return new Error('the routine turn was cancelled');
|
|
39
|
+
if (detail?.status === 'rejected') return new Error("the bot's chat closed before the routine ran");
|
|
40
|
+
const error = detail?.error;
|
|
41
|
+
return new Error(String(error?.message || error || 'the routine turn failed'));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Deliver one fire of routine `name` (`kind` schedule | webhook) to its
|
|
46
|
+
* owner's home thread. `prompt` is the model-visible body (instructions, plus
|
|
47
|
+
* a webhook's fenced payload); `skillSelection` its trusted part (default:
|
|
48
|
+
* the whole body); `event` a short label for the marker (webhook event).
|
|
49
|
+
*/
|
|
50
|
+
export async function runRoutineTurn(
|
|
51
|
+
{
|
|
52
|
+
kind,
|
|
53
|
+
name,
|
|
54
|
+
ownerAgentId = null,
|
|
55
|
+
prompt,
|
|
56
|
+
skillSelection = null,
|
|
57
|
+
attachments = null,
|
|
58
|
+
cwd = null,
|
|
59
|
+
event = '',
|
|
60
|
+
signal = null,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
surface = agentHomeLiveSurface(),
|
|
64
|
+
loadSession = defaultLoadSession,
|
|
65
|
+
limit = ROUTINE_LIMITS.homeQueueLimit,
|
|
66
|
+
log = (line) => process.stderr.write(`mixdog routines: ${line}\n`),
|
|
67
|
+
} = {}
|
|
68
|
+
) {
|
|
69
|
+
const body = String(prompt || '').trim();
|
|
70
|
+
if (!body) throw new Error(`${kind} "${name}" has no instructions`);
|
|
71
|
+
if (signal?.aborted) throw abortError(signal);
|
|
72
|
+
if (typeof surface?.submit !== 'function') throw new Error('routine run: the session service is not running');
|
|
73
|
+
const agentId = scheduleOwnerAgentId({ ownerAgentId });
|
|
74
|
+
const homeId = agentHomeSessionId(agentId);
|
|
75
|
+
const home = await loadSession(homeId);
|
|
76
|
+
if (!home || home.closed === true) {
|
|
77
|
+
throw new Error(`the bot "${agentId}" has no chat yet: open it once in the app`);
|
|
78
|
+
}
|
|
79
|
+
const queued = waiting.get(homeId) || 0;
|
|
80
|
+
if (queued >= limit) throw new Error(`${limit} routine runs already wait in this bot's chat`);
|
|
81
|
+
waiting.set(homeId, queued + 1);
|
|
82
|
+
const trigger = normalizeRoutineTrigger({ kind, name, event });
|
|
83
|
+
const header = routineTriggerHeader({ kind, name, project: cwd ? String(cwd) : '' });
|
|
84
|
+
const content = automationPromptContent(`${header}\n\n${body}`, attachments);
|
|
85
|
+
return new Promise((resolve, reject) => {
|
|
86
|
+
let started = false;
|
|
87
|
+
let aborted = false;
|
|
88
|
+
let done = false;
|
|
89
|
+
let unmark = () => {};
|
|
90
|
+
let released = false;
|
|
91
|
+
const release = () => {
|
|
92
|
+
if (released) return;
|
|
93
|
+
released = true;
|
|
94
|
+
const left = (waiting.get(homeId) || 1) - 1;
|
|
95
|
+
if (left > 0) waiting.set(homeId, left);
|
|
96
|
+
else waiting.delete(homeId);
|
|
97
|
+
signal?.removeEventListener?.('abort', onAbort);
|
|
98
|
+
};
|
|
99
|
+
const finish = (fn, value) => {
|
|
100
|
+
if (done) return;
|
|
101
|
+
done = true;
|
|
102
|
+
fn(value);
|
|
103
|
+
};
|
|
104
|
+
const abortTurn = () =>
|
|
105
|
+
Promise.resolve()
|
|
106
|
+
.then(() => surface.abort?.(homeId))
|
|
107
|
+
.catch((error) => log(`aborting ${kind} "${name}" in ${homeId} failed: ${error?.message || error}`));
|
|
108
|
+
function onAbort() {
|
|
109
|
+
aborted = true;
|
|
110
|
+
if (started) void abortTurn();
|
|
111
|
+
finish(reject, abortError(signal));
|
|
112
|
+
}
|
|
113
|
+
signal?.addEventListener?.('abort', onAbort, { once: true });
|
|
114
|
+
const options = {
|
|
115
|
+
id: `routine_${randomUUID()}`,
|
|
116
|
+
mode: 'routine',
|
|
117
|
+
// Runs after the thread's current turn, never steered into it.
|
|
118
|
+
priority: 'later',
|
|
119
|
+
isMeta: true,
|
|
120
|
+
skipSlashCommands: true,
|
|
121
|
+
restorable: false,
|
|
122
|
+
// Esc ends this fire; it is never put back in the queue.
|
|
123
|
+
abortDiscardOnAbort: true,
|
|
124
|
+
skillSelection: String(skillSelection ?? body),
|
|
125
|
+
transcriptMeta: { routineTrigger: trigger },
|
|
126
|
+
onCommitted: () => {
|
|
127
|
+
if (started) return;
|
|
128
|
+
started = true;
|
|
129
|
+
// Nobody watches this turn: its approvals are held for the owner.
|
|
130
|
+
unmark = markUnattendedRun(homeId, { kind, agentId, name });
|
|
131
|
+
if (aborted) void abortTurn();
|
|
132
|
+
},
|
|
133
|
+
onSettled: (detail) => {
|
|
134
|
+
// Read before unmarking: a step only a person can do ended the turn.
|
|
135
|
+
const human = unattendedRunOf(homeId)?.humanNeeded;
|
|
136
|
+
unmark();
|
|
137
|
+
release();
|
|
138
|
+
if (human) finish(reject, new Error(routineHumanNeededText(human.outcome, human.site)));
|
|
139
|
+
else if (detail?.status === 'done') {
|
|
140
|
+
finish(resolve, { sessionId: homeId, result: String(detail?.result?.content || '') });
|
|
141
|
+
} else finish(reject, settledError(detail));
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
Promise.resolve()
|
|
145
|
+
.then(() => surface.submit(homeId, content, options))
|
|
146
|
+
.then((accepted) => {
|
|
147
|
+
if (accepted === true) return;
|
|
148
|
+
release();
|
|
149
|
+
finish(reject, new Error(`the bot's chat did not accept the ${kind} "${name}"`));
|
|
150
|
+
})
|
|
151
|
+
.catch((error) => {
|
|
152
|
+
release();
|
|
153
|
+
finish(reject, error);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Routines are bot-based: a schedule or webhook runs in its owner bot's home
|
|
3
|
+
* thread (routine-home-turn.mjs) and nowhere else. An owner that does not
|
|
4
|
+
* exist — Mixy before the representative bot was created, a bot archived or
|
|
5
|
+
* deleted — makes the routine paused: it does not fire, the lists show why,
|
|
6
|
+
* and a new routine cannot name it.
|
|
7
|
+
*/
|
|
8
|
+
import { MIXY_AGENT_ID } from '../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
9
|
+
import { scheduleOwnerAgentId } from './agent-home-delivery.mjs';
|
|
10
|
+
|
|
11
|
+
/** `ownerProblem` codes and the error each one raises. */
|
|
12
|
+
export const ROUTINE_OWNER_PROBLEMS = Object.freeze({
|
|
13
|
+
'no-mixy': 'Create the representative bot first.',
|
|
14
|
+
'owner-deleted': 'The bot that owns this routine no longer exists. Pick another bot.',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
let editor = null;
|
|
18
|
+
async function defaultProbe() {
|
|
19
|
+
if (!editor) {
|
|
20
|
+
const [{ getPluginData }, { createAgentEditorApi }] = await Promise.all([
|
|
21
|
+
import('../runtime/agent/orchestrator/config.mjs'),
|
|
22
|
+
import('./workflow-agents-api/agent-editor.mjs'),
|
|
23
|
+
]);
|
|
24
|
+
editor = createAgentEditorApi({ cfgMod: { getPluginData } });
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
// An undecided profile (null) counts as having Mixy: nobody is blocked by
|
|
28
|
+
// a flag the host has not written yet.
|
|
29
|
+
mixyExists: () => editor.getLeadStatus().created !== false,
|
|
30
|
+
presence: (agentId) => editor.agentDefinitionPresence([agentId])[agentId],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Why `ownerAgentId` (none = Mixy) cannot own or run a routine: a
|
|
35
|
+
* ROUTINE_OWNER_PROBLEMS code, '' when it can. Only a proven deletion
|
|
36
|
+
* counts for a bot; a read fault never pauses anything. */
|
|
37
|
+
export async function routineOwnerProblem(ownerAgentId, probe = null) {
|
|
38
|
+
const owner = scheduleOwnerAgentId({ ownerAgentId });
|
|
39
|
+
const check = probe || (await defaultProbe());
|
|
40
|
+
if (owner === MIXY_AGENT_ID) return check.mixyExists() ? '' : 'no-mixy';
|
|
41
|
+
return check.presence(owner) === 'deleted' ? 'owner-deleted' : '';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Rejects with the owner's problem; resolves when it can own a routine. */
|
|
45
|
+
export async function assertRoutineOwner(ownerAgentId, probe = null) {
|
|
46
|
+
const problem = await routineOwnerProblem(ownerAgentId, probe);
|
|
47
|
+
if (problem) throw new Error(ROUTINE_OWNER_PROBLEMS[problem]);
|
|
48
|
+
}
|
|
@@ -1,71 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Run a schedule
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* filter as its own type, so it shows in desktop Recent / TUI resume), the
|
|
7
|
-
* schedule's provider/model route, and the schedule's project cwd.
|
|
2
|
+
* Run a schedule fire: its instructions become one turn in its owner bot's
|
|
3
|
+
* home thread (routine-home-turn.mjs), under the owned-routine guards
|
|
4
|
+
* (owned-automation-run.mjs). Shared by the engine's "Run now" and the
|
|
5
|
+
* channels-worker scheduler.
|
|
8
6
|
*/
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { modelRouteFields, parseScheduleModelRef } from '../runtime/shared/schedule-model-ref.mjs';
|
|
13
|
-
import { migrateCodexRoute } from '../runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs';
|
|
14
|
-
import { automationWorkflowOpts } from './automation-workflow.mjs';
|
|
15
|
-
import { runAutomationTurns } from './automation-agents.mjs';
|
|
16
|
-
import { automationPromptContent } from '../runtime/shared/automation-attachments.mjs';
|
|
17
|
-
|
|
18
|
-
/** Resolve schedule.model into a {provider,model,effort?,fast?} route. */
|
|
19
|
-
function scheduleRouteFromModelRef(modelRef, config = null) {
|
|
20
|
-
const ref = parseScheduleModelRef(modelRef);
|
|
21
|
-
// A model the provider catalog superseded runs on its successor.
|
|
22
|
-
if (ref && typeof ref === 'object') return migrateCodexRoute(ref);
|
|
23
|
-
const cfg = config || loadConfig({ secrets: false });
|
|
24
|
-
const preset = cfg.presets?.find((p) => p.id === ref || p.name === ref);
|
|
25
|
-
if (!preset) {
|
|
26
|
-
throw new Error(`schedule model "${ref}" is neither a provider/model route nor a known preset name`);
|
|
27
|
-
}
|
|
28
|
-
return modelRouteFields(preset);
|
|
29
|
-
}
|
|
7
|
+
import { markScheduleSkipped } from '../runtime/channels/lib/schedules-db.mjs';
|
|
8
|
+
import { runOwnedAutomation } from './owned-automation-run.mjs';
|
|
9
|
+
import { runRoutineTurn } from './routine-home-turn.mjs';
|
|
30
10
|
|
|
31
11
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* while the fallback gets a small origin header.
|
|
12
|
+
* One fire of `schedule`. `prompt` overrides schedule.prompt when the caller
|
|
13
|
+
* (channels worker) already resolved the body; `attended` marks a person's
|
|
14
|
+
* "Run now" (no failure backoff).
|
|
36
15
|
*/
|
|
37
|
-
export async function runScheduleSession(schedule, {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
sourceType: 'schedule',
|
|
53
|
-
sourceName: schedule.name,
|
|
54
|
-
...(cwd ? { cwd } : {}),
|
|
55
|
-
desktopSession: cwd
|
|
56
|
-
? { classification: 'project', projectPath: cwd }
|
|
57
|
-
: { classification: 'task', projectPath: null },
|
|
58
|
-
...automationWorkflowOpts(schedule.workflow),
|
|
59
|
-
});
|
|
60
|
-
// The user message is the schedule's instructions verbatim: the desktop
|
|
61
|
-
// title/preview derive from it, so no "[Scheduled task: …]" header noise.
|
|
62
|
-
// Stored attachments ride along as composer-style content parts.
|
|
63
|
-
const content = automationPromptContent(prompt, schedule.attachments);
|
|
64
|
-
// Agents the run delegates to report back; each result is the next turn.
|
|
65
|
-
const result = await runAutomationTurns(
|
|
66
|
-
session.id,
|
|
67
|
-
() => askSession(session.id, content, null, null, cwd || undefined),
|
|
68
|
-
(completions, askOpts) => askSession(session.id, completions, null, null, cwd || undefined, undefined, askOpts)
|
|
16
|
+
export async function runScheduleSession(schedule, { attended = false, prompt = null, signal = null } = {}) {
|
|
17
|
+
const body = String(prompt ?? schedule.prompt ?? '').trim();
|
|
18
|
+
return runOwnedSchedule(
|
|
19
|
+
schedule,
|
|
20
|
+
({ signal: runSignal }) =>
|
|
21
|
+
runRoutineTurn({
|
|
22
|
+
kind: 'schedule',
|
|
23
|
+
name: schedule.name,
|
|
24
|
+
ownerAgentId: schedule.ownerAgentId,
|
|
25
|
+
prompt: body,
|
|
26
|
+
attachments: schedule.attachments,
|
|
27
|
+
cwd: schedule.cwd || null,
|
|
28
|
+
signal: runSignal,
|
|
29
|
+
}),
|
|
30
|
+
{ attended, signal }
|
|
69
31
|
);
|
|
70
|
-
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** One owned run of `schedule` (owned-automation-run.mjs). */
|
|
35
|
+
export function runOwnedSchedule(schedule, run, { recordSkip = markScheduleSkipped, ...deps } = {}) {
|
|
36
|
+
return runOwnedAutomation('schedule', schedule, run, { recordSkip, ...deps });
|
|
71
37
|
}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
import { agentScope, clean, clearAgentStatuslineRoute } from './helpers.mjs';
|
|
9
9
|
import { isLeadPoolAgent } from './worker-rows.mjs';
|
|
10
10
|
import { createCloseAll } from './close-flow/close-all.mjs';
|
|
11
|
+
import { closeManagedSession } from '../../lifecycle/shared.mjs';
|
|
11
12
|
|
|
12
13
|
const CLOSE_REASON = 'cancelled by agent close';
|
|
13
14
|
|
|
@@ -68,7 +69,7 @@ export function createCloseFlow({ mgr, registry, views }) {
|
|
|
68
69
|
// below is an idempotent no-op fallback once terminal.
|
|
69
70
|
// Closing a runtime cancels its work; only explicit session deletion
|
|
70
71
|
// may tombstone the conversation.
|
|
71
|
-
const ok = await mgr
|
|
72
|
+
const ok = await closeManagedSession(mgr, sessionId, 'cli-agent-close', { tombstone: false });
|
|
72
73
|
if (task?.taskId) cancelBackgroundTask(task.taskId, CLOSE_REASON);
|
|
73
74
|
// Drop the row only once the cancellation is DURABLY recorded: a failed
|
|
74
75
|
// close that still forgot the row would leave no cancelled state behind.
|
|
@@ -352,6 +352,16 @@ export function readAgentFrontmatterPermission(agent, dataDir, standaloneSourceR
|
|
|
352
352
|
);
|
|
353
353
|
}
|
|
354
354
|
|
|
355
|
+
const _frontmatterKindCache = new Map(); // key -> { value, atMs }
|
|
356
|
+
|
|
357
|
+
/** The agent definition's frontmatter `kind` (isContactAgentId reads it), or
|
|
358
|
+
* null when it sets none. */
|
|
359
|
+
export function readAgentFrontmatterKind(agent, dataDir, standaloneSourceRoot) {
|
|
360
|
+
return cachedFrontmatterValue(_frontmatterKindCache, agent, dataDir, standaloneSourceRoot, (fm) =>
|
|
361
|
+
typeof fm.kind === 'string' && fm.kind.trim() ? fm.kind.trim() : null
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
355
365
|
/** The agent definition's `firstResponseTimeoutMs` (a non-negative integer;
|
|
356
366
|
* 0 disables the first-response deadline), or null when it sets none. */
|
|
357
367
|
export function readAgentFirstResponseTimeoutMs(agent, dataDir, standaloneSourceRoot) {
|
|
@@ -76,13 +76,21 @@ export function createAgentList({ mgr, refreshTagsFromSessions, agentSessionEntr
|
|
|
76
76
|
return function list({ scanSessions = false, context = {}, includeTerminal = false } = {}) {
|
|
77
77
|
refreshTagsFromSessions({ scanSessions, context });
|
|
78
78
|
const now = Date.now();
|
|
79
|
-
const rows = agentSessionEntries({ scanSessions, context }).map(({ tag, session, indexRow }) =>
|
|
79
|
+
const rows = agentSessionEntries({ scanSessions, context }).map(({ tag, session, indexRow, loaded }) =>
|
|
80
80
|
agentRow({
|
|
81
81
|
tag,
|
|
82
82
|
session,
|
|
83
83
|
indexRow,
|
|
84
84
|
runtime: mgr.getSessionRuntime?.(session.id),
|
|
85
|
-
|
|
85
|
+
// A tag-bound entry is the getSession answer itself; an index row or
|
|
86
|
+
// a scanned summary is only a projection and still reads the session.
|
|
87
|
+
progress: progress.sessionProgressExtras(
|
|
88
|
+
session.id,
|
|
89
|
+
session.agent || null,
|
|
90
|
+
now,
|
|
91
|
+
null,
|
|
92
|
+
loaded ? { loaded: session } : {}
|
|
93
|
+
),
|
|
86
94
|
now,
|
|
87
95
|
})
|
|
88
96
|
);
|
|
@@ -58,9 +58,16 @@ export function liveAgentStatusRow(row) {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export function createSessionProgress({ mgr }) {
|
|
61
|
-
|
|
61
|
+
/** `loaded`: the caller's own getSession(sessionId) answer from this same
|
|
62
|
+
* read, so the session is not loaded a second time. */
|
|
63
|
+
function sessionProgressExtras(sessionId, role, now = Date.now(), taskStatus = null, { loaded } = {}) {
|
|
62
64
|
if (!sessionId) return {};
|
|
63
|
-
|
|
65
|
+
// Only the session's status is read here: the manager's stamp-validated
|
|
66
|
+
// status lookup spares a whole-transcript read per idle worker per pulse.
|
|
67
|
+
let sessionStatus;
|
|
68
|
+
if (loaded !== undefined) sessionStatus = loaded?.status || null;
|
|
69
|
+
else if (typeof mgr.loadSessionStatus === 'function') sessionStatus = mgr.loadSessionStatus(sessionId) || null;
|
|
70
|
+
else sessionStatus = mgr.getSession(sessionId)?.status || null;
|
|
64
71
|
const runtime = mgr.getSessionRuntime?.(sessionId) || null;
|
|
65
72
|
const snapshot =
|
|
66
73
|
typeof mgr.getSessionProgressSnapshot === 'function' ? mgr.getSessionProgressSnapshot(sessionId) : null;
|
|
@@ -72,8 +79,8 @@ export function createSessionProgress({ mgr }) {
|
|
|
72
79
|
typeof mgr.getSessionPendingMessageDepth === 'function' ? mgr.getSessionPendingMessageDepth(sessionId) : null;
|
|
73
80
|
return buildAgentTaskProgressFields({
|
|
74
81
|
now,
|
|
75
|
-
sessionStatus
|
|
76
|
-
runtimeStage: runtime?.stage || snapshot?.stage ||
|
|
82
|
+
sessionStatus,
|
|
83
|
+
runtimeStage: runtime?.stage || snapshot?.stage || sessionStatus,
|
|
77
84
|
snapshot,
|
|
78
85
|
runtime,
|
|
79
86
|
policy,
|
|
@@ -96,6 +103,8 @@ export function createSessionProgress({ mgr }) {
|
|
|
96
103
|
stage: progress.worker_stage || runtime?.stage || status,
|
|
97
104
|
// Additive: present only while the worker's turn waits on a user approval.
|
|
98
105
|
...(runtime?.awaitingUser ? { awaitingUser: runtime.awaitingUser } : {}),
|
|
106
|
+
// Additive: present only while the worker's turn sits in `task wait`.
|
|
107
|
+
...(runtime?.taskWaits > 0 ? { awaitingTask: 'wait' } : {}),
|
|
99
108
|
clientHostPid: session.clientHostPid || null,
|
|
100
109
|
lastStreamDeltaAt: runtime?.lastStreamDeltaAt ? new Date(runtime.lastStreamDeltaAt).toISOString() : null,
|
|
101
110
|
...progress,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import { clean } from './helpers.mjs';
|
|
10
10
|
import { createEarlyCompletionNotice } from './notify/early-completion.mjs';
|
|
11
11
|
|
|
12
|
-
export function createNotify(mgr, { notifySessionCompletion } = {}) {
|
|
12
|
+
export function createNotify(mgr, { notifySessionCompletion, onWorkerCompletionQueued = null } = {}) {
|
|
13
13
|
function enqueueCompletionMessage(sessionId, text, meta = {}) {
|
|
14
14
|
const target = clean(sessionId);
|
|
15
15
|
if (!target || typeof mgr.enqueuePendingMessage !== 'function') return false;
|
|
@@ -28,8 +28,8 @@ export function createNotify(mgr, { notifySessionCompletion } = {}) {
|
|
|
28
28
|
logDuplicateSkip('notify-enqueue', { executionId: meta?.execution_id, text: visible });
|
|
29
29
|
return true;
|
|
30
30
|
}
|
|
31
|
-
// Mark this as a
|
|
32
|
-
//
|
|
31
|
+
// Mark this as a completion/task notification: delivery dedupes it by
|
|
32
|
+
// execution id, and it stays queued (durably) until the model gets it.
|
|
33
33
|
return Boolean(
|
|
34
34
|
mgr.enqueuePendingMessage(
|
|
35
35
|
target,
|
|
@@ -67,7 +67,18 @@ export function createNotify(mgr, { notifySessionCompletion } = {}) {
|
|
|
67
67
|
// appear as a second Lead-level completion card. Agent task completion
|
|
68
68
|
// has its own owner delivery path below; only that terminal handoff
|
|
69
69
|
// crosses the parent boundary.
|
|
70
|
-
|
|
70
|
+
if (!workerId) return false;
|
|
71
|
+
const queued = enqueueCompletionMessage(workerId, text, meta);
|
|
72
|
+
// A busy worker takes the completion at its next tool boundary; an idle
|
|
73
|
+
// one is woken so the result reaches it now, not at its next message.
|
|
74
|
+
if (queued && typeof onWorkerCompletionQueued === 'function') {
|
|
75
|
+
setImmediate(() => {
|
|
76
|
+
try {
|
|
77
|
+
onWorkerCompletionQueued(workerId);
|
|
78
|
+
} catch {}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return queued;
|
|
71
82
|
};
|
|
72
83
|
}
|
|
73
84
|
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// agent-tool/restart-notify.mjs
|
|
2
|
+
// Agent tasks live in process memory, so a daemon restart ends every in-flight
|
|
3
|
+
// one without a word: the successor only sees worker rows left `failed`
|
|
4
|
+
// (process-restart). This tells each task's owner, exactly once.
|
|
5
|
+
//
|
|
6
|
+
// Order is what makes it safe: the failure notification is enqueued in the
|
|
7
|
+
// owner's persisted pending queue under a stable id (`restart:<taskId>`) and
|
|
8
|
+
// flushed to the spool FIRST; only then is the row stamped `restartNotified`.
|
|
9
|
+
// A crash or a throw before the stamp leaves the row retryable, and the retry
|
|
10
|
+
// re-enqueues the same id — the queue is id-idempotent, so the owner still
|
|
11
|
+
// sees it once.
|
|
12
|
+
import {
|
|
13
|
+
acknowledgeBackgroundTaskCompletion,
|
|
14
|
+
completeBackgroundTask,
|
|
15
|
+
getBackgroundTask,
|
|
16
|
+
registerBackgroundTask,
|
|
17
|
+
} from '../../../runtime/shared/background-tasks.mjs';
|
|
18
|
+
import { renderAgentCompletionEnvelope } from '../../../runtime/shared/task-notification-envelope.mjs';
|
|
19
|
+
import { modelVisibleToolCompletionMessage } from '../../../runtime/shared/tool-execution-contract.mjs';
|
|
20
|
+
import { clean } from './helpers.mjs';
|
|
21
|
+
|
|
22
|
+
const RESTART_FAILURE_ERROR = 'process restart: the daemon restarted while this agent task was running';
|
|
23
|
+
const SETTLE_TIMEOUT_MS = 5000;
|
|
24
|
+
|
|
25
|
+
/** Stable dedup id of one lost task's notification. A row that never recorded
|
|
26
|
+
* a task id falls back to its session and settle time. */
|
|
27
|
+
export function restartNotificationId(row) {
|
|
28
|
+
return `restart:${clean(row.task_id) || `${clean(row.sessionId)}:${clean(row.finishedAt)}`}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** `pendingRestartFailures()` lists rows whose owner is not yet told;
|
|
32
|
+
* `markRestartNotified(rows)` stamps them. `mgr` supplies the persisted
|
|
33
|
+
* pending queue (enqueuePendingMessage / markCompletionEntry /
|
|
34
|
+
* settlePendingMessageWrites). `notifySessionCompletion` is only the live,
|
|
35
|
+
* best-effort emit to attached surfaces after the durable enqueue. */
|
|
36
|
+
export function createRestartFailureNotifier({
|
|
37
|
+
pendingRestartFailures,
|
|
38
|
+
markRestartNotified,
|
|
39
|
+
mgr,
|
|
40
|
+
notifySessionCompletion,
|
|
41
|
+
}) {
|
|
42
|
+
function enqueueDurably(row) {
|
|
43
|
+
const owner = clean(row.ownerSessionId);
|
|
44
|
+
const executionId = restartNotificationId(row);
|
|
45
|
+
const meta = {
|
|
46
|
+
type: 'agent_task_result',
|
|
47
|
+
execution_surface: 'agent',
|
|
48
|
+
execution_id: executionId,
|
|
49
|
+
status: 'failed',
|
|
50
|
+
caller_session_id: owner,
|
|
51
|
+
};
|
|
52
|
+
const text = renderAgentCompletionEnvelope({
|
|
53
|
+
id: clean(row.task_id) || executionId,
|
|
54
|
+
tag: row.tag,
|
|
55
|
+
status: 'failed',
|
|
56
|
+
error: RESTART_FAILURE_ERROR,
|
|
57
|
+
});
|
|
58
|
+
const entry = mgr.markCompletionEntry(modelVisibleToolCompletionMessage(text, meta), { executionId, meta });
|
|
59
|
+
return { owner, text, meta, entry };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Lets `agent status <id>` resolve after the restart; best-effort.
|
|
63
|
+
function registerFailedTask(row) {
|
|
64
|
+
const taskId = clean(row.task_id);
|
|
65
|
+
if (!taskId || getBackgroundTask(taskId)) return;
|
|
66
|
+
const owner = clean(row.ownerSessionId);
|
|
67
|
+
registerBackgroundTask({
|
|
68
|
+
taskId,
|
|
69
|
+
surface: 'agent',
|
|
70
|
+
operation: 'restart',
|
|
71
|
+
label: row.tag,
|
|
72
|
+
input: { type: 'restart', tag: row.tag, sessionId: row.sessionId, agent: row.agent || null },
|
|
73
|
+
context: { callerSessionId: owner, ownerSessionId: owner, clientHostPid: row.clientHostPid || null },
|
|
74
|
+
meta: {
|
|
75
|
+
tag: row.tag,
|
|
76
|
+
sessionId: row.sessionId,
|
|
77
|
+
agent: row.agent || null,
|
|
78
|
+
provider: row.provider || null,
|
|
79
|
+
model: row.model || null,
|
|
80
|
+
preset: row.preset || null,
|
|
81
|
+
effort: row.effort || null,
|
|
82
|
+
},
|
|
83
|
+
resultType: 'agent_task_result',
|
|
84
|
+
});
|
|
85
|
+
completeBackgroundTask(taskId, {
|
|
86
|
+
status: 'failed',
|
|
87
|
+
error: RESTART_FAILURE_ERROR,
|
|
88
|
+
terminalReason: 'process-restart',
|
|
89
|
+
notify: false,
|
|
90
|
+
});
|
|
91
|
+
acknowledgeBackgroundTaskCompletion(taskId);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function notifyRow(row) {
|
|
95
|
+
const { owner, text, meta, entry } = enqueueDurably(row);
|
|
96
|
+
if (!(mgr.enqueuePendingMessage(owner, entry) > 0)) throw new Error(`restart notification refused for ${owner}`);
|
|
97
|
+
if (!(await mgr.settlePendingMessageWrites({ timeoutMs: SETTLE_TIMEOUT_MS }))) {
|
|
98
|
+
throw new Error(`restart notification for ${owner} did not reach the spool`);
|
|
99
|
+
}
|
|
100
|
+
markRestartNotified([row]);
|
|
101
|
+
try {
|
|
102
|
+
registerFailedTask(row);
|
|
103
|
+
} catch {
|
|
104
|
+
/* status lookup only */
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
// Same execution id as the queued entry: the queue dedups the mirror.
|
|
108
|
+
notifySessionCompletion?.(owner, text, meta);
|
|
109
|
+
} catch {
|
|
110
|
+
/* the durable queue is authoritative */
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let inFlight = null;
|
|
115
|
+
async function run() {
|
|
116
|
+
for (const row of pendingRestartFailures()) {
|
|
117
|
+
try {
|
|
118
|
+
await notifyRow(row);
|
|
119
|
+
} catch (err) {
|
|
120
|
+
// Not stamped: the next pass or restart retries this row.
|
|
121
|
+
process.stderr.write(`[agent-tool] restart notification retry pending: ${err?.message || err}\n`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return function notifyRestartFailures() {
|
|
127
|
+
inFlight ||= run()
|
|
128
|
+
.catch((err) => process.stderr.write(`[agent-tool] restart notification pass failed: ${err?.message || err}\n`))
|
|
129
|
+
.finally(() => {
|
|
130
|
+
inFlight = null;
|
|
131
|
+
});
|
|
132
|
+
return inFlight;
|
|
133
|
+
};
|
|
134
|
+
}
|