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
|
@@ -98,6 +98,8 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
98
98
|
registry.upsertWorkerSessionDeferred(session, tag, {
|
|
99
99
|
status: 'running',
|
|
100
100
|
stage: 'running',
|
|
101
|
+
// The send's own task: a restart that ends this turn reports it by id.
|
|
102
|
+
task_id: job?.taskId,
|
|
101
103
|
turnStartedAt: new Date().toISOString(),
|
|
102
104
|
});
|
|
103
105
|
let handoffMsgStart = 0;
|
|
@@ -224,5 +226,26 @@ export function createSendFlow({ mgr, defaultCwd, sessionSurface, canUseSessionS
|
|
|
224
226
|
return renderResult({ ...extras, ...views.renderJob(job, false) });
|
|
225
227
|
}
|
|
226
228
|
|
|
227
|
-
|
|
229
|
+
// A background-task completion was queued for this worker. A busy worker
|
|
230
|
+
// takes it at its next tool boundary; an idle one runs a follow-up turn on
|
|
231
|
+
// an empty prompt, which drains the queued completion (never an empty user
|
|
232
|
+
// turn). Its answer reaches the owner like any send result.
|
|
233
|
+
function wakeIdleWorker(sessionId) {
|
|
234
|
+
const id = clean(sessionId);
|
|
235
|
+
if (!id || views.isSessionBusy(id)) return false;
|
|
236
|
+
const session = mgr.getSession(id);
|
|
237
|
+
if (!session || session.closed) return false;
|
|
238
|
+
const owner = clean(session.ownerSessionId || session.parentSessionId);
|
|
239
|
+
const notifyContext = owner
|
|
240
|
+
? { callerSessionId: owner, ownerSessionId: owner, clientHostPid: session.clientHostPid || null }
|
|
241
|
+
: null;
|
|
242
|
+
void dispatchToExistingSession({ args: {}, session, sessionId: id, prompt: '' }, notifyContext).catch((error) => {
|
|
243
|
+
try {
|
|
244
|
+
process.stderr.write(`[agent] completion wake failed session=${id}: ${error?.message || error}\n`);
|
|
245
|
+
} catch {}
|
|
246
|
+
});
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
return { prepareSend, dispatchToExistingSession, wakeIdleWorker };
|
|
228
251
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* flip to running, and the cancellation checks around the turn.
|
|
6
6
|
*/
|
|
7
7
|
import { nonNegativeInt, clearAgentStatuslineRoute } from '../helpers.mjs';
|
|
8
|
+
import { closeManagedSession } from '../../../lifecycle/shared.mjs';
|
|
8
9
|
|
|
9
10
|
export function createDeferredSpawn({
|
|
10
11
|
mgr,
|
|
@@ -22,7 +23,7 @@ export function createDeferredSpawn({
|
|
|
22
23
|
function closePreparedSpawn(prepared, reason = 'agent-task-cancel') {
|
|
23
24
|
if (!prepared?.session?.id) return;
|
|
24
25
|
try {
|
|
25
|
-
Promise.resolve(mgr
|
|
26
|
+
Promise.resolve(closeManagedSession(mgr, prepared.session.id, reason)).catch(() => {});
|
|
26
27
|
} catch {}
|
|
27
28
|
try {
|
|
28
29
|
clearAgentStatuslineRoute(prepared.session.id);
|
|
@@ -7,6 +7,7 @@ import { sanitizeTaskMeta, startBackgroundTask } from '../../../../runtime/share
|
|
|
7
7
|
import { resourceAdmission } from '../../../../runtime/shared/resource-admission.mjs';
|
|
8
8
|
import { clean, terminalPidForContext } from '../helpers.mjs';
|
|
9
9
|
import { renderResult } from '../render.mjs';
|
|
10
|
+
import { closeManagedSession } from '../../../lifecycle/shared.mjs';
|
|
10
11
|
|
|
11
12
|
/** The completion callback that hands a worker's result back to its caller session; null without a handoff. */
|
|
12
13
|
function handoffNotifier(handoffSessionId, notifySessionCompletion) {
|
|
@@ -53,9 +54,9 @@ export function createJobStarter({ mgr, notifyStatusChange, notifySessionComplet
|
|
|
53
54
|
const currentMeta = task?.meta || jobMeta;
|
|
54
55
|
if (currentMeta?.sessionId) {
|
|
55
56
|
try {
|
|
56
|
-
Promise.resolve(
|
|
57
|
-
(
|
|
58
|
-
);
|
|
57
|
+
Promise.resolve(
|
|
58
|
+
closeManagedSession(mgr, currentMeta.sessionId, 'agent-task-cancel', { tombstone: false })
|
|
59
|
+
).catch(() => {});
|
|
59
60
|
} catch {}
|
|
60
61
|
}
|
|
61
62
|
setImmediate(notifyStatusChange);
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
agentDefinitionExists,
|
|
10
10
|
clean,
|
|
11
11
|
normalizeAgentName,
|
|
12
|
+
readAgentFrontmatterKind,
|
|
12
13
|
readAgentFrontmatterPermission,
|
|
13
14
|
resolvePrompt,
|
|
14
15
|
terminalPidForContext,
|
|
@@ -18,8 +19,13 @@ import { normalizeAgentPermission } from '../../../../runtime/shared/markdown-fr
|
|
|
18
19
|
import { resolveAgentSpawnPreset } from '../spawn-preset.mjs';
|
|
19
20
|
import { AGENT_OWNER } from '../../../../runtime/agent/orchestrator/agent-owner.mjs';
|
|
20
21
|
import { workspaceCwdLock } from '../../../workspace/admission-gate.mjs';
|
|
22
|
+
import { isContactAgentId } from '../../../../runtime/agent/orchestrator/runtime-core/workflow-ids.mjs';
|
|
23
|
+
import { AGENT_MODE, resolveSessionMode } from '../../../../runtime/agent/orchestrator/session/agent-mode.mjs';
|
|
24
|
+
import { MIXY_AGENT_ID } from '../../../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
25
|
+
import { mixyDisplayName } from '../../../../runtime/agent/orchestrator/session/mixy-name.mjs';
|
|
21
26
|
|
|
22
27
|
export function createSpawnPlanner({
|
|
28
|
+
mgr = null,
|
|
23
29
|
cfgMod,
|
|
24
30
|
dataDir,
|
|
25
31
|
STANDALONE_SOURCE_ROOT,
|
|
@@ -44,6 +50,18 @@ export function createSpawnPlanner({
|
|
|
44
50
|
if (isAgentDisabled(config, agent)) {
|
|
45
51
|
throw new Error(`agent spawn: agent "${agent}" is turned off`);
|
|
46
52
|
}
|
|
53
|
+
// Only Mixy hands work to a contact agent; any other agent-mode Lead
|
|
54
|
+
// delegates to sub-agents alone (its catalog lists no contact either).
|
|
55
|
+
if (isContactAgentId(agent, readAgentFrontmatterKind(agent, dataDir, STANDALONE_SOURCE_ROOT))) {
|
|
56
|
+
const callerId = clean(context?.callerSessionId || context?.sessionId);
|
|
57
|
+
const caller = (callerId && mgr?.getSession?.(callerId)) || null;
|
|
58
|
+
const { mode, agentId } = resolveSessionMode({ session: caller, sessionId: callerId });
|
|
59
|
+
if (mode === AGENT_MODE && agentId !== MIXY_AGENT_ID) {
|
|
60
|
+
throw new Error(
|
|
61
|
+
`agent spawn: only ${mixyDisplayName()} (the representative agent) can hand work to the contact agent "${agent}"; delegate to a sub-agent instead`
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
47
65
|
const agentPermission = readAgentFrontmatterPermission(agent, dataDir, STANDALONE_SOURCE_ROOT);
|
|
48
66
|
const agentPerm = normalizeAgentPermission(agentPermission) || null;
|
|
49
67
|
const { presetName, preset } = resolveAgentSpawnPreset(config, args);
|
|
@@ -56,10 +74,7 @@ export function createSpawnPlanner({
|
|
|
56
74
|
// Workers share their Lead's execution root. While the Lead runs in its
|
|
57
75
|
// worktree, that root is locked: neither args.cwd nor an inherited
|
|
58
76
|
// (pre-transition) cwd can send a worker elsewhere.
|
|
59
|
-
const lockedCwd = workspaceCwdLock([
|
|
60
|
-
context?.ownerSessionId,
|
|
61
|
-
context?.callerSessionId || context?.sessionId,
|
|
62
|
-
]);
|
|
77
|
+
const lockedCwd = workspaceCwdLock([context?.ownerSessionId, context?.callerSessionId || context?.sessionId]);
|
|
63
78
|
const baseCwd = resolve(lockedCwd || callerCwd || defaultCwd || process.cwd());
|
|
64
79
|
const workerCwd = !lockedCwd && clean(args.cwd) ? resolve(baseCwd, args.cwd) : baseCwd;
|
|
65
80
|
const prompt = await resolvePrompt(args, workerCwd);
|
|
@@ -58,8 +58,10 @@ export function createSpawnPreparer({
|
|
|
58
58
|
ensureProvider,
|
|
59
59
|
sessionSurface = null,
|
|
60
60
|
refreshTagsFromSessions,
|
|
61
|
+
mgr = null,
|
|
61
62
|
}) {
|
|
62
63
|
const { resolveSpawnPlan, spawnSessionSpec } = createSpawnPlanner({
|
|
64
|
+
mgr,
|
|
63
65
|
cfgMod,
|
|
64
66
|
dataDir,
|
|
65
67
|
STANDALONE_SOURCE_ROOT,
|
|
@@ -39,9 +39,13 @@ export function createSpawnRunner({
|
|
|
39
39
|
emitSubagentEvent,
|
|
40
40
|
sessionSurface = null,
|
|
41
41
|
createTurnReviewCollector,
|
|
42
|
+
onWorkerCompletionQueued = null,
|
|
42
43
|
}) {
|
|
43
44
|
// Owner/worker completion notification lives in ../notify.mjs.
|
|
44
|
-
const { workerNotifyFn, notifyOwnerAgentCompletionEarly } = createNotify(mgr, {
|
|
45
|
+
const { workerNotifyFn, notifyOwnerAgentCompletionEarly } = createNotify(mgr, {
|
|
46
|
+
notifySessionCompletion,
|
|
47
|
+
onWorkerCompletionQueued,
|
|
48
|
+
});
|
|
45
49
|
|
|
46
50
|
// Idle-progress watchdogs (shared sweep timer) live in
|
|
47
51
|
// agent-watchdog-registry.mjs.
|
|
@@ -32,14 +32,16 @@ export function createTagLookup({ tags, mgr, readWorkerRows, reaper, getLiveSess
|
|
|
32
32
|
const rows = [];
|
|
33
33
|
const seen = new Set();
|
|
34
34
|
const tombstones = reaper.tagTombstoneIndex();
|
|
35
|
-
|
|
35
|
+
// `loaded`: `session` is getLiveSession's own answer (not a catalog
|
|
36
|
+
// summary), so consumers may reuse it instead of loading it again.
|
|
37
|
+
const add = (session, fallbackTag = '', loaded = false) => {
|
|
36
38
|
const tag = agentTagOf(session) || clean(fallbackTag);
|
|
37
39
|
if (!tag || !session?.id || session.closed === true) return;
|
|
38
40
|
if (isLeadPoolAgent(session.agent)) return;
|
|
39
41
|
if (!sessionMatchesContext(session, context)) return;
|
|
40
42
|
if (seen.has(session.id)) return;
|
|
41
43
|
seen.add(session.id);
|
|
42
|
-
rows.push({ tag, session });
|
|
44
|
+
rows.push(loaded ? { tag, session, loaded: true } : { tag, session });
|
|
43
45
|
};
|
|
44
46
|
const addIndexRow = (row) => {
|
|
45
47
|
const tag = clean(row?.tag);
|
|
@@ -70,9 +72,12 @@ export function createTagLookup({ tags, mgr, readWorkerRows, reaper, getLiveSess
|
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
for (const [tag, sessionId] of tags.entries()) {
|
|
75
|
+
// add() drops an id already listed; loading it first (a whole-session
|
|
76
|
+
// read for an idle worker) was pure cost on every status pulse.
|
|
77
|
+
if (seen.has(sessionId)) continue;
|
|
73
78
|
const session = getLiveSession(sessionId);
|
|
74
79
|
if (session && reaper.tombstoneBlocksScan(session, tag, tombstones)) continue;
|
|
75
|
-
add(session, tag);
|
|
80
|
+
add(session, tag, true);
|
|
76
81
|
}
|
|
77
82
|
return rows;
|
|
78
83
|
}
|
|
@@ -112,6 +112,9 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
|
|
|
112
112
|
readWorkerRows,
|
|
113
113
|
writeWorkerRows: index.writeWorkerRows,
|
|
114
114
|
flushWorkerIndexMutations: index.flushWorkerIndexMutations,
|
|
115
|
+
recoverStaleWorkerRows: index.recoverStaleWorkerRows,
|
|
116
|
+
pendingRestartFailures: index.pendingRestartFailures,
|
|
117
|
+
markRestartNotified: index.markRestartNotified,
|
|
115
118
|
upsertWorkerSession: index.upsertWorkerSession,
|
|
116
119
|
upsertWorkerSessionDeferred,
|
|
117
120
|
upsertLeadSession,
|
|
@@ -55,6 +55,9 @@ export function normalizeWorkerRows(value) {
|
|
|
55
55
|
// Why a `failed` row failed (row-liveness, a watchdog stop). Always
|
|
56
56
|
// present, so a later whole-row write clears a stale reason.
|
|
57
57
|
failureReason: clean(row.failureReason) || null,
|
|
58
|
+
// When the owner was told this row's turn died with a process restart;
|
|
59
|
+
// always present, so new work on the row starts unnotified.
|
|
60
|
+
restartNotified: clean(row.restartNotified) || null,
|
|
58
61
|
permission: clean(row.permission) || null,
|
|
59
62
|
toolPermission: clean(row.toolPermission) || null,
|
|
60
63
|
messages: positiveInt(row.messages) || 0,
|
|
@@ -112,6 +115,7 @@ export function workerRowFromSession(session, fallbackTag = '', extra = {}, getS
|
|
|
112
115
|
task_id: clean(extra.task_id || extra.taskId) || null,
|
|
113
116
|
error: clean(extra.error) || null,
|
|
114
117
|
failureReason: clean(extra.failureReason) || null,
|
|
118
|
+
restartNotified: clean(extra.restartNotified) || null,
|
|
115
119
|
permission: clean(session?.permission) || null,
|
|
116
120
|
toolPermission: clean(session?.toolPermission) || null,
|
|
117
121
|
messages: Array.isArray(session?.messages) ? session.messages.length : 0,
|
|
@@ -161,14 +161,19 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
|
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
// Startup recovery: stale active rows settle — as failed when
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
// restart) is
|
|
168
|
-
|
|
164
|
+
// Startup recovery: stale active rows settle — as failed when another
|
|
165
|
+
// process ran their turn (it is gone, or is the predecessor still shutting
|
|
166
|
+
// down: either way the turn never finished), otherwise to idle — and an
|
|
167
|
+
// approval wait left behind by a runtime that is gone (daemon restart) is
|
|
168
|
+
// cleared. `deadOnly` (later sweeps) settles only rows whose runtime is
|
|
169
|
+
// provably dead, never a live process's quiet turn.
|
|
170
|
+
function recoverStaleWorkerRows({ deadOnly = false } = {}) {
|
|
169
171
|
const now = Date.now();
|
|
170
172
|
const rows = store.readAll();
|
|
171
|
-
const
|
|
173
|
+
const isStale = deadOnly
|
|
174
|
+
? (row) => isActiveWorkerRow(row) && runtimeDied(row)
|
|
175
|
+
: (row) => liveness.isStaleActive(row, now);
|
|
176
|
+
const staleActive = rows.filter(isStale);
|
|
172
177
|
const staleWaits = rows.some(isStaleApprovalWait);
|
|
173
178
|
if (!staleActive.length && !staleWaits) return false;
|
|
174
179
|
if (staleActive.length) {
|
|
@@ -176,12 +181,11 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
|
|
|
176
181
|
for (const row of staleActive) {
|
|
177
182
|
const key = workerRowKey(row);
|
|
178
183
|
const current = byKey.get(key);
|
|
179
|
-
if (!current || !
|
|
184
|
+
if (!current || !isStale(current)) continue;
|
|
185
|
+
const ranElsewhere = positiveInt(current.runtimePid) && positiveInt(current.runtimePid) !== process.pid;
|
|
180
186
|
byKey.set(
|
|
181
187
|
key,
|
|
182
|
-
|
|
183
|
-
? liveness.failedRow(current, now, PROCESS_RESTART_FAILURE)
|
|
184
|
-
: liveness.idleRow(current, now)
|
|
188
|
+
ranElsewhere ? liveness.failedRow(current, now, PROCESS_RESTART_FAILURE) : liveness.idleRow(current, now)
|
|
185
189
|
);
|
|
186
190
|
}
|
|
187
191
|
});
|
|
@@ -190,6 +194,34 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
|
|
|
190
194
|
return true;
|
|
191
195
|
}
|
|
192
196
|
|
|
197
|
+
const isUnnotifiedRestartFailure = (row) =>
|
|
198
|
+
row.status === 'failed' &&
|
|
199
|
+
row.failureReason === PROCESS_RESTART_FAILURE &&
|
|
200
|
+
Boolean(clean(row.ownerSessionId)) &&
|
|
201
|
+
!row.restartNotified;
|
|
202
|
+
|
|
203
|
+
/** Rows whose turn a process restart ended and whose owner has not been told
|
|
204
|
+
* yet — whoever settled the row (this process at startup, or the
|
|
205
|
+
* predecessor's exit flush). Read-only: the caller enqueues the owner's
|
|
206
|
+
* notification durably, THEN calls `markRestartNotified`, so a crash in
|
|
207
|
+
* between retries (the notification's stable id makes the retry exactly-once). */
|
|
208
|
+
function pendingRestartFailures() {
|
|
209
|
+
return store.readAll().filter(isUnnotifiedRestartFailure);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** Stamp these rows as told, once their notification is durably queued. */
|
|
213
|
+
function markRestartNotified(rows) {
|
|
214
|
+
const stamp = new Date().toISOString();
|
|
215
|
+
store.write((byKey) => {
|
|
216
|
+
for (const row of rows) {
|
|
217
|
+
const key = workerRowKey(row);
|
|
218
|
+
const current = byKey.get(key);
|
|
219
|
+
if (!current || !isUnnotifiedRestartFailure(current)) continue;
|
|
220
|
+
byKey.set(key, { ...current, restartNotified: stamp });
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
193
225
|
function flushWorkerIndexOnExit() {
|
|
194
226
|
batch.flush();
|
|
195
227
|
flushActiveWorkerRows();
|
|
@@ -285,5 +317,7 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
|
|
|
285
317
|
flushActiveWorkerRows,
|
|
286
318
|
flushWorkerIndexOnExit,
|
|
287
319
|
recoverStaleWorkerRows,
|
|
320
|
+
pendingRestartFailures,
|
|
321
|
+
markRestartNotified,
|
|
288
322
|
};
|
|
289
323
|
}
|
|
@@ -9,6 +9,7 @@ import { liveAgentStatusRow } from './agent-tool/job-views/session-progress.mjs'
|
|
|
9
9
|
import { createSpawnFlow } from './agent-tool/spawn-flow.mjs';
|
|
10
10
|
import { createSendFlow } from './agent-tool/send-flow.mjs';
|
|
11
11
|
import { createCloseFlow } from './agent-tool/close-flow.mjs';
|
|
12
|
+
import { createRestartFailureNotifier } from './agent-tool/restart-notify.mjs';
|
|
12
13
|
import { createTerminalTrace } from './agent-tool/terminal-trace.mjs';
|
|
13
14
|
import { createAgentExecute } from './agent-tool/execute.mjs';
|
|
14
15
|
import { createTurnReviewCollector } from './agent-tool/turn-review.mjs';
|
|
@@ -70,8 +71,24 @@ export function createStandaloneAgent({
|
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
const registry = createTagRegistry({ dataDir, cfgMod, mgr });
|
|
74
|
+
// Tasks the previous process was running died with it: tell their owners.
|
|
75
|
+
// Later sweeps also catch rows the predecessor settled as it shut down.
|
|
76
|
+
const notifyRestartFailures = createRestartFailureNotifier({
|
|
77
|
+
pendingRestartFailures: registry.pendingRestartFailures,
|
|
78
|
+
markRestartNotified: registry.markRestartNotified,
|
|
79
|
+
mgr,
|
|
80
|
+
notifySessionCompletion,
|
|
81
|
+
});
|
|
82
|
+
const sweepRestartFailures = () => {
|
|
83
|
+
registry.recoverStaleWorkerRows({ deadOnly: true });
|
|
84
|
+
notifyRestartFailures();
|
|
85
|
+
};
|
|
86
|
+
notifyRestartFailures();
|
|
73
87
|
const views = createJobViews({ ...registry, mgr, reg, cfgMod, DEFAULT_SPAWN_PREP_TIMEOUT_MS });
|
|
88
|
+
// Late-bound: the send flow that wakes an idle worker is built after spawn.
|
|
89
|
+
let wakeIdleWorker = null;
|
|
74
90
|
const spawnFlow = createSpawnFlow({
|
|
91
|
+
onWorkerCompletionQueued: (sessionId) => wakeIdleWorker?.(sessionId),
|
|
75
92
|
...registry,
|
|
76
93
|
...views,
|
|
77
94
|
mgr,
|
|
@@ -96,6 +113,7 @@ export function createStandaloneAgent({
|
|
|
96
113
|
views,
|
|
97
114
|
spawnFlow,
|
|
98
115
|
});
|
|
116
|
+
wakeIdleWorker = sendFlow.wakeIdleWorker;
|
|
99
117
|
const closeFlow = createCloseFlow({ mgr, registry, views });
|
|
100
118
|
const terminalTrace = createTerminalTrace({ registry });
|
|
101
119
|
const execute = createAgentExecute({
|
|
@@ -116,6 +134,7 @@ export function createStandaloneAgent({
|
|
|
116
134
|
void awaitKeychainPrewarm();
|
|
117
135
|
return { workers: [], jobs: [], scope: null };
|
|
118
136
|
}
|
|
137
|
+
sweepRestartFailures();
|
|
119
138
|
const scopedContext = agentScope({}, context);
|
|
120
139
|
const ownerSession = callerSessionForContext(scopedContext);
|
|
121
140
|
const pid = terminalPidForContext(scopedContext);
|
|
@@ -134,6 +153,7 @@ export function createStandaloneAgent({
|
|
|
134
153
|
void awaitKeychainPrewarm();
|
|
135
154
|
return [];
|
|
136
155
|
}
|
|
156
|
+
sweepRestartFailures();
|
|
137
157
|
const scopedContext = agentScope({ recover: true }, context);
|
|
138
158
|
registry.refreshTagsFromSessions({ scanSessions: true, context: scopedContext });
|
|
139
159
|
return views.list({ scanSessions: false, context: scopedContext });
|
|
@@ -23,13 +23,14 @@ import {
|
|
|
23
23
|
setEndpointEnabled as dbSetEndpointEnabled,
|
|
24
24
|
} from '../../runtime/channels/lib/webhooks-db.mjs';
|
|
25
25
|
import { normalizeAutomationAttachments } from '../../runtime/shared/automation-attachments.mjs';
|
|
26
|
-
import {
|
|
26
|
+
import { assertRoutineOwner, routineOwnerProblem } from '../routine-owner.mjs';
|
|
27
27
|
import { hasEnabledAutomation } from '../../runtime/shared/automation-presence.mjs';
|
|
28
28
|
import { resolveScheduleTimezone, validateScheduleCron } from '../../runtime/shared/schedule-time.mjs';
|
|
29
29
|
import { pgClusterExists } from '../../runtime/memory/lib/pg/adapter.mjs';
|
|
30
30
|
import { resolvePluginData } from '../../runtime/shared/plugin-paths.mjs';
|
|
31
31
|
import { readHookPublicBase } from '../../runtime/channels/lib/webhook/relay-tunnel.mjs';
|
|
32
32
|
import { WEBHOOK_TEST_FIELD, WEBHOOK_TEST_HEADER } from '../../runtime/channels/lib/webhook/request-handler.mjs';
|
|
33
|
+
import { MIXY_AGENT_ID, agentHomeSessionId } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
33
34
|
|
|
34
35
|
const NAME_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
35
36
|
|
|
@@ -187,7 +188,7 @@ function parseAtDatetime(at) {
|
|
|
187
188
|
// Map the store's def shape onto the flat display shape every schedule reader
|
|
188
189
|
// (channelSetup, renderChannelStatus, TUI pickers) consumes: `.time` renders
|
|
189
190
|
// the cron or the one-shot datetime, `.route` the channel/session target.
|
|
190
|
-
function scheduleToDisplay(s) {
|
|
191
|
+
function scheduleToDisplay(s, ownerProblem = '') {
|
|
191
192
|
return {
|
|
192
193
|
name: s.name,
|
|
193
194
|
description: s.description || '',
|
|
@@ -195,26 +196,85 @@ function scheduleToDisplay(s) {
|
|
|
195
196
|
whenAt: s.whenAt || undefined,
|
|
196
197
|
whenCron: s.whenCron || undefined,
|
|
197
198
|
timezone: s.timezone || undefined,
|
|
198
|
-
// Shown (and re-saved by the editor) on the catalog successor of a superseded model.
|
|
199
|
-
model: s.model ? migrateCodexModelRef(s.model) : undefined,
|
|
200
199
|
cwd: s.cwd || undefined,
|
|
201
|
-
workflow: s.workflow || undefined,
|
|
202
200
|
attachments: s.attachments || undefined,
|
|
203
201
|
enabled: s.enabled !== false,
|
|
204
202
|
instructions: s.prompt,
|
|
205
203
|
route: 'session',
|
|
204
|
+
// The bot it belongs to: each run is a turn in that bot's chat.
|
|
205
|
+
owner: s.ownerAgentId || MIXY_AGENT_ID,
|
|
206
|
+
// Why it is paused for its owner (routine-owner.mjs); absent when it runs.
|
|
207
|
+
...(ownerProblem ? { ownerProblem } : {}),
|
|
208
|
+
nextFireAt: isoOrUndefined(s.nextFireAt),
|
|
209
|
+
lastSuccessAt: isoOrUndefined(s.lastSuccessAt),
|
|
210
|
+
lastFailedAt: isoOrUndefined(s.lastFailedAt),
|
|
211
|
+
lastSkippedAt: isoOrUndefined(s.lastSkippedAt),
|
|
212
|
+
...routineHealth(s),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Failures in a row (the routine pauses itself at the limit) and the results
|
|
217
|
+
// of finished runs still not queued for the owner: `{ count, failed, error }`,
|
|
218
|
+
// `failed` when the queue refused one (the app offers a retry).
|
|
219
|
+
function routineHealth(row) {
|
|
220
|
+
const entries = Object.values(row.resultDelivery || {}).filter(Boolean);
|
|
221
|
+
const refused = entries.filter((entry) => entry.state === 'failed').at(-1);
|
|
222
|
+
return {
|
|
223
|
+
consecutiveFailures: Number(row.consecutiveFailures) || 0,
|
|
224
|
+
...(entries.length
|
|
225
|
+
? {
|
|
226
|
+
undelivered: {
|
|
227
|
+
count: entries.length,
|
|
228
|
+
failed: Boolean(refused),
|
|
229
|
+
...(refused?.error ? { error: String(refused.error) } : {}),
|
|
230
|
+
},
|
|
231
|
+
}
|
|
232
|
+
: {}),
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function isoOrUndefined(value) {
|
|
237
|
+
if (!value) return undefined;
|
|
238
|
+
const at = new Date(value);
|
|
239
|
+
return Number.isNaN(at.getTime()) ? undefined : at.toISOString();
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// A schedule's or webhook's owner: an explicit agent id, else the saved owner
|
|
243
|
+
// on an overwrite, else Mixy.
|
|
244
|
+
function scheduleOwner(owner, existing) {
|
|
245
|
+
const value = String(owner ?? '').trim();
|
|
246
|
+
if (value) {
|
|
247
|
+
if (!agentHomeSessionId(value)) throw new Error(`schedule owner "${value}" is not a valid agent id`);
|
|
248
|
+
return value;
|
|
249
|
+
}
|
|
250
|
+
return existing?.ownerAgentId || MIXY_AGENT_ID;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/** Each owner's problem (routine-owner.mjs), probed once per owner. */
|
|
254
|
+
function ownerProblems() {
|
|
255
|
+
const seen = new Map();
|
|
256
|
+
return (ownerAgentId) => {
|
|
257
|
+
const owner = ownerAgentId || MIXY_AGENT_ID;
|
|
258
|
+
if (!seen.has(owner))
|
|
259
|
+
seen.set(
|
|
260
|
+
owner,
|
|
261
|
+
routineOwnerProblem(owner).catch(() => '')
|
|
262
|
+
);
|
|
263
|
+
return seen.get(owner);
|
|
206
264
|
};
|
|
207
265
|
}
|
|
208
266
|
|
|
209
267
|
export async function listSchedules() {
|
|
210
268
|
const rows = await dbListSchedules();
|
|
211
|
-
|
|
269
|
+
const problemOf = ownerProblems();
|
|
270
|
+
return Promise.all(rows.map(async (row) => scheduleToDisplay(row, await problemOf(row.ownerAgentId))));
|
|
212
271
|
}
|
|
213
272
|
|
|
214
273
|
// Register or update a schedule in the PG store. Recurring input maps `time`
|
|
215
274
|
// (+ optional `days`) to a cron; one-shot input maps an `at` datetime; the two
|
|
216
275
|
// are mutually exclusive (also enforced by the store's when_at/when_cron XOR).
|
|
217
|
-
// Every schedule runs as a
|
|
276
|
+
// Every schedule runs as a turn in its owner bot's chat; a bot that does not
|
|
277
|
+
// exist (no representative bot yet, an archived bot) cannot own one.
|
|
218
278
|
export async function saveSchedule({
|
|
219
279
|
name,
|
|
220
280
|
description = '',
|
|
@@ -222,26 +282,26 @@ export async function saveSchedule({
|
|
|
222
282
|
at,
|
|
223
283
|
timezone,
|
|
224
284
|
days,
|
|
225
|
-
model,
|
|
226
285
|
cwd,
|
|
227
|
-
workflow,
|
|
228
286
|
attachments,
|
|
229
287
|
enabled,
|
|
230
288
|
instructions,
|
|
289
|
+
owner,
|
|
231
290
|
overwrite = false,
|
|
232
291
|
} = {}) {
|
|
233
292
|
const id = assertScheduleName(name);
|
|
234
293
|
const body = String(instructions || '').trim();
|
|
235
294
|
if (!body) throw new Error('schedule instructions are required');
|
|
236
|
-
const scheduleModel = String(model || '').trim();
|
|
237
|
-
if (!scheduleModel) throw new Error('schedule model is required — choose a model before saving');
|
|
238
295
|
const hasTime = time != null && String(time).trim() !== '';
|
|
239
296
|
const hasAt = at != null && String(at).trim() !== '';
|
|
240
297
|
if (hasTime && hasAt) throw new Error('provide either `time` (recurring) or `at` (one-shot), not both');
|
|
241
298
|
if (!hasTime && !hasAt) throw new Error('either `time` (recurring cron) or `at` (one-shot datetime) is required');
|
|
242
|
-
|
|
299
|
+
const existing = await dbGetSchedule(id);
|
|
300
|
+
if (overwrite !== true && existing) {
|
|
243
301
|
throw new Error(`schedule "${id}" already exists`);
|
|
244
302
|
}
|
|
303
|
+
const ownerAgentId = scheduleOwner(owner, existing);
|
|
304
|
+
await assertRoutineOwner(ownerAgentId);
|
|
245
305
|
const whenCron = hasTime ? validateScheduleCron(foldDaysIntoCron(normalizeCron(time), days)) : null;
|
|
246
306
|
const whenAt = hasAt ? parseAtDatetime(at) : null;
|
|
247
307
|
const scheduleTimezone = hasTime ? resolveScheduleTimezone(timezone) : null;
|
|
@@ -253,14 +313,13 @@ export async function saveSchedule({
|
|
|
253
313
|
timezone: scheduleTimezone,
|
|
254
314
|
target: 'session',
|
|
255
315
|
channelId: null,
|
|
256
|
-
model: scheduleModel,
|
|
257
316
|
cwd: cwd ? String(cwd).trim() : null,
|
|
258
|
-
workflow: workflow ? String(workflow).trim() : null,
|
|
259
317
|
attachments: normalizeAutomationAttachments(attachments),
|
|
260
318
|
delivery: 'app',
|
|
261
319
|
prompt: body,
|
|
262
320
|
enabled: enabled !== false,
|
|
263
321
|
nextFireAt: whenAt,
|
|
322
|
+
ownerAgentId,
|
|
264
323
|
});
|
|
265
324
|
automationProbe.invalidate();
|
|
266
325
|
return scheduleToDisplay(saved);
|
|
@@ -287,13 +346,13 @@ export async function setScheduleEnabled(name, enabled) {
|
|
|
287
346
|
// store's migration hook.
|
|
288
347
|
async function listWebhooks() {
|
|
289
348
|
const endpoints = await dbListEndpoints();
|
|
290
|
-
|
|
349
|
+
const problemOf = ownerProblems();
|
|
350
|
+
const problems = await Promise.all(endpoints.map((ep) => problemOf(ep.ownerAgentId)));
|
|
351
|
+
return endpoints.map((ep, index) => ({
|
|
291
352
|
name: ep.name,
|
|
292
353
|
description: ep.description || '',
|
|
293
354
|
parser: ep.parser || 'github',
|
|
294
|
-
...(ep.model ? { model: migrateCodexModelRef(ep.model) } : {}),
|
|
295
355
|
...(ep.cwd ? { cwd: ep.cwd } : {}),
|
|
296
|
-
...(ep.workflow ? { workflow: ep.workflow } : {}),
|
|
297
356
|
...(ep.attachments ? { attachments: ep.attachments } : {}),
|
|
298
357
|
enabled: ep.enabled,
|
|
299
358
|
// The store never projects the plaintext secret through list paths; it
|
|
@@ -302,6 +361,16 @@ async function listWebhooks() {
|
|
|
302
361
|
secret: undefined,
|
|
303
362
|
instructions: ep.instructions,
|
|
304
363
|
route: 'session',
|
|
364
|
+
// The bot it belongs to: each run is a turn in that bot's chat.
|
|
365
|
+
owner: ep.ownerAgentId || MIXY_AGENT_ID,
|
|
366
|
+
...(problems[index] ? { ownerProblem: problems[index] } : {}),
|
|
367
|
+
lastEventAt: isoOrUndefined(ep.lastEventAt),
|
|
368
|
+
lastSuccessAt: isoOrUndefined(ep.lastSuccessAt),
|
|
369
|
+
lastFailedAt: isoOrUndefined(ep.lastFailedAt),
|
|
370
|
+
lastSkippedAt: isoOrUndefined(ep.lastSkippedAt),
|
|
371
|
+
// Whether "Run now" has a received payload to re-run (never the payload).
|
|
372
|
+
hasLastPayload: ep.hasLastPayload === true,
|
|
373
|
+
...routineHealth(ep),
|
|
305
374
|
}));
|
|
306
375
|
}
|
|
307
376
|
|
|
@@ -310,12 +379,11 @@ export async function saveWebhook({
|
|
|
310
379
|
description = '',
|
|
311
380
|
parser = 'github',
|
|
312
381
|
secret,
|
|
313
|
-
model,
|
|
314
382
|
cwd,
|
|
315
|
-
workflow,
|
|
316
383
|
attachments,
|
|
317
384
|
enabled,
|
|
318
385
|
instructions,
|
|
386
|
+
owner,
|
|
319
387
|
overwrite = false,
|
|
320
388
|
} = {}) {
|
|
321
389
|
const id = assertName(name, 'webhook name');
|
|
@@ -327,9 +395,12 @@ export async function saveWebhook({
|
|
|
327
395
|
}
|
|
328
396
|
const body = String(instructions || '').trim();
|
|
329
397
|
if (!body) throw new Error('webhook instructions are required');
|
|
330
|
-
|
|
398
|
+
const existing = await dbLoadEndpoint(id);
|
|
399
|
+
if (overwrite !== true && existing) {
|
|
331
400
|
throw new Error(`webhook "${id}" already exists`);
|
|
332
401
|
}
|
|
402
|
+
const ownerAgentId = scheduleOwner(owner, existing);
|
|
403
|
+
await assertRoutineOwner(ownerAgentId);
|
|
333
404
|
// Secret semantics: an explicit value always wins; an EMPTY value on an
|
|
334
405
|
// overwrite PRESERVES the stored secret (editing instructions must not
|
|
335
406
|
// silently rotate the key the external service was configured with); only
|
|
@@ -343,23 +414,21 @@ export async function saveWebhook({
|
|
|
343
414
|
description: String(description || '').trim(),
|
|
344
415
|
parser: nextParser,
|
|
345
416
|
channelId: null,
|
|
346
|
-
model: model ? String(model).trim() : null,
|
|
347
417
|
cwd: cwd ? String(cwd).trim() : null,
|
|
348
|
-
workflow: workflow ? String(workflow).trim() : null,
|
|
349
418
|
attachments: normalizeAutomationAttachments(attachments),
|
|
350
419
|
delivery: 'app',
|
|
351
420
|
secret: secretValue,
|
|
352
421
|
instructions: body,
|
|
353
422
|
enabled: enabled !== false,
|
|
423
|
+
ownerAgentId,
|
|
354
424
|
});
|
|
355
425
|
automationProbe.invalidate();
|
|
356
426
|
return {
|
|
357
427
|
name: id,
|
|
428
|
+
owner: saved.ownerAgentId || ownerAgentId,
|
|
358
429
|
description: saved.description,
|
|
359
430
|
parser: saved.parser,
|
|
360
|
-
...(saved.model ? { model: saved.model } : {}),
|
|
361
431
|
...(saved.cwd ? { cwd: saved.cwd } : {}),
|
|
362
|
-
...(saved.workflow ? { workflow: saved.workflow } : {}),
|
|
363
432
|
...(saved.attachments ? { attachments: saved.attachments } : {}),
|
|
364
433
|
...(enabled === false ? { enabled: false } : {}),
|
|
365
434
|
secret: secretValue,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Whose memory a session reads and writes (runtime/memory/lib/
|
|
2
|
+
// core-memory-access.mjs enforces it). Mixy is the Lead configuration, so the
|
|
3
|
+
// user's own sessions (an ordinary Lead session, Mixy's home) act as Mixy; an
|
|
4
|
+
// agent's home thread and its room member sessions act as that agent; a
|
|
5
|
+
// schedule or webhook run acts for its owning agent (`ownerAgentId`, stamped
|
|
6
|
+
// at creation); a delegated agent as its own agent id.
|
|
7
|
+
import { MIXY_AGENT_ID, agentHomeSessionId } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
8
|
+
import { resolveSessionMode } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
|
|
9
|
+
import { isAgentOwner } from '../../runtime/agent/orchestrator/agent-owner.mjs';
|
|
10
|
+
import { scheduleCallerScope } from './schedule-access.mjs';
|
|
11
|
+
|
|
12
|
+
const validAgentId = (value) => {
|
|
13
|
+
const id = typeof value === 'string' ? value.trim() : '';
|
|
14
|
+
return id && agentHomeSessionId(id) ? id : '';
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** The `memory_caller` `{ kind, agentId }` of a calling session record:
|
|
18
|
+
* 'human' and 'agent' are conversations with the user, 'room-member' and
|
|
19
|
+
* 'headless' unattended runs. */
|
|
20
|
+
export function memoryCallerScope(session) {
|
|
21
|
+
const scope = scheduleCallerScope(session);
|
|
22
|
+
if (scope.kind === 'human') return { kind: 'human', agentId: MIXY_AGENT_ID };
|
|
23
|
+
if (scope.kind !== 'headless') return scope;
|
|
24
|
+
const delegated = isAgentOwner(session) || Boolean(session?.parentSessionId);
|
|
25
|
+
return {
|
|
26
|
+
kind: 'headless',
|
|
27
|
+
agentId: validAgentId(session?.ownerAgentId) || (delegated ? validAgentId(session?.agent) : ''),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** The agent whose own memory a session's prompt carries: its home thread's,
|
|
32
|
+
* room member's or run owner's agent, Mixy for the user's Lead sessions, and
|
|
33
|
+
* none for a delegated agent. `session` is the live record when there is
|
|
34
|
+
* one, else the reserved id and creation profile. */
|
|
35
|
+
export function injectedMemoryAgentId({ session = null, sessionId = '', profile = null } = {}) {
|
|
36
|
+
return resolveSessionMode({ session, sessionId, profile }).agentId;
|
|
37
|
+
}
|