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
|
@@ -292,20 +292,27 @@ function mergeLegacyDays(db, { days, hourly, hourlyDay, fromDay, toDay }) {
|
|
|
292
292
|
* Compaction requests run under their own provider session id but are
|
|
293
293
|
* recorded under the source session, so this is the whole conversation
|
|
294
294
|
* across compactions. The same route choice as a rollup applies: a gateway
|
|
295
|
-
* summary never doubles a detail record.
|
|
295
|
+
* summary never doubles a detail record. `ownerIds` adds every session
|
|
296
|
+
* recorded as run for one of them (a Lead's agents, theirs in turn).
|
|
296
297
|
*/
|
|
297
|
-
export function readSessionUsage(db, sessionIds) {
|
|
298
|
+
export function readSessionUsage(db, sessionIds, ownerIds = []) {
|
|
298
299
|
const total = empty();
|
|
299
300
|
const rows = db
|
|
300
301
|
.prepare(`
|
|
301
|
-
WITH
|
|
302
|
+
WITH RECURSIVE owned(id) AS (
|
|
303
|
+
SELECT o.session FROM usage_session_owners o JOIN usage_sessions s ON s.id=o.owner
|
|
304
|
+
WHERE s.value IN (SELECT value FROM json_each(?))
|
|
305
|
+
UNION
|
|
306
|
+
SELECT o.session FROM usage_session_owners o JOIN owned ON o.owner=owned.id
|
|
307
|
+
), mine AS (
|
|
302
308
|
SELECT day,route,COUNT(*) AS turns,SUM(input) AS input,SUM(output) AS output,
|
|
303
309
|
SUM(cache_read) AS cache_read,SUM(cache_write) AS cache_write,
|
|
304
310
|
SUM(cost_usd) AS cost_usd,SUM(duration_ms) AS duration_ms,
|
|
305
311
|
SUM(CASE WHEN duration_ms>0 AND output>0 THEN output ELSE 0 END) AS speed_output,
|
|
306
312
|
SUM(CASE WHEN duration_ms>0 AND output>0 THEN duration_ms ELSE 0 END) AS speed_ms
|
|
307
313
|
FROM usage_events WHERE session IN (
|
|
308
|
-
SELECT id FROM usage_sessions WHERE value IN (SELECT value FROM json_each(?))
|
|
314
|
+
SELECT id FROM usage_sessions WHERE value IN (SELECT value FROM json_each(?))
|
|
315
|
+
UNION SELECT id FROM owned)
|
|
309
316
|
GROUP BY day,route
|
|
310
317
|
), attributed AS (
|
|
311
318
|
SELECT printf('%04d-%02d-%02d',m.day/10000,(m.day/100)%100,m.day%100) AS day,
|
|
@@ -320,7 +327,7 @@ export function readSessionUsage(db, sessionIds) {
|
|
|
320
327
|
)
|
|
321
328
|
SELECT a.* FROM attributed a JOIN (${best}) b USING(day,provider,model,rank)
|
|
322
329
|
`)
|
|
323
|
-
.all(JSON.stringify(sessionIds), '0000-01-01', '9999-12-31');
|
|
330
|
+
.all(JSON.stringify(ownerIds), JSON.stringify(sessionIds), '0000-01-01', '9999-12-31');
|
|
324
331
|
let speedOutput = 0;
|
|
325
332
|
let speedMs = 0;
|
|
326
333
|
for (const row of rows) {
|
|
@@ -60,7 +60,7 @@ function recordBatch(ledger, rows) {
|
|
|
60
60
|
const operations = {
|
|
61
61
|
rollup: ({ path, options }) => read(path, (db) => rollupUsage(db, options)),
|
|
62
62
|
rollupDelta: ({ path, options, known, now }) => read(path, (db) => rollupDelta(db, options, known, now)),
|
|
63
|
-
sessionUsage: ({ path, sessionIds }) => read(path, (db) => readSessionUsage(db, sessionIds)),
|
|
63
|
+
sessionUsage: ({ path, sessionIds, ownerIds }) => read(path, (db) => readSessionUsage(db, sessionIds, ownerIds)),
|
|
64
64
|
record: ({ path, rows }) => write(path, (ledger) => recordBatch(ledger, rows)),
|
|
65
65
|
recordQuota: ({ path, samples }) => write(path, (ledger) => ledger.recordQuota(samples)),
|
|
66
66
|
quotaHistory: ({ path, options }) => read(path, (db) => readQuotaHistory(db, options)),
|
|
@@ -78,6 +78,13 @@ const COMPACT_SCHEMA = `
|
|
|
78
78
|
-- One session's lifetime totals (the /context footer) read that session's
|
|
79
79
|
-- records only instead of scanning every record ever written.
|
|
80
80
|
CREATE INDEX IF NOT EXISTS usage_events_session ON usage_events(session);
|
|
81
|
+
-- The session each session ran for (an agent's Lead), so a Lead's agents
|
|
82
|
+
-- stay countable after their own session records are gone.
|
|
83
|
+
CREATE TABLE IF NOT EXISTS usage_session_owners (
|
|
84
|
+
session INTEGER PRIMARY KEY REFERENCES usage_sessions(id),
|
|
85
|
+
owner INTEGER NOT NULL REFERENCES usage_sessions(id)
|
|
86
|
+
);
|
|
87
|
+
CREATE INDEX IF NOT EXISTS usage_session_owners_owner ON usage_session_owners(owner);
|
|
81
88
|
`;
|
|
82
89
|
|
|
83
90
|
// Preserve the old read surface. Only storage changes: every field, including
|
|
@@ -109,6 +116,7 @@ function compactEventWriter(db) {
|
|
|
109
116
|
const insertSession = db.prepare('INSERT OR IGNORE INTO usage_sessions(value) VALUES (?)');
|
|
110
117
|
const findSession = db.prepare('SELECT id FROM usage_sessions WHERE value=?');
|
|
111
118
|
const insert = db.prepare('INSERT INTO usage_events VALUES (?,?,?,?,?,?,?,?,?,?,?)');
|
|
119
|
+
const insertOwner = db.prepare('INSERT OR IGNORE INTO usage_session_owners VALUES (?,?)');
|
|
112
120
|
return (row) => {
|
|
113
121
|
for (const key of ['id', 'provider', 'model', 'kind', 'source_type', 'cost_source', 'origin', 'session_id']) {
|
|
114
122
|
if (row[key] == null) throw new Error(`Usage requires ${key}`);
|
|
@@ -133,6 +141,11 @@ function compactEventWriter(db) {
|
|
|
133
141
|
const route = findRoute.get(signature).id;
|
|
134
142
|
insertSession.run(String(row.session_id));
|
|
135
143
|
const session = findSession.get(String(row.session_id)).id;
|
|
144
|
+
const owner = row.owner_session_id ? String(row.owner_session_id) : '';
|
|
145
|
+
if (owner && owner !== String(row.session_id)) {
|
|
146
|
+
insertSession.run(owner);
|
|
147
|
+
insertOwner.run(session, findSession.get(owner).id);
|
|
148
|
+
}
|
|
136
149
|
insert.run(
|
|
137
150
|
id,
|
|
138
151
|
row.ts,
|
|
@@ -201,7 +214,6 @@ function migrateUsageLedger(db, path) {
|
|
|
201
214
|
|
|
202
215
|
export function usageRouteKind(provider) {
|
|
203
216
|
if (provider === 'mixdog-local') return 'local';
|
|
204
|
-
if (provider === 'opencode-go') return 'quota-api';
|
|
205
217
|
return provider.endsWith('-oauth') ? 'oauth' : 'api';
|
|
206
218
|
}
|
|
207
219
|
|
|
@@ -273,6 +285,7 @@ export function makeUsageRecord(args) {
|
|
|
273
285
|
model,
|
|
274
286
|
kind,
|
|
275
287
|
sessionId: ['no-session', '(none)'].includes(args.sessionId) ? '' : text(args.sessionId),
|
|
288
|
+
...(args.ownerSessionId ? { ownerSessionId: text(args.ownerSessionId) } : {}),
|
|
276
289
|
sourceType: text(args.sourceType),
|
|
277
290
|
input: priced.input,
|
|
278
291
|
output: num(args.outputTokens),
|
|
@@ -453,6 +466,7 @@ export class UsageLedger {
|
|
|
453
466
|
!this.insert({
|
|
454
467
|
...row,
|
|
455
468
|
session_id: row.sessionId,
|
|
469
|
+
owner_session_id: row.ownerSessionId,
|
|
456
470
|
source_type: row.sourceType,
|
|
457
471
|
cache_read: row.cacheRead,
|
|
458
472
|
cache_write: row.cacheWrite,
|
|
@@ -558,10 +572,11 @@ export class UsageLedger {
|
|
|
558
572
|
return this.workerRequest('quotaWindows', { options });
|
|
559
573
|
}
|
|
560
574
|
|
|
561
|
-
/** Every request one session made under any of its ids, compactions included, read on the ledger worker.
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
575
|
+
/** Every request one session made under any of its ids, compactions included, read on the ledger worker.
|
|
576
|
+
* `ownerIds` adds every session recorded as run for them, transitively. */
|
|
577
|
+
sessionUsageAsync(sessionIds, ownerIds = []) {
|
|
578
|
+
if (this.path === ':memory:') return Promise.resolve().then(() => readSessionUsage(this.db, sessionIds, ownerIds));
|
|
579
|
+
return this.workerRequest('sessionUsage', { sessionIds, ownerIds });
|
|
565
580
|
}
|
|
566
581
|
|
|
567
582
|
preserveLegacyDays(days) {
|
|
@@ -22,8 +22,12 @@ const PERIODIC_ATTRIBUTION_FREE_BYTES = 2 * 1024 * 1024 * 1024;
|
|
|
22
22
|
let periodicTimer = null;
|
|
23
23
|
let lastPressureSnapshotAt = 0;
|
|
24
24
|
|
|
25
|
+
// Opt-in diagnostics (MIXDOG_MEMORY_SNAPSHOT=1): every sample starts a
|
|
26
|
+
// PowerShell process on Windows (two for a full snapshot, requested exactly
|
|
27
|
+
// when the host is under memory pressure), from every process that loads
|
|
28
|
+
// this module. A normal install never pays for that.
|
|
25
29
|
function enabled() {
|
|
26
|
-
return process.env.MIXDOG_MEMORY_SNAPSHOT
|
|
30
|
+
return process.env.MIXDOG_MEMORY_SNAPSHOT === '1';
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
function snapshotPaths() {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Opt-in (MIXDOG_NOTIFY_TRACE=1) completion-notification trace: off by
|
|
2
|
+
// default, so a normal install writes no line per delivery decision (it kept
|
|
3
|
+
// a multi-MB log growing in every data dir). The display path for
|
|
2
4
|
// background completions is event-time only and has repeatedly failed silently
|
|
3
5
|
// in the field (2026-08-17: bench shell output never rendered while the model
|
|
4
6
|
// queue twin worked every time). One append-only line per decision point keeps
|
|
@@ -36,7 +38,12 @@ function tracePath() {
|
|
|
36
38
|
return join(traceDir, 'notify-trace.log');
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
function notifyTraceEnabled() {
|
|
42
|
+
return process.env.MIXDOG_NOTIFY_TRACE === '1';
|
|
43
|
+
}
|
|
44
|
+
|
|
39
45
|
export function notifyTrace(stage, fields = {}) {
|
|
46
|
+
if (!notifyTraceEnabled()) return;
|
|
40
47
|
try {
|
|
41
48
|
const parts = [`[${new Date().toISOString()}]`, `pid=${process.pid}`, stage];
|
|
42
49
|
for (const [key, value] of Object.entries(fields)) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function plainPreviewText(text: unknown): string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// A messenger preview line reads as plain text, as KakaoTalk shows it: the
|
|
2
|
+
// markdown a reply was written in (bold, headings, list markers, quotes,
|
|
3
|
+
// code fences and spans, links, images) is dropped, its words kept.
|
|
4
|
+
|
|
5
|
+
/** `text` without markdown syntax, whitespace folded to single spaces. */
|
|
6
|
+
export function plainPreviewText(text) {
|
|
7
|
+
// HTML comments never show in markdown (a greeting's suggestions ride one).
|
|
8
|
+
return String(text ?? '')
|
|
9
|
+
.replace(/<!--[\s\S]*?(?:-->|$)/g, ' ')
|
|
10
|
+
.replace(/^[ \t]*(`{3,}|~{3,})[^\n]*$/gm, ' ')
|
|
11
|
+
.replace(/!\[([^\]]*)\]\([^)]*\)/g, '$1')
|
|
12
|
+
.replace(/\[([^\]]+)\]\([^)]*\)/g, '$1')
|
|
13
|
+
.replace(/^[ \t]{0,3}#{1,6}[ \t]+/gm, '')
|
|
14
|
+
.replace(/^[ \t]*>[ \t]?/gm, '')
|
|
15
|
+
.replace(/^[ \t]*(?:[-*+]|\d+[.)])[ \t]+(?:\[[ xX]\][ \t]+)?/gm, '')
|
|
16
|
+
.replace(/^[ \t]*(?:[-*_][ \t]*){3,}$/gm, ' ')
|
|
17
|
+
.replace(/(\*\*|__)(?=\S)([\s\S]*?\S)\1/g, '$2')
|
|
18
|
+
.replace(/(^|[^\w*])\*(?=\S)([^*\n]*?\S)\*(?!\w)/g, '$1$2')
|
|
19
|
+
.replace(/(^|[^\w_])_(?=\S)([^_\n]*?\S)_(?!\w)/g, '$1$2')
|
|
20
|
+
.replace(/~~(?=\S)([\s\S]*?\S)~~/g, '$1')
|
|
21
|
+
.replace(/`+([^`\n]*)`+/g, '$1')
|
|
22
|
+
.replace(/\s+/g, ' ')
|
|
23
|
+
.trim()
|
|
24
|
+
.slice(0, PREVIEW_CAP);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** A safety cap only: the row clamps the shown text to two lines. */
|
|
28
|
+
const PREVIEW_CAP = 200;
|
|
@@ -88,6 +88,11 @@
|
|
|
88
88
|
"credentialFile": "antigravity-oauth.json",
|
|
89
89
|
"credentialPathEnv": "ANTIGRAVITY_OAUTH_CREDENTIALS_PATH",
|
|
90
90
|
"modelCatalogFile": "antigravity-oauth-models.json"
|
|
91
|
+
},
|
|
92
|
+
"opencode-go-oauth": {
|
|
93
|
+
"credentialFile": "opencode-go-oauth.json",
|
|
94
|
+
"credentialPathEnv": "OPENCODE_GO_OAUTH_CREDENTIALS_PATH",
|
|
95
|
+
"modelCatalogFile": "opencode-go-oauth-models.json"
|
|
91
96
|
}
|
|
92
97
|
},
|
|
93
98
|
"apiKeyProviders": {
|
|
@@ -96,7 +101,6 @@
|
|
|
96
101
|
"gemini": "GEMINI_API_KEY",
|
|
97
102
|
"deepseek": "DEEPSEEK_API_KEY",
|
|
98
103
|
"xai": "XAI_API_KEY",
|
|
99
|
-
"opencode-go": "OPENCODE_API_KEY",
|
|
100
104
|
"openrouter": "OPENROUTER_API_KEY"
|
|
101
105
|
},
|
|
102
106
|
"personalStateCounters": [
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
// Worker-thread body for process-runner.mjs: helper children (process-table
|
|
2
|
+
// enumeration, tree kills) are spawned on this thread, never on the host
|
|
3
|
+
// event loop (run-child.mjs).
|
|
4
|
+
import { runChild } from './run-child.mjs';
|
|
5
|
+
import { serveWorkerRequests } from './worker-requests.mjs';
|
|
6
|
+
|
|
7
|
+
serveWorkerRequests(runChild);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Run short helper processes from one shared worker thread, so their
|
|
2
|
+
// synchronous native process creation never stalls the host event loop. A
|
|
3
|
+
// daemon profile under heavy agent load measured single PowerShell spawns
|
|
4
|
+
// blocking the daemon's loop for up to 7 s each. Separate from the git
|
|
5
|
+
// runner's worker: a slow helper start never queues a git child behind it.
|
|
6
|
+
import { SHARE_ENV } from 'node:worker_threads';
|
|
7
|
+
import { runChild } from './run-child.mjs';
|
|
8
|
+
import { createWorkerRequestClient } from './worker-requests.mjs';
|
|
9
|
+
|
|
10
|
+
// Created on first use. A bundled copy of this module (the desktop service's
|
|
11
|
+
// CommonJS bundle) has no module URL and no worker file beside it: there the
|
|
12
|
+
// child is started on the calling thread, exactly as before.
|
|
13
|
+
let requestProcess = null;
|
|
14
|
+
function processClient() {
|
|
15
|
+
if (requestProcess !== null) return requestProcess;
|
|
16
|
+
try {
|
|
17
|
+
// SHARE_ENV: children inherit the live process environment, exactly as a
|
|
18
|
+
// spawn from this thread would.
|
|
19
|
+
requestProcess = createWorkerRequestClient(new URL('./process-runner-worker.mjs', import.meta.url), {
|
|
20
|
+
env: SHARE_ENV,
|
|
21
|
+
});
|
|
22
|
+
} catch {
|
|
23
|
+
requestProcess = false;
|
|
24
|
+
}
|
|
25
|
+
return requestProcess;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Resolves to { code, stdout, stderr } (a non-zero exit is the caller's to
|
|
30
|
+
* judge). Rejects with code ETIMEDOUT after timeoutMs (the child is killed;
|
|
31
|
+
* 0 sets no deadline),
|
|
32
|
+
* EMAXBUFFER once stdout+stderr exceed maxBytes, or the spawn error itself.
|
|
33
|
+
*/
|
|
34
|
+
export function runProcessOffThread(command, args, { cwd, input = '', env = null, timeoutMs, maxBytes }) {
|
|
35
|
+
const request = processClient();
|
|
36
|
+
const payload = { command, args, cwd, input, env, timeoutMs, maxBytes };
|
|
37
|
+
return request ? request(payload) : runChild(payload);
|
|
38
|
+
}
|
|
@@ -13,6 +13,7 @@ export const ACCOUNT_PROVIDERS = Object.freeze([
|
|
|
13
13
|
'mimo-oauth',
|
|
14
14
|
'cursor-oauth',
|
|
15
15
|
'antigravity-oauth',
|
|
16
|
+
'opencode-go-oauth',
|
|
16
17
|
]);
|
|
17
18
|
const MAX_ACCOUNTS = 20;
|
|
18
19
|
// `dataDir` defaults to this process's data dir; an isolated runtime passes
|
|
@@ -79,7 +80,7 @@ function normalizeLabels(pool) {
|
|
|
79
80
|
// only; `limit` keeps the selected account until it reaches a limit and then
|
|
80
81
|
// moves to the account with the most headroom; `headroom` starts every new
|
|
81
82
|
// session on the account with the most headroom and keeps it for that session.
|
|
82
|
-
|
|
83
|
+
const ACCOUNT_POLICIES = Object.freeze(['manual', 'limit', 'headroom']);
|
|
83
84
|
|
|
84
85
|
// `auto` predates `policy` and is still written beside it, so a build that
|
|
85
86
|
// knows only `auto` reads the same switching on/off. Whenever the two
|
|
@@ -88,7 +88,7 @@ export function readSourceWindow(text) {
|
|
|
88
88
|
rows.push({ number, content: row[2] });
|
|
89
89
|
continue;
|
|
90
90
|
}
|
|
91
|
-
const metadata = /^\[lines (\d+)-(\d+) of (\d+)(?:;
|
|
91
|
+
const metadata = /^\[lines (\d+)-(\d+) of (\d+)(?:; offset:\d+ for more)?\]$/.exec(line);
|
|
92
92
|
if (!metadata || footer) return null;
|
|
93
93
|
footer = metadata;
|
|
94
94
|
totalLines = Number(metadata[3]);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { freemem, totalmem } from 'node:os';
|
|
1
|
+
import { availableParallelism, freemem, totalmem } from 'node:os';
|
|
2
2
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
3
3
|
import { requestMemoryPressureSnapshot } from './memory-snapshot.mjs';
|
|
4
4
|
import { nonNegativeInt, positiveInt } from './numbers.mjs';
|
|
@@ -6,12 +6,20 @@ import { nonNegativeInt, positiveInt } from './numbers.mjs';
|
|
|
6
6
|
const MB = 1024 * 1024;
|
|
7
7
|
|
|
8
8
|
// The unified daemon queues bursts instead of starting an unbounded number of
|
|
9
|
-
// agent/provider
|
|
10
|
-
//
|
|
9
|
+
// agent/provider tasks in one process. Shell commands start immediately: their
|
|
10
|
+
// only bound is maxShells (64) live foreground commands, a runaway guard
|
|
11
|
+
// rather than a CPU budget; the OS shares the cores. Environment overrides remain available; memory thresholds
|
|
12
|
+
// are diagnostic only.
|
|
13
|
+
// Agent leases are held only while an agent runs tools (they yield during
|
|
14
|
+
// provider I/O) and their tool work is mostly child-process I/O, so two per
|
|
15
|
+
// core keeps the host busy: 30-agent stress on 20 cores halved wall time at
|
|
16
|
+
// 40 versus 8 with no event-loop or memory cost. 8 is the floor for small
|
|
17
|
+
// hosts. maxHighLoad now bounds agents only and defaults to the same.
|
|
18
|
+
const AGENT_LIMIT = Math.max(8, 2 * availableParallelism());
|
|
11
19
|
const RESOURCE_ADMISSION_DEFAULTS = Object.freeze({
|
|
12
|
-
maxAgents:
|
|
13
|
-
maxShells:
|
|
14
|
-
maxHighLoad:
|
|
20
|
+
maxAgents: AGENT_LIMIT,
|
|
21
|
+
maxShells: 64,
|
|
22
|
+
maxHighLoad: AGENT_LIMIT,
|
|
15
23
|
maxQueue: 1024,
|
|
16
24
|
minFreeMemoryMb: 0,
|
|
17
25
|
maxRssMb: 0,
|
|
@@ -79,12 +87,15 @@ class ResourceAdmissionQueueFullError extends ResourcePressureError {
|
|
|
79
87
|
* shells. Running work is never revoked: pressure only rejects a new request or
|
|
80
88
|
* keeps a concurrency-blocked request in the bounded FIFO queue.
|
|
81
89
|
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
90
|
+
* Shell leases are their own pool of maxShells: they are not part of the
|
|
91
|
+
* maxHighLoad budget, do not suspend the calling agent's lease, and never wait
|
|
92
|
+
* behind queued agent work, so a command starts at once unless maxShells
|
|
93
|
+
* commands are already running. A shell lease covers only the foreground part
|
|
94
|
+
* of a command: promotion to a background job releases it
|
|
95
|
+
* (lib/shell-run-background/promote-job.mjs), so background jobs are not
|
|
96
|
+
* capped at all: they are mostly idle servers/watchers at below-normal OS
|
|
97
|
+
* priority whose memory lives in their own processes. Session/runtime close
|
|
98
|
+
* stops them (shell-jobs shutdownShellJobs).
|
|
88
99
|
*/
|
|
89
100
|
export class ResourceAdmissionController {
|
|
90
101
|
constructor({ limits = {}, metrics = defaultMetrics, now = Date.now, env = process.env } = {}) {
|
|
@@ -98,6 +109,20 @@ export class ResourceAdmissionController {
|
|
|
98
109
|
// Live leases for saturation diagnostics only (labels/ages in snapshot()).
|
|
99
110
|
this.activeLeases = new Set();
|
|
100
111
|
this.context = new AsyncLocalStorage();
|
|
112
|
+
// Admission waits by pool: first acquisition (agent/shell) and the
|
|
113
|
+
// reacquisition after a yielded provider call (restore). Shows whether
|
|
114
|
+
// the agent cap actually delays work.
|
|
115
|
+
this.waitStats = {};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
_recordWait(pool, waitedMs) {
|
|
119
|
+
this.waitStats[pool] ??= { admitted: 0, waited: 0, totalWaitMs: 0, maxWaitMs: 0 };
|
|
120
|
+
const stats = this.waitStats[pool];
|
|
121
|
+
stats.admitted += 1;
|
|
122
|
+
if (waitedMs <= 0) return;
|
|
123
|
+
stats.waited += 1;
|
|
124
|
+
stats.totalWaitMs += waitedMs;
|
|
125
|
+
stats.maxWaitMs = Math.max(stats.maxWaitMs, waitedMs);
|
|
101
126
|
}
|
|
102
127
|
|
|
103
128
|
_recordMemoryPressure(kind) {
|
|
@@ -129,9 +154,14 @@ export class ResourceAdmissionController {
|
|
|
129
154
|
}
|
|
130
155
|
|
|
131
156
|
_canStart(kind) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
157
|
+
if (kind === 'shell') return this.active.shell < this.limits.maxShells;
|
|
158
|
+
return this.active.agent < this.limits.maxHighLoad && this.active.agent < this.limits.maxAgents;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Shell and agent waiters never delay each other's new requests.
|
|
162
|
+
_queuedInPool(lane) {
|
|
163
|
+
const shell = lane === 'shell';
|
|
164
|
+
return this.queue.some((item) => (item.kind === 'shell') === shell);
|
|
135
165
|
}
|
|
136
166
|
|
|
137
167
|
_adjustOwnerCount(kind, ownerKey, delta) {
|
|
@@ -240,6 +270,7 @@ export class ResourceAdmissionController {
|
|
|
240
270
|
},
|
|
241
271
|
};
|
|
242
272
|
this.activeLeases.add(lease);
|
|
273
|
+
this._recordWait(kind, lease.queuedMs);
|
|
243
274
|
return lease;
|
|
244
275
|
}
|
|
245
276
|
|
|
@@ -294,8 +325,9 @@ export class ResourceAdmissionController {
|
|
|
294
325
|
this._recordMemoryPressure(lane);
|
|
295
326
|
const ambientParent = this.context.getStore();
|
|
296
327
|
const detachedDependency = dependency === 'detached' && ambientParent?.controller === this;
|
|
297
|
-
|
|
298
|
-
|
|
328
|
+
// A shell runs beside its agent instead of taking the agent's slot.
|
|
329
|
+
const parent = detachedDependency || lane === 'shell' ? null : this._suspendParent(ambientParent);
|
|
330
|
+
if (detachedDependency && (!this._canStart(lane) || this._queuedInPool(lane))) {
|
|
299
331
|
const error = new ResourcePressureError(
|
|
300
332
|
`detached nested ${lane} work has no admission capacity; retry after running work completes`,
|
|
301
333
|
{ kind: lane }
|
|
@@ -303,7 +335,7 @@ export class ResourceAdmissionController {
|
|
|
303
335
|
error.code = 'ERESOURCEDEPENDENCY';
|
|
304
336
|
return Promise.reject(error);
|
|
305
337
|
}
|
|
306
|
-
if (this._canStart(lane) && this.
|
|
338
|
+
if (this._canStart(lane) && !this._queuedInPool(lane)) {
|
|
307
339
|
const lease = this._lease(lane, null, parent, owner, taskPriority);
|
|
308
340
|
lease.label = label;
|
|
309
341
|
lease.signal = signal;
|
|
@@ -439,6 +471,7 @@ export class ResourceAdmissionController {
|
|
|
439
471
|
if (item.restore) {
|
|
440
472
|
item.parent.restorePending = null;
|
|
441
473
|
item.parent.counted = true;
|
|
474
|
+
this._recordWait(`${item.kind}Restore`, Math.max(0, this.now() - item.queuedAt));
|
|
442
475
|
this.active[item.kind] += 1;
|
|
443
476
|
this._adjustOwnerCount(item.kind, item.ownerKey, 1);
|
|
444
477
|
item.resolve();
|
|
@@ -461,6 +494,15 @@ export class ResourceAdmissionController {
|
|
|
461
494
|
shell: this.activeByOwner.shell.size,
|
|
462
495
|
},
|
|
463
496
|
queued: this.queue.length,
|
|
497
|
+
waitStats: Object.fromEntries(
|
|
498
|
+
Object.entries(this.waitStats).map(([pool, stats]) => [
|
|
499
|
+
pool,
|
|
500
|
+
{
|
|
501
|
+
...stats,
|
|
502
|
+
averageQueuedMs: stats.waited > 0 ? Math.round(stats.totalWaitMs / stats.waited) : 0,
|
|
503
|
+
},
|
|
504
|
+
])
|
|
505
|
+
),
|
|
464
506
|
limits: {
|
|
465
507
|
...this.limits,
|
|
466
508
|
maxAgents: wireLimit(this.limits.maxAgents),
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const ROUTINE_LIMITS: Readonly<{
|
|
2
|
+
backoffBaseMs: number;
|
|
3
|
+
pauseAfterFailures: number;
|
|
4
|
+
homeQueueLimit: number;
|
|
5
|
+
}>;
|
|
6
|
+
|
|
7
|
+
export declare function routineBackoffRemaining(
|
|
8
|
+
state: { consecutiveFailures?: unknown; lastFailedAt?: unknown } | null | undefined,
|
|
9
|
+
now?: number,
|
|
10
|
+
limits?: typeof ROUTINE_LIMITS
|
|
11
|
+
): number;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Safeguards of owned routines (schedules and webhook endpoints, see
|
|
2
|
+
// session-runtime/owned-automation-run.mjs): after a failure the next
|
|
3
|
+
// unattended fire waits `backoffBaseMs * 2^(n-1)` (n consecutive failures)
|
|
4
|
+
// and the routine switches itself off at `pauseAfterFailures`; a home thread
|
|
5
|
+
// holds at most `homeQueueLimit` routine turns waiting (and as many queued
|
|
6
|
+
// rows posted from outside its turns). Runs themselves are
|
|
7
|
+
// unlimited: no concurrency cap and no deadline.
|
|
8
|
+
export const ROUTINE_LIMITS = Object.freeze({
|
|
9
|
+
backoffBaseMs: 60_000,
|
|
10
|
+
pauseAfterFailures: 5,
|
|
11
|
+
homeQueueLimit: 200,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
/** How long (ms) an unattended fire still waits after the routine's
|
|
15
|
+
* `consecutiveFailures`, the latest at `lastFailedAt`; 0 when it may run. */
|
|
16
|
+
export function routineBackoffRemaining(state, now = Date.now(), limits = ROUTINE_LIMITS) {
|
|
17
|
+
const failures = Number(state?.consecutiveFailures) || 0;
|
|
18
|
+
const at = state?.lastFailedAt ? new Date(state.lastFailedAt).getTime() : Number.NaN;
|
|
19
|
+
if (failures < 1 || !Number.isFinite(at)) return 0;
|
|
20
|
+
return Math.max(0, at + limits.backoffBaseMs * 2 ** (failures - 1) - now);
|
|
21
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface RoutineTrigger {
|
|
2
|
+
kind: 'schedule' | 'webhook';
|
|
3
|
+
name: string;
|
|
4
|
+
event?: string;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export declare function routineTriggerHeader(input: { kind: string; name: string; project?: string }): string;
|
|
8
|
+
export declare function stripRoutineTriggerHeader(text: unknown): string;
|
|
9
|
+
export declare function normalizeRoutineTrigger(value: unknown): RoutineTrigger | null;
|
|
10
|
+
export declare function routineTriggerField(value: unknown): { routineTrigger?: RoutineTrigger };
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// A routine fire delivered into its bot's home thread as a turn
|
|
2
|
+
// (session-runtime/routine-home-turn.mjs): the model-visible header line that
|
|
3
|
+
// opens the turn's prompt, and the `routineTrigger` marker its user row
|
|
4
|
+
// carries (live, persisted in meta.transcript, restored) so a chat paints it
|
|
5
|
+
// as a routine marker instead of a user bubble.
|
|
6
|
+
|
|
7
|
+
const HEADER_PREFIX = '[Routine trigger]';
|
|
8
|
+
const KINDS = new Set(['schedule', 'webhook']);
|
|
9
|
+
|
|
10
|
+
/** The first line of a routine turn's prompt: which routine fired and how to
|
|
11
|
+
* treat the turn. Only the turn's content carries it, never the system
|
|
12
|
+
* prompt, so the thread's prompt cache is untouched. */
|
|
13
|
+
export function routineTriggerHeader({ kind, name, project = '' }) {
|
|
14
|
+
const what = kind === 'webhook' ? 'webhook' : 'schedule';
|
|
15
|
+
return [
|
|
16
|
+
`${HEADER_PREFIX} Your ${what} "${String(name)}" fired.`,
|
|
17
|
+
'Carry out its instructions below now, yourself or by delegating; nobody is watching this turn, so approvals wait for the user.',
|
|
18
|
+
'Reply in this chat with the result.',
|
|
19
|
+
...(project ? [`Project folder: ${project}`] : []),
|
|
20
|
+
].join(' ');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** `text` without the header line a routine turn opens with. */
|
|
24
|
+
export function stripRoutineTriggerHeader(text) {
|
|
25
|
+
const value = String(text ?? '');
|
|
26
|
+
if (!value.startsWith(HEADER_PREFIX)) return value;
|
|
27
|
+
const end = value.indexOf('\n');
|
|
28
|
+
return end < 0 ? '' : value.slice(end + 1).replace(/^\n+/, '');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** A well-formed `{ kind, name, event? }` marker, or null. */
|
|
32
|
+
export function normalizeRoutineTrigger(value) {
|
|
33
|
+
if (!value || typeof value !== 'object') return null;
|
|
34
|
+
const name = typeof value.name === 'string' ? value.name.trim().slice(0, 200) : '';
|
|
35
|
+
if (!name || !KINDS.has(value.kind)) return null;
|
|
36
|
+
const event = typeof value.event === 'string' ? value.event.trim().slice(0, 200) : '';
|
|
37
|
+
return { kind: value.kind, name, ...(event ? { event } : {}) };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The `routineTrigger` field of a transcript row (absent when none). */
|
|
41
|
+
export function routineTriggerField(value) {
|
|
42
|
+
const trigger = normalizeRoutineTrigger(value?.routineTrigger);
|
|
43
|
+
return trigger ? { routineTrigger: trigger } : {};
|
|
44
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// One child process run to completion, its output collected — the body of
|
|
2
|
+
// the off-thread runners (git-runner-worker.mjs, process-runner-worker.mjs).
|
|
3
|
+
// Starting a child process is a synchronous native call (CreateProcess on
|
|
4
|
+
// Windows, amplified by on-access scanning and seconds long under load), so
|
|
5
|
+
// those workers spawn here instead of on the host event loop.
|
|
6
|
+
// Resolves to { code, stdout, stderr }; rejects with code ETIMEDOUT after
|
|
7
|
+
// timeoutMs (the child is killed), EMAXBUFFER once stdout+stderr exceed
|
|
8
|
+
// maxBytes, or the spawn error itself.
|
|
9
|
+
import { spawn } from 'node:child_process';
|
|
10
|
+
|
|
11
|
+
export function runChild({ command, args, cwd, input, env, timeoutMs, maxBytes, stdoutEncoding = 'utf8' }) {
|
|
12
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
13
|
+
const hasInput = (typeof input === 'string' || ArrayBuffer.isView(input)) && input.length > 0;
|
|
14
|
+
const child = spawn(command, args, {
|
|
15
|
+
cwd,
|
|
16
|
+
...(env ? { env } : {}),
|
|
17
|
+
windowsHide: true,
|
|
18
|
+
stdio: [hasInput ? 'pipe' : 'ignore', 'pipe', 'pipe'],
|
|
19
|
+
});
|
|
20
|
+
const stdout = [];
|
|
21
|
+
const stderr = [];
|
|
22
|
+
let outputBytes = 0;
|
|
23
|
+
let stdinError = null;
|
|
24
|
+
let settled = false;
|
|
25
|
+
const finish = (error, result) => {
|
|
26
|
+
if (settled) return;
|
|
27
|
+
settled = true;
|
|
28
|
+
clearTimeout(timer);
|
|
29
|
+
if (error) rejectPromise(error);
|
|
30
|
+
else resolvePromise(result);
|
|
31
|
+
};
|
|
32
|
+
// timeoutMs 0: no deadline (the caller's own work bounds the child).
|
|
33
|
+
const timer =
|
|
34
|
+
timeoutMs > 0
|
|
35
|
+
? setTimeout(() => {
|
|
36
|
+
const error = new Error(`${command} ${args.join(' ')} timed out after ${timeoutMs}ms`);
|
|
37
|
+
error.code = 'ETIMEDOUT';
|
|
38
|
+
try {
|
|
39
|
+
child.kill();
|
|
40
|
+
} catch {}
|
|
41
|
+
finish(error);
|
|
42
|
+
}, timeoutMs)
|
|
43
|
+
: null;
|
|
44
|
+
const collect = (chunks, chunk) => {
|
|
45
|
+
const next = Buffer.from(chunk);
|
|
46
|
+
outputBytes += next.length;
|
|
47
|
+
if (outputBytes > maxBytes) {
|
|
48
|
+
const error = new Error(`${command} ${args.join(' ')} exceeded ${maxBytes} output bytes`);
|
|
49
|
+
error.code = 'EMAXBUFFER';
|
|
50
|
+
try {
|
|
51
|
+
child.kill();
|
|
52
|
+
} catch {}
|
|
53
|
+
finish(error);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
chunks.push(next);
|
|
57
|
+
};
|
|
58
|
+
child.stdout.on('data', (chunk) => collect(stdout, chunk));
|
|
59
|
+
child.stderr.on('data', (chunk) => collect(stderr, chunk));
|
|
60
|
+
child.once('error', (error) => finish(error));
|
|
61
|
+
child.once('close', (code) => {
|
|
62
|
+
const result = {
|
|
63
|
+
code: Number(code ?? 1),
|
|
64
|
+
// 'base64' keeps non-UTF-8 bytes (a replayable patch) intact across the thread hop.
|
|
65
|
+
stdout: Buffer.concat(stdout).toString(stdoutEncoding === 'base64' ? 'base64' : 'utf8'),
|
|
66
|
+
stderr: Buffer.concat(stderr).toString('utf8'),
|
|
67
|
+
};
|
|
68
|
+
// A failed stdin write only matters when the child otherwise reported success.
|
|
69
|
+
if (stdinError && result.code === 0) {
|
|
70
|
+
finish(stdinError);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
finish(null, result);
|
|
74
|
+
});
|
|
75
|
+
if (child.stdin) {
|
|
76
|
+
// A short-lived child can close before stdin is flushed. Keep that
|
|
77
|
+
// transport race inside this promise instead of an unhandled EPIPE.
|
|
78
|
+
child.stdin.on('error', (error) => {
|
|
79
|
+
stdinError = error;
|
|
80
|
+
});
|
|
81
|
+
child.stdin.end(input);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// route
|
|
6
|
-
//
|
|
7
|
-
// The optional route fields
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// stored preset can never be mutated through the run.
|
|
1
|
+
// Model route-ref wire format (task sessions, provider model caches): either a
|
|
2
|
+
// config.presets id/name (legacy) or a direct
|
|
3
|
+
// "provider/model[@effort][+fast][+noauto][?parameter=value]" route string
|
|
4
|
+
// (`+noauto`: Auto effort off for the route; absent means on). Slash-form
|
|
5
|
+
// values become direct route objects, which agent-dispatch consumes without a
|
|
6
|
+
// presets lookup.
|
|
7
|
+
// The optional route fields a run carries, from a preset, a maintenance slot
|
|
8
|
+
// or a parsed route ref. modelParameters is copied so a stored preset can
|
|
9
|
+
// never be mutated through the run.
|
|
11
10
|
export function modelRouteFields(slot = {}) {
|
|
12
11
|
return {
|
|
13
12
|
provider: slot.provider,
|