mixdog 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -4
- package/package.json +8 -8
- package/scripts/native-release-status.mjs +238 -0
- package/scripts/verify-runtime-dependency-versions.mjs +158 -0
- package/src/agents/reviewer/AGENT.md +5 -7
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +9 -1
- package/src/defaults/skills/browser-use/SKILL.md +6 -3
- package/src/defaults/skills/local-provider/SKILL.md +33 -6
- package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
- package/src/defaults/skills/setup/SKILL.md +23 -1
- package/src/defaults/skills/setup/references/actions.md +50 -3
- package/src/defaults/skills/setup/references/surfaces.md +23 -3
- package/src/defaults/skills/setup-guide/SKILL.md +7 -3
- package/src/defaults/skills/visualize/SKILL.md +9 -6
- package/src/defaults/skills/visualize/references/craft.md +8 -1
- package/src/help.mjs +1 -1
- package/src/lib/keychain-cjs.cjs +4 -1
- package/src/lib/rules-builder.cjs +14 -7
- package/src/rules/agent-mode/AGENT_MODE.md +8 -5
- package/src/rules/agent-mode/MIXY.md +6 -8
- package/src/rules/lead/LEAD.md +7 -10
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/20-research.md +2 -0
- package/src/rules/shared/45-destructive.md +5 -1
- package/src/rules/shared/60-verification.md +6 -4
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
- package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
- package/src/runtime/agent/orchestrator/config.mjs +11 -0
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -2
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -5
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
- package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +84 -32
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +38 -11
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +15 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +84 -42
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +27 -8
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +14 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
- package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
- package/src/runtime/agent/orchestrator/providers/registry.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +13 -1
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
- package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +5 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +10 -1
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +4 -6
- package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +52 -6
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +35 -13
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +7 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +8 -3
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -2
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +196 -45
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/continuation.mjs +15 -6
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +45 -19
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +44 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +185 -37
- package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
- package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +240 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +102 -35
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +19 -9
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +199 -109
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/continuation.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/empty-nudge.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +62 -13
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +22 -6
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +5 -5
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +33 -8
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/call-prep.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +27 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/manager/agent-listing-notice.mjs +102 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +27 -14
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
- package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +32 -1
- package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +115 -0
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +28 -9
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +4 -9
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +14 -1
- package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +52 -11
- package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +18 -3
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +126 -12
- package/src/runtime/agent/orchestrator/session/runtime-user-context.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +16 -3
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +5 -4
- package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +140 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +15 -5
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +49 -1
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +80 -1
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +33 -1
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.d.mts +5 -0
- package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +37 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +35 -5
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +42 -2
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +47 -14
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +6 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +127 -20
- package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +557 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +10 -12
- package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +42 -23
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
- package/src/runtime/attachments/attachment-reference.mjs +155 -0
- package/src/runtime/attachments/legacy-office.mjs +110 -0
- package/src/runtime/attachments/limits.mjs +5 -1
- package/src/runtime/attachments/office-extract.mjs +3 -6
- package/src/runtime/attachments/pdf-extract.mjs +84 -10
- package/src/runtime/attachments/prompt-restore.mjs +70 -0
- package/src/runtime/attachments/store.mjs +109 -33
- package/src/runtime/browser-bridge/client.mjs +73 -20
- package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +14 -7
- package/src/runtime/channels/lib/state-file.mjs +15 -15
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
- package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
- package/src/runtime/channels/lib/worker-main.mjs +3 -2
- package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
- package/src/runtime/effort-judge/judge-client.mjs +66 -16
- package/src/runtime/effort-judge/model-install.mjs +47 -7
- package/src/runtime/local-provider/asset-installer.mjs +10 -4
- package/src/runtime/local-provider/catalog.mjs +5 -2
- package/src/runtime/local-provider/registered-models.mjs +64 -27
- package/src/runtime/local-provider/server.mjs +2 -3
- package/src/runtime/media/adapters/image-api.mjs +89 -0
- package/src/runtime/media/auth.mjs +64 -1
- package/src/runtime/media/catalog.mjs +66 -4
- package/src/runtime/media/jobs.mjs +4 -0
- package/src/runtime/media/lanes.mjs +46 -5
- package/src/runtime/media/media-usage.mjs +17 -0
- package/src/runtime/media/renditions.mjs +15 -15
- package/src/runtime/media/store.mjs +36 -35
- package/src/runtime/media/tool.mjs +8 -1
- package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
- package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
- package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
- package/src/runtime/memory/lib/memory-chunk-quality.mjs +14 -2
- package/src/runtime/memory/lib/pg/process.mjs +8 -4
- package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
- package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
- package/src/runtime/office/core/journal.mjs +7 -14
- package/src/runtime/office/design/library/design-library-core.mjs +4 -16
- package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
- package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
- package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
- package/src/runtime/office/pdf/pdf-render.mjs +30 -18
- package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +135 -29
- package/src/runtime/shared/agent-avatar-sprites.mjs +23 -8
- package/src/runtime/shared/agent-avatar.mjs +3 -2
- package/src/runtime/shared/agent-kind-migration.mjs +200 -0
- package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
- package/src/runtime/shared/agent-message-envelope.mjs +44 -0
- package/src/runtime/shared/agent-reap-state.d.mts +4 -0
- package/src/runtime/shared/agent-room-host.d.mts +31 -0
- package/src/runtime/shared/agent-room-host.mjs +58 -0
- package/src/runtime/shared/agent-store.mjs +24 -7
- package/src/runtime/shared/agent-task-starts.mjs +27 -0
- package/src/runtime/shared/atomic-file.d.mts +50 -0
- package/src/runtime/shared/atomic-file.mjs +394 -132
- package/src/runtime/shared/background-tasks.mjs +7 -4
- package/src/runtime/shared/bot-hops.mjs +35 -0
- package/src/runtime/shared/bot-split-migration.mjs +1 -1
- package/src/runtime/shared/bounded-download.mjs +4 -2
- package/src/runtime/shared/config.mjs +39 -9
- package/src/runtime/shared/defaults-separation.mjs +6 -2
- package/src/runtime/shared/delegated-approval-host.mjs +74 -0
- package/src/runtime/shared/err-text.mjs +4 -0
- package/src/runtime/shared/error-presentation.mjs +22 -4
- package/src/runtime/shared/file-has-data.mjs +28 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
- package/src/runtime/shared/pending-agent-work.mjs +54 -0
- package/src/runtime/shared/process-lifecycle.mjs +8 -12
- package/src/runtime/shared/projects.mjs +50 -41
- package/src/runtime/shared/provider-accounts.mjs +17 -12
- package/src/runtime/shared/redact-directories.mjs +18 -0
- package/src/runtime/shared/remove-directory.mjs +28 -0
- package/src/runtime/shared/routine-trigger.d.mts +6 -1
- package/src/runtime/shared/routine-trigger.mjs +14 -6
- package/src/runtime/shared/run-child.d.mts +3 -0
- package/src/runtime/shared/run-child.mjs +24 -3
- package/src/runtime/shared/session-baseline-store.mjs +8 -2
- package/src/runtime/shared/session-sidebar-host.d.mts +11 -2
- package/src/runtime/shared/session-sidebar-host.mjs +16 -3
- package/src/runtime/shared/singleton-owner.mjs +7 -6
- package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
- package/src/runtime/shared/staged-update.mjs +4 -2
- package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
- package/src/runtime/shared/tool-execution-contract.mjs +10 -0
- package/src/runtime/shared/tool-work-units.mjs +12 -9
- package/src/runtime/shared/transcript-metadata.mjs +28 -3
- package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
- package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
- package/src/runtime/shared/turn-snapshot.mjs +277 -124
- package/src/runtime/shared/user-cwd.mjs +9 -4
- package/src/runtime/shared/user-data-guard.mjs +92 -61
- package/src/runtime/shared/utf8-cut.mjs +10 -0
- package/src/runtime/shared/worktrees/activity-gate.mjs +251 -61
- package/src/runtime/shared/worktrees/contract.mjs +11 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +11 -2
- package/src/runtime/shared/worktrees/manager.mjs +419 -52
- package/src/runtime/shared/worktrees/registry.mjs +29 -27
- package/src/runtime/shared/worktrees/tool-host.mjs +39 -0
- package/src/runtime/tidy/core-install.mjs +26 -4
- package/src/runtime/tidy/install.mjs +91 -23
- package/src/runtime/tidy/process.mjs +41 -8
- package/src/runtime/tidy/resolve.mjs +10 -7
- package/src/runtime/web-search/lib/config.mjs +4 -16
- package/src/session-runtime/agent-home-delivery.mjs +542 -204
- package/src/session-runtime/agent-profile-changes.mjs +16 -0
- package/src/session-runtime/agent-room-delivery.mjs +81 -35
- package/src/session-runtime/agent-task-sessions.mjs +811 -179
- package/src/session-runtime/agent-tool-routing.mjs +1 -0
- package/src/session-runtime/boot/apis.mjs +48 -24
- package/src/session-runtime/boot/config.mjs +1 -0
- package/src/session-runtime/boot/facade.mjs +16 -7
- package/src/session-runtime/boot/infrastructure.mjs +14 -2
- package/src/session-runtime/boot/providers.mjs +2 -2
- package/src/session-runtime/boot/shared.mjs +12 -6
- package/src/session-runtime/boot/tools.mjs +23 -3
- package/src/session-runtime/bot-status.mjs +432 -0
- package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
- package/src/session-runtime/config-lifecycle.mjs +60 -55
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
- package/src/session-runtime/held-requests.mjs +31 -33
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +24 -26
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown.mjs +11 -3
- package/src/session-runtime/mcp-glue/connect.mjs +100 -186
- package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
- package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
- package/src/session-runtime/media-api.mjs +5 -2
- package/src/session-runtime/model-recency.mjs +1 -0
- package/src/session-runtime/model-route/route-tuning.mjs +4 -1
- package/src/session-runtime/model-route/set-route.mjs +61 -1
- package/src/session-runtime/owned-automation-run.mjs +8 -1
- package/src/session-runtime/provider-models/row-hydration.mjs +8 -1
- package/src/session-runtime/quick-model-rows/model-meta.mjs +2 -0
- package/src/session-runtime/quick-model-rows/provider-rows.mjs +7 -1
- package/src/session-runtime/route-resolution.mjs +16 -8
- package/src/session-runtime/route-state.mjs +1 -59
- package/src/session-runtime/routine-home-turn.mjs +5 -3
- package/src/session-runtime/runtime-bootstrap.mjs +5 -3
- package/src/session-runtime/runtime-paths.mjs +11 -5
- package/src/session-runtime/runtime-review-api.mjs +4 -1
- package/src/session-runtime/runtime-tunables.mjs +6 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
- package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
- package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +34 -19
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +25 -21
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +7 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +8 -5
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
- package/src/session-runtime/services/agent-tool.mjs +6 -0
- package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
- package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
- package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
- package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
- package/src/session-runtime/services/plugin-admin.mjs +26 -26
- package/src/session-runtime/services/provider-admin.mjs +26 -6
- package/src/session-runtime/services/schedule-access.mjs +33 -4
- package/src/session-runtime/services/seeds.mjs +4 -3
- package/src/session-runtime/services/usage-dashboard.mjs +1 -1
- package/src/session-runtime/services/usage-stats-model.mjs +2 -1
- package/src/session-runtime/services/worktree-access.mjs +27 -0
- package/src/session-runtime/session-create/materialize.mjs +2 -3
- package/src/session-runtime/session-create/session-options.mjs +15 -2
- package/src/session-runtime/session-hooks.mjs +9 -17
- package/src/session-runtime/settings-builtin-tools-api.mjs +65 -1
- package/src/session-runtime/settings-compaction-api.mjs +86 -39
- package/src/session-runtime/setup-tool/executor.mjs +12 -2
- package/src/session-runtime/setup-tool/settings-contract.mjs +34 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
- package/src/session-runtime/skills-api.mjs +12 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +349 -0
- package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
- package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
- package/src/session-runtime/tool-policy/policy-stage.mjs +183 -0
- package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
- package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
- package/src/session-runtime/tool-policy-refresh.mjs +48 -369
- package/src/session-runtime/tool-surface.mjs +10 -4
- package/src/session-runtime/turn/session-ops.mjs +8 -0
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +95 -88
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +7 -2
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +527 -333
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +85 -63
- package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
- package/src/session-runtime/workspace/transition-steps.mjs +1 -18
- package/src/session-runtime/workspace/transitions.mjs +279 -67
- package/src/session-runtime/workspace/workspace-state.mjs +7 -6
- package/src/session-runtime/workspace/worktree-tool.mjs +194 -0
- package/src/standalone/daemon-agent-control.mjs +4 -1
- package/src/standalone/daemon-lag-profiler.mjs +3 -1
- package/src/standalone/daemon-session-control.mjs +173 -15
- package/src/standalone/daemon-telemetry.mjs +9 -0
- package/src/standalone/daemon.mjs +33 -10
- package/src/standalone/local-session-runtime.mjs +33 -16
- package/src/standalone/session-client.mjs +7 -2
- package/src/standalone/session-protocol.mjs +8 -0
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +2 -0
- package/src/standalone/session-service/agent-route-follow.mjs +69 -0
- package/src/standalone/session-service/session-calls/session-turns.mjs +33 -4
- package/src/standalone/session-service.mjs +21 -0
- package/src/standalone/session-state-projection.mjs +19 -9
- package/src/standalone/session-tool-output.mjs +36 -9
- package/src/standalone/staged-import.mjs +47 -0
- package/src/tui/App.jsx +2 -0
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
- package/src/tui/app/message-selector.mjs +15 -2
- package/src/tui/app/model-options.mjs +16 -2
- package/src/tui/app/model-picker.mjs +2 -1
- package/src/tui/app/route-pickers.mjs +3 -1
- package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
- package/src/tui/dist/index.mjs +617 -369
- package/src/tui/paste-attachments.mjs +0 -1
- package/src/tui/paste-text-policy.mjs +4 -5
- package/src/tui/prompt-history-store.mjs +16 -21
- package/src/tui/session/agent-job-feed/execution-delivery.mjs +4 -1
- package/src/tui/session/context-state.mjs +4 -0
- package/src/tui/session/notice-surface.mjs +3 -0
- package/src/tui/session/session-api/intake/abort.mjs +52 -18
- package/src/tui/session/session-api/intake/rewind.mjs +39 -4
- package/src/tui/session/session-api/media.mjs +2 -1
- package/src/tui/session/session-api/routes-agent-definitions.mjs +76 -0
- package/src/tui/session/session-api/routes-write.mjs +203 -0
- package/src/tui/session/session-api/routes.mjs +23 -247
- package/src/tui/session/session-api/settings.mjs +14 -1
- package/src/tui/session/session-flow/drain.mjs +28 -3
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
- package/src/tui/session/session-flow/steering.mjs +8 -3
- package/src/tui/session/tool-approval.mjs +142 -14
- package/src/tui/session/transcript-intake.mjs +2 -0
- package/src/tui/session/turn.mjs +23 -14
- package/src/tui/transcript-tool-failures.mjs +8 -2
- package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
- package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
- package/src/rules/agent-mode/ROUTINE.md +0 -6
- package/src/session-runtime/room-member-gate.mjs +0 -48
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
// connect. All mutable progress lives on the caller-owned `state`.
|
|
4
4
|
import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
|
|
5
5
|
import { envFlag } from '../../runtime/shared/env.mjs';
|
|
6
|
+
import { awaitInitialConnect } from './initial-connect-gate.mjs';
|
|
6
7
|
import { ensurePluginServerData } from './plugin-servers.mjs';
|
|
8
|
+
import { createServerConnection } from './server-connection.mjs';
|
|
7
9
|
|
|
8
10
|
export function createMcpConnect({
|
|
9
11
|
mcpClient,
|
|
@@ -29,58 +31,100 @@ export function createMcpConnect({
|
|
|
29
31
|
// Answer it with the redirect URL pasted from the browser.
|
|
30
32
|
const completeMcpLogin = (name, callbackUrl) => mcpClient.completeMcpLogin(clean(name), callbackUrl, scopeOptions());
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
await
|
|
48
|
-
|
|
34
|
+
const { applyMcpServerConnection, reconcileServers } = createServerConnection({
|
|
35
|
+
mcpClient,
|
|
36
|
+
state,
|
|
37
|
+
resolveEffectiveMcpServers,
|
|
38
|
+
getMcpScopeId,
|
|
39
|
+
scopeOptions,
|
|
40
|
+
applied,
|
|
41
|
+
fingerprint,
|
|
42
|
+
syncScopeRoot,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Wait for a prior run (its failures were already captured in state).
|
|
46
|
+
async function settled(prior) {
|
|
47
|
+
if (!prior) return;
|
|
48
|
+
try {
|
|
49
|
+
await prior;
|
|
50
|
+
} catch {
|
|
51
|
+
/* prior run's failures already captured */
|
|
49
52
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Register `run` as the in-flight connect so a later reset serializes
|
|
56
|
+
// behind it instead of interleaving disconnect/connect.
|
|
57
|
+
async function trackInFlight(run) {
|
|
58
|
+
state.mcpConnectInFlight = run;
|
|
53
59
|
try {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
target,
|
|
58
|
-
cfg,
|
|
59
|
-
login ? { interactive: true, openBrowser: login.openBrowser } : {}
|
|
60
|
-
);
|
|
61
|
-
} catch (error) {
|
|
62
|
-
const failure = { name: target, msg: error?.message || String(error) };
|
|
63
|
-
if (error?.authRequired) failure.authRequired = true;
|
|
64
|
-
const failures = Array.isArray(error?.failures) ? error.failures : [failure];
|
|
65
|
-
state.mcpFailures = [...(state.mcpFailures || []), ...failures];
|
|
60
|
+
await run;
|
|
61
|
+
} finally {
|
|
62
|
+
if (state.mcpConnectInFlight === run) state.mcpConnectInFlight = null;
|
|
66
63
|
}
|
|
67
64
|
}
|
|
68
65
|
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
66
|
+
// Scoped single-server toggle (or reconcile): non-superseding. It must NEVER
|
|
67
|
+
// cancel a pending full {reset} (cwd-change/boot). So do not bump the
|
|
68
|
+
// generation; just wait for any in-flight run, then bail if a newer full
|
|
69
|
+
// reset has been requested in the meantime.
|
|
70
|
+
async function connectScoped({ only, enabled, reconcile, login }) {
|
|
71
|
+
// A disable/remove must not wait out an interactive login of the
|
|
72
|
+
// connect it queues behind: cancel that login first.
|
|
73
|
+
if (only && enabled === false) cancelMcpLogin(only);
|
|
74
|
+
// Atomically capture the current generation AND the prior in-flight
|
|
75
|
+
// promise in the same synchronous step, then chain our op onto it. No
|
|
76
|
+
// await sits between the capture and the `state.mcpConnectInFlight = run`
|
|
77
|
+
// assignment, so concurrent {only} calls queue FIFO instead of resuming
|
|
78
|
+
// together and clobbering the in-flight slot. We never bump the
|
|
79
|
+
// generation; a {reset} does, so any {only} queued behind a reset sees
|
|
80
|
+
// the newer generation when its turn comes and bails.
|
|
81
|
+
const gen = state.mcpConnectGeneration;
|
|
82
|
+
const prev = state.mcpConnectInFlight;
|
|
83
|
+
await trackInFlight(
|
|
84
|
+
(async () => {
|
|
85
|
+
await settled(prev);
|
|
86
|
+
if (gen !== state.mcpConnectGeneration) return;
|
|
87
|
+
if (reconcile) await reconcileServers();
|
|
88
|
+
else await applyMcpServerConnection(only, enabled, undefined, login);
|
|
89
|
+
})()
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Serialize reconnects: boot connect, cwd-change reset, and rapid cwd
|
|
94
|
+
// switches must never interleave their disconnect/connect phases, or an
|
|
95
|
+
// older run finishing after a newer reset could re-add stale servers into
|
|
96
|
+
// the shared client registry. Approach: a generation token + a single
|
|
97
|
+
// in-flight promise. Each call bumps the generation, waits for any prior
|
|
98
|
+
// run to finish, then bails if a newer call has superseded it — leaving the
|
|
99
|
+
// latest requested effective-server-set in the registry.
|
|
100
|
+
async function connectAll({ reset }) {
|
|
101
|
+
const gen = ++state.mcpConnectGeneration;
|
|
102
|
+
await settled(state.mcpConnectInFlight);
|
|
103
|
+
if (gen !== state.mcpConnectGeneration) return;
|
|
104
|
+
await trackInFlight(
|
|
105
|
+
(async () => {
|
|
106
|
+
if (reset) {
|
|
107
|
+
await mcpClient.disconnectAll?.(scopeOptions());
|
|
108
|
+
applied().clear();
|
|
109
|
+
}
|
|
110
|
+
state.mcpFailures = [];
|
|
111
|
+
syncScopeRoot();
|
|
112
|
+
const { servers } = resolveEffectiveMcpServers();
|
|
113
|
+
for (const [name, cfg] of Object.entries(servers)) {
|
|
114
|
+
if (cfg?.enabled === false) applied().delete(name);
|
|
115
|
+
else applied().set(name, fingerprint(cfg));
|
|
116
|
+
}
|
|
117
|
+
if (Object.keys(servers).length === 0) return;
|
|
118
|
+
try {
|
|
119
|
+
for (const cfg of Object.values(servers)) if (cfg?.enabled !== false) ensurePluginServerData(cfg);
|
|
120
|
+
await mcpClient.connectMcpServers(servers, scopeOptions());
|
|
121
|
+
} catch (error) {
|
|
122
|
+
state.mcpFailures = Array.isArray(error?.failures)
|
|
123
|
+
? error.failures
|
|
124
|
+
: [{ name: 'mcp', msg: error?.message || String(error) }];
|
|
125
|
+
}
|
|
126
|
+
})()
|
|
127
|
+
);
|
|
84
128
|
}
|
|
85
129
|
|
|
86
130
|
async function connectConfiguredMcp({
|
|
@@ -98,146 +142,16 @@ export function createMcpConnect({
|
|
|
98
142
|
else await mcpClient.disconnectAll?.(scopeOptions());
|
|
99
143
|
return mcpStatus();
|
|
100
144
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// just wait for any in-flight run, then bail if a newer full reset has
|
|
104
|
-
// been requested in the meantime. Registering as in-flight makes a later
|
|
105
|
-
// reset serialize behind us instead of interleaving disconnect/connect.
|
|
106
|
-
if (only || reconcile) {
|
|
107
|
-
// A disable/remove must not wait out an interactive login of the
|
|
108
|
-
// connect it queues behind: cancel that login first.
|
|
109
|
-
if (only && enabled === false) cancelMcpLogin(only);
|
|
110
|
-
// Atomically capture the current generation AND the prior in-flight
|
|
111
|
-
// promise in the same synchronous step, then chain our op onto it. No
|
|
112
|
-
// await sits between the capture and the `state.mcpConnectInFlight = run`
|
|
113
|
-
// assignment, so concurrent {only} calls queue FIFO instead of resuming
|
|
114
|
-
// together and clobbering the in-flight slot. We never bump the
|
|
115
|
-
// generation; a {reset} does, so any {only} queued behind a reset sees
|
|
116
|
-
// the newer generation when its turn comes and bails.
|
|
117
|
-
const gen = state.mcpConnectGeneration;
|
|
118
|
-
const prev = state.mcpConnectInFlight;
|
|
119
|
-
const run = (async () => {
|
|
120
|
-
if (prev) {
|
|
121
|
-
try {
|
|
122
|
-
await prev;
|
|
123
|
-
} catch {
|
|
124
|
-
/* prior run's failures already captured */
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
if (gen !== state.mcpConnectGeneration) return;
|
|
128
|
-
if (reconcile) await reconcileServers();
|
|
129
|
-
else await applyMcpServerConnection(only, enabled, undefined, login);
|
|
130
|
-
})();
|
|
131
|
-
state.mcpConnectInFlight = run;
|
|
132
|
-
try {
|
|
133
|
-
await run;
|
|
134
|
-
} finally {
|
|
135
|
-
if (state.mcpConnectInFlight === run) state.mcpConnectInFlight = null;
|
|
136
|
-
}
|
|
137
|
-
return mcpStatus();
|
|
138
|
-
}
|
|
139
|
-
// Serialize reconnects: boot connect, cwd-change reset, and rapid cwd
|
|
140
|
-
// switches must never interleave their disconnect/connect phases, or an
|
|
141
|
-
// older run finishing after a newer reset could re-add stale servers into
|
|
142
|
-
// the shared client registry. Approach: a generation token + a single
|
|
143
|
-
// in-flight promise. Each call bumps the generation, waits for any prior
|
|
144
|
-
// run to finish, then bails if a newer call has superseded it — leaving the
|
|
145
|
-
// latest requested effective-server-set in the registry.
|
|
146
|
-
const gen = ++state.mcpConnectGeneration;
|
|
147
|
-
if (state.mcpConnectInFlight) {
|
|
148
|
-
try {
|
|
149
|
-
await state.mcpConnectInFlight;
|
|
150
|
-
} catch {
|
|
151
|
-
/* prior run's failures already captured */
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (gen !== state.mcpConnectGeneration) return mcpStatus();
|
|
155
|
-
const run = (async () => {
|
|
156
|
-
if (reset) {
|
|
157
|
-
await mcpClient.disconnectAll?.(scopeOptions());
|
|
158
|
-
applied().clear();
|
|
159
|
-
}
|
|
160
|
-
state.mcpFailures = [];
|
|
161
|
-
syncScopeRoot();
|
|
162
|
-
const { servers } = resolveEffectiveMcpServers();
|
|
163
|
-
for (const [name, cfg] of Object.entries(servers)) {
|
|
164
|
-
if (cfg?.enabled === false) applied().delete(name);
|
|
165
|
-
else applied().set(name, fingerprint(cfg));
|
|
166
|
-
}
|
|
167
|
-
if (Object.keys(servers).length === 0) return;
|
|
168
|
-
try {
|
|
169
|
-
for (const cfg of Object.values(servers)) if (cfg?.enabled !== false) ensurePluginServerData(cfg);
|
|
170
|
-
await mcpClient.connectMcpServers(servers, scopeOptions());
|
|
171
|
-
} catch (error) {
|
|
172
|
-
state.mcpFailures = Array.isArray(error?.failures)
|
|
173
|
-
? error.failures
|
|
174
|
-
: [{ name: 'mcp', msg: error?.message || String(error) }];
|
|
175
|
-
}
|
|
176
|
-
})();
|
|
177
|
-
state.mcpConnectInFlight = run;
|
|
178
|
-
try {
|
|
179
|
-
await run;
|
|
180
|
-
} finally {
|
|
181
|
-
if (state.mcpConnectInFlight === run) state.mcpConnectInFlight = null;
|
|
182
|
-
}
|
|
145
|
+
if (only || reconcile) await connectScoped({ only, enabled, reconcile, login });
|
|
146
|
+
else await connectAll({ reset });
|
|
183
147
|
return mcpStatus();
|
|
184
148
|
}
|
|
185
149
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
let budgetMs = 10000;
|
|
194
|
-
try {
|
|
195
|
-
// The gate must outlast the slowest enabled server's own startup budget;
|
|
196
|
-
// a server with its budget disabled (0) means the connect may never
|
|
197
|
-
// settle, so the whole gate is disabled (handled below).
|
|
198
|
-
const configs = Object.values(resolveEffectiveMcpServers().servers).filter((cfg) => cfg?.enabled !== false);
|
|
199
|
-
const budgets = (configs.length > 0 ? configs : [{}])
|
|
200
|
-
.map((cfg) => mcpClient.resolveMcpStartupTimeoutMs?.(cfg))
|
|
201
|
-
.filter((value) => Number.isFinite(value));
|
|
202
|
-
if (budgets.length > 0) budgetMs = budgets.includes(0) ? 0 : Math.max(...budgets);
|
|
203
|
-
} catch {
|
|
204
|
-
/* fall back to default budget */
|
|
205
|
-
}
|
|
206
|
-
if (maxWaitMs !== null && maxWaitMs !== undefined) {
|
|
207
|
-
const requestedMaxWaitMs = Number(maxWaitMs);
|
|
208
|
-
if (Number.isFinite(requestedMaxWaitMs) && requestedMaxWaitMs >= 0) {
|
|
209
|
-
budgetMs = Math.min(budgetMs, requestedMaxWaitMs);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
// Budget disabled (0/off) = no per-server startup timeout, so the connect
|
|
213
|
-
// promise may never settle; never gate the turn on it — fall back to the
|
|
214
|
-
// legacy fire-and-forget behavior (late servers use the deferred path).
|
|
215
|
-
if (!(budgetMs > 0)) return;
|
|
216
|
-
let timer = null;
|
|
217
|
-
let expired = false;
|
|
218
|
-
const budget = new Promise((resolveBudget) => {
|
|
219
|
-
timer = setTimeout(() => {
|
|
220
|
-
expired = true;
|
|
221
|
-
resolveBudget();
|
|
222
|
-
}, budgetMs);
|
|
223
|
-
});
|
|
224
|
-
try {
|
|
225
|
-
// Follow replacement connects (a reconnect queued behind the captured
|
|
226
|
-
// run installs a new in-flight promise) inside ONE fixed deadline.
|
|
227
|
-
// Failures are already captured in state.mcpFailures, so rejections are
|
|
228
|
-
// swallowed: this gate must never reject the turn.
|
|
229
|
-
let current = inFlight;
|
|
230
|
-
while (current && !expired) {
|
|
231
|
-
await Promise.race([Promise.resolve(current).catch(() => {}), budget]);
|
|
232
|
-
if (expired) break;
|
|
233
|
-
// Let a queued reconnect install its promise before re-checking.
|
|
234
|
-
await Promise.race([new Promise((resolveTick) => setImmediate(resolveTick)), budget]);
|
|
235
|
-
current = state.mcpConnectInFlight;
|
|
236
|
-
}
|
|
237
|
-
} finally {
|
|
238
|
-
if (timer) clearTimeout(timer);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
return { connectConfiguredMcp, awaitInitialMcpConnect, cancelMcpLogin, completeMcpLogin };
|
|
150
|
+
return {
|
|
151
|
+
connectConfiguredMcp,
|
|
152
|
+
awaitInitialMcpConnect: (maxWaitMs) =>
|
|
153
|
+
awaitInitialConnect({ state, mcpClient, resolveEffectiveMcpServers }, maxWaitMs),
|
|
154
|
+
cancelMcpLogin,
|
|
155
|
+
completeMcpLogin,
|
|
156
|
+
};
|
|
243
157
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// The turn gate on the initial MCP connect: a bounded wait, never a rejection.
|
|
2
|
+
|
|
3
|
+
// Turn gate: await the in-flight INITIAL connect, bounded by both the global
|
|
4
|
+
// server startup budget and the caller's TTFT grace. A server still
|
|
5
|
+
// connecting after the grace flows through the existing late-tool deferred
|
|
6
|
+
// announcement path unchanged.
|
|
7
|
+
export async function awaitInitialConnect({ state, mcpClient, resolveEffectiveMcpServers }, maxWaitMs = undefined) {
|
|
8
|
+
const inFlight = state.mcpConnectInFlight;
|
|
9
|
+
if (!inFlight) return;
|
|
10
|
+
let budgetMs = 10000;
|
|
11
|
+
try {
|
|
12
|
+
// The gate must outlast the slowest enabled server's own startup budget;
|
|
13
|
+
// a server with its budget disabled (0) means the connect may never
|
|
14
|
+
// settle, so the whole gate is disabled (handled below).
|
|
15
|
+
const configs = Object.values(resolveEffectiveMcpServers().servers).filter((cfg) => cfg?.enabled !== false);
|
|
16
|
+
const budgets = (configs.length > 0 ? configs : [{}])
|
|
17
|
+
.map((cfg) => mcpClient.resolveMcpStartupTimeoutMs?.(cfg))
|
|
18
|
+
.filter((value) => Number.isFinite(value));
|
|
19
|
+
if (budgets.length > 0) budgetMs = budgets.includes(0) ? 0 : Math.max(...budgets);
|
|
20
|
+
} catch {
|
|
21
|
+
/* fall back to default budget */
|
|
22
|
+
}
|
|
23
|
+
if (maxWaitMs !== null && maxWaitMs !== undefined) {
|
|
24
|
+
const requestedMaxWaitMs = Number(maxWaitMs);
|
|
25
|
+
if (Number.isFinite(requestedMaxWaitMs) && requestedMaxWaitMs >= 0) {
|
|
26
|
+
budgetMs = Math.min(budgetMs, requestedMaxWaitMs);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// Budget disabled (0/off) = no per-server startup timeout, so the connect
|
|
30
|
+
// promise may never settle; never gate the turn on it — fall back to the
|
|
31
|
+
// legacy fire-and-forget behavior (late servers use the deferred path).
|
|
32
|
+
if (!(budgetMs > 0)) return;
|
|
33
|
+
let timer = null;
|
|
34
|
+
let expired = false;
|
|
35
|
+
const budget = new Promise((resolveBudget) => {
|
|
36
|
+
timer = setTimeout(() => {
|
|
37
|
+
expired = true;
|
|
38
|
+
resolveBudget();
|
|
39
|
+
}, budgetMs);
|
|
40
|
+
});
|
|
41
|
+
try {
|
|
42
|
+
// Follow replacement connects (a reconnect queued behind the captured
|
|
43
|
+
// run installs a new in-flight promise) inside ONE fixed deadline.
|
|
44
|
+
// Failures are already captured in state.mcpFailures, so rejections are
|
|
45
|
+
// swallowed: this gate must never reject the turn.
|
|
46
|
+
let current = inFlight;
|
|
47
|
+
while (current && !expired) {
|
|
48
|
+
await Promise.race([Promise.resolve(current).catch(() => {}), budget]);
|
|
49
|
+
if (expired) break;
|
|
50
|
+
// Let a queued reconnect install its promise before re-checking.
|
|
51
|
+
await Promise.race([new Promise((resolveTick) => setImmediate(resolveTick)), budget]);
|
|
52
|
+
current = state.mcpConnectInFlight;
|
|
53
|
+
}
|
|
54
|
+
} finally {
|
|
55
|
+
if (timer) clearTimeout(timer);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Connecting, disconnecting and reconciling individual MCP servers in the live
|
|
2
|
+
// registry. The caller (connect.mjs) owns the serialization and the shared state.
|
|
3
|
+
import { clean } from '../../runtime/agent/orchestrator/runtime-core/session-text.mjs';
|
|
4
|
+
import { ensurePluginServerData } from './plugin-servers.mjs';
|
|
5
|
+
|
|
6
|
+
export function createServerConnection({
|
|
7
|
+
mcpClient,
|
|
8
|
+
state,
|
|
9
|
+
resolveEffectiveMcpServers,
|
|
10
|
+
getMcpScopeId,
|
|
11
|
+
scopeOptions,
|
|
12
|
+
applied,
|
|
13
|
+
fingerprint,
|
|
14
|
+
syncScopeRoot,
|
|
15
|
+
}) {
|
|
16
|
+
// Connect/disconnect exactly one server in the live registry, leaving all
|
|
17
|
+
// others untouched. Used by the enable/disable toggle so a single-server
|
|
18
|
+
// change never triggers a full disconnectAll()/reconnect freeze. Only an
|
|
19
|
+
// explicit sign-in passes `login` ({ openBrowser }): every other connect is
|
|
20
|
+
// non-interactive and reports a server that needs one as sign-in required.
|
|
21
|
+
async function applyMcpServerConnection(name, enabled, servers = resolveEffectiveMcpServers().servers, login = null) {
|
|
22
|
+
const target = clean(name);
|
|
23
|
+
if (!target) return;
|
|
24
|
+
// Changing this server's state clears any stale failure record for it.
|
|
25
|
+
if (Array.isArray(state.mcpFailures)) {
|
|
26
|
+
state.mcpFailures = state.mcpFailures.filter((row) => row.name !== target);
|
|
27
|
+
}
|
|
28
|
+
const cfg = servers[target];
|
|
29
|
+
if (enabled === false || !cfg || cfg.enabled === false) {
|
|
30
|
+
applied().delete(target);
|
|
31
|
+
await mcpClient.disconnectMcpServer?.(target, scopeOptions());
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
applied().set(target, fingerprint(cfg));
|
|
35
|
+
// Close-then-connect as one generation-guarded op: a shutdown landing
|
|
36
|
+
// between the close and the connect never resurrects the server.
|
|
37
|
+
try {
|
|
38
|
+
ensurePluginServerData(cfg);
|
|
39
|
+
await mcpClient.reconnectSingleMcpServer(
|
|
40
|
+
getMcpScopeId(),
|
|
41
|
+
target,
|
|
42
|
+
cfg,
|
|
43
|
+
login ? { interactive: true, openBrowser: login.openBrowser } : {}
|
|
44
|
+
);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
const failure = { name: target, msg: error?.message || String(error) };
|
|
47
|
+
if (error?.authRequired) failure.authRequired = true;
|
|
48
|
+
const failures = Array.isArray(error?.failures) ? error.failures : [failure];
|
|
49
|
+
state.mcpFailures = [...(state.mcpFailures || []), ...failures];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Bring the registry in line with the effective set: drop servers that are
|
|
54
|
+
// gone or disabled, (re)connect servers that are new or whose resolved
|
|
55
|
+
// config changed; untouched servers keep their connection.
|
|
56
|
+
async function reconcileServers() {
|
|
57
|
+
syncScopeRoot();
|
|
58
|
+
const { servers } = resolveEffectiveMcpServers();
|
|
59
|
+
const known = applied();
|
|
60
|
+
const drops = [...known.keys()].filter((name) => !servers[name] || servers[name].enabled === false);
|
|
61
|
+
const connects = Object.entries(servers)
|
|
62
|
+
.filter(([name, cfg]) => cfg?.enabled !== false && known.get(name) !== fingerprint(cfg))
|
|
63
|
+
.map(([name]) => name);
|
|
64
|
+
await Promise.allSettled([
|
|
65
|
+
...drops.map((name) => applyMcpServerConnection(name, false, servers)),
|
|
66
|
+
...connects.map((name) => applyMcpServerConnection(name, true, servers)),
|
|
67
|
+
]);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { applyMcpServerConnection, reconcileServers };
|
|
71
|
+
}
|
|
@@ -41,8 +41,11 @@ export function createMediaApi() {
|
|
|
41
41
|
});
|
|
42
42
|
return { status: await module.getVoiceStatus(), error };
|
|
43
43
|
},
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
// `budgetMs` (Studio) caps the per-lane catalog wait; slower lanes come
|
|
45
|
+
// back `catalogPending`. Capped so a caller cannot park the call.
|
|
46
|
+
async listMediaLanes(options) {
|
|
47
|
+
const budgetMs = Math.min(30_000, Math.max(0, Math.trunc(Number(options?.budgetMs) || 0)));
|
|
48
|
+
return (await lanes()).listMediaLanes({ budgetMs });
|
|
46
49
|
},
|
|
47
50
|
// The Studio's current selection is the runtime's default: a tool call
|
|
48
51
|
// that omits lane/model follows it. Studio pushes on every settled change.
|
|
@@ -11,6 +11,7 @@ function customRowFields(name, m) {
|
|
|
11
11
|
if (!isCustomProviderName(name)) return {};
|
|
12
12
|
return {
|
|
13
13
|
...(typeof m.name === 'string' && m.name ? { name: m.name } : {}),
|
|
14
|
+
...(typeof m.providerName === 'string' && m.providerName ? { providerName: m.providerName } : {}),
|
|
14
15
|
...(typeof m.hidden === 'boolean' ? { hidden: m.hidden } : {}),
|
|
15
16
|
...(typeof m.manual === 'boolean' ? { manual: m.manual } : {}),
|
|
16
17
|
...(m.customReasoning && typeof m.customReasoning === 'object' ? { customReasoning: m.customReasoning } : {}),
|
|
@@ -67,7 +67,10 @@ export function createRouteTuning(deps, persist) {
|
|
|
67
67
|
},
|
|
68
68
|
async setEffort(value) {
|
|
69
69
|
const normalized = normalizeEffortInput(value);
|
|
70
|
-
|
|
70
|
+
// An explicit level is the user's choice for this route: Auto effort
|
|
71
|
+
// would replace it on the next turn (its base is fixed), so the pick
|
|
72
|
+
// turns the route's Auto off until it is switched back on.
|
|
73
|
+
setRouteState({ ...getRoute(), effort: normalized, ...(normalized ? { autoEffort: false } : {}) });
|
|
71
74
|
const modelMeta = await lookupModelMeta(getRoute().provider, getRoute().model);
|
|
72
75
|
const fastCapable = selectionFastCapable(getRoute().provider, modelMeta, normalized, getRoute().modelParameters);
|
|
73
76
|
await commitRouteTuning(fastCapable, modelMeta);
|
|
@@ -24,6 +24,11 @@ import {
|
|
|
24
24
|
} from '../../runtime/agent/orchestrator/runtime-core/session-route-policy.mjs';
|
|
25
25
|
import { rebuildToolSurfaceForProviderWithMigration } from '../../runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs';
|
|
26
26
|
import { UNOWNED_LEASE, openRouteLease } from './route-ownership.mjs';
|
|
27
|
+
import { resolveSessionMode } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
|
|
28
|
+
import { ownerRouteFallbacks } from '../../runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs';
|
|
29
|
+
import { normalizeWorkflowRoute } from '../../runtime/agent/orchestrator/runtime-core/workflow.mjs';
|
|
30
|
+
import { routeChain, validateRouteChainProviders } from '../../runtime/shared/model-route-chain.mjs';
|
|
31
|
+
import { resolveChainEntry } from '../workflow-agents-api/agent-route.mjs';
|
|
27
32
|
|
|
28
33
|
/** The request, completed from the live route where the caller left gaps. */
|
|
29
34
|
function completeRequest(deps, next) {
|
|
@@ -105,6 +110,32 @@ async function recreateEmptySession(deps, lease) {
|
|
|
105
110
|
if (closed) await createCurrentSession('model-switch-empty');
|
|
106
111
|
}
|
|
107
112
|
|
|
113
|
+
/** The fallback chain a Lead-class session follows on `route`: its owner's chain
|
|
114
|
+
* while the route is the owner's primary model, none otherwise (see
|
|
115
|
+
* owner-route-fallbacks.mjs). Nothing for an agent's session, which keeps its own. */
|
|
116
|
+
export function sessionRouteFallbackFields(deps, session, route) {
|
|
117
|
+
const { mode, agentId } = resolveSessionMode({ session });
|
|
118
|
+
if (!agentId) return {};
|
|
119
|
+
return {
|
|
120
|
+
routeFallbacks: ownerRouteFallbacks({
|
|
121
|
+
sessionMode: mode,
|
|
122
|
+
agentId,
|
|
123
|
+
provider: route.provider,
|
|
124
|
+
model: route.model,
|
|
125
|
+
config: deps.getConfig(),
|
|
126
|
+
}),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** A same-model selection (a bot profile saved with new fallbacks) restarts the
|
|
131
|
+
* addressed session's chain when the owner's chain no longer matches it. */
|
|
132
|
+
function refreshSessionFallbacks(deps, session) {
|
|
133
|
+
const fields = sessionRouteFallbackFields(deps, session, deps.getRoute());
|
|
134
|
+
if (!fields.routeFallbacks) return;
|
|
135
|
+
if (JSON.stringify(fields.routeFallbacks) === JSON.stringify(session.routeFallbacks || [])) return;
|
|
136
|
+
deps.mgr.updateSessionRoute?.(session.id, fields, { session });
|
|
137
|
+
}
|
|
138
|
+
|
|
108
139
|
/** Rewrite the addressed empty session to the route it was asked to run on. */
|
|
109
140
|
function updateSessionInPlace(deps, session, updateOptions) {
|
|
110
141
|
const { getRoute, getSession, setSession, mgr, statusRoutes } = deps;
|
|
@@ -119,6 +150,7 @@ function updateSessionInPlace(deps, session, updateOptions) {
|
|
|
119
150
|
contextPercent: route.contextPercent,
|
|
120
151
|
contextTokens: route.contextTokens || null,
|
|
121
152
|
selectedContextWindow: route.selectedContextWindow || null,
|
|
153
|
+
...sessionRouteFallbackFields(deps, session, route),
|
|
122
154
|
};
|
|
123
155
|
const updated = mgr.updateSessionRoute?.(session.id, fields, updateOptions);
|
|
124
156
|
if (updated) setSession(updated);
|
|
@@ -183,6 +215,27 @@ function switchSessionInPlace(deps, session) {
|
|
|
183
215
|
return recorded ? boundary : null;
|
|
184
216
|
}
|
|
185
217
|
|
|
218
|
+
/** The Lead's fallback models after this selection, checked like an agent's
|
|
219
|
+
* chain (leaf routes, distinct providers): an explicit list replaces the
|
|
220
|
+
* stored one ([] clears it), a selection without one keeps it. */
|
|
221
|
+
async function leadFallbackChain(deps, next, primary) {
|
|
222
|
+
const storedPreset = findPreset(deps.getConfig(), workflowPresetId('lead'));
|
|
223
|
+
const requested = hasOwn(next || {}, 'fallbacks') ? next.fallbacks : storedPreset?.fallbacks;
|
|
224
|
+
if (!Array.isArray(requested) || !requested.length) return [];
|
|
225
|
+
const chain = routeChain({ provider: primary.provider, model: primary.model, fallbacks: requested });
|
|
226
|
+
validateRouteChainProviders(chain);
|
|
227
|
+
const storedChain = routeChain(storedPreset || {});
|
|
228
|
+
// Each entry goes through the agents' normalizer (fast clamp, context window).
|
|
229
|
+
const resolved = [];
|
|
230
|
+
for (const entry of chain.slice(1)) {
|
|
231
|
+
const previous = storedChain.find((c) => c.provider === entry.provider && c.model === entry.model);
|
|
232
|
+
resolved.push(await resolveChainEntry(deps, entry, previous || {}));
|
|
233
|
+
}
|
|
234
|
+
return (
|
|
235
|
+
normalizeWorkflowRoute({ provider: primary.provider, model: primary.model, fallbacks: resolved })?.fallbacks || []
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
186
239
|
/** Validate, persist and adopt the requested route as the runtime's route. */
|
|
187
240
|
async function adoptRoute(deps, persist, next, options, lease) {
|
|
188
241
|
const {
|
|
@@ -195,6 +248,12 @@ async function adoptRoute(deps, persist, next, options, lease) {
|
|
|
195
248
|
scheduleStatuslineUsageRefresh,
|
|
196
249
|
} = deps;
|
|
197
250
|
const { selectedRoute, fastCapable, modelMeta } = await resolveSelectedRoute(deps, next);
|
|
251
|
+
// The Lead's fallback chain travels with an explicit main-model choice only
|
|
252
|
+
// (the Lead editor, the setup tool); a session's own pick never touches it.
|
|
253
|
+
const persistedRoute =
|
|
254
|
+
options?.keepMainModel === false && options?.sessionOnly !== true
|
|
255
|
+
? { ...selectedRoute, fallbacks: await leadFallbackChain(deps, next, selectedRoute) }
|
|
256
|
+
: selectedRoute;
|
|
198
257
|
// The Lead route a conditional fill wrote, until the file confirms it.
|
|
199
258
|
let filled = null;
|
|
200
259
|
// Provider readiness may outlast the session the selection was made for.
|
|
@@ -222,7 +281,7 @@ async function adoptRoute(deps, persist, next, options, lease) {
|
|
|
222
281
|
// The main model changes only on an explicit main-model choice
|
|
223
282
|
// (keepMainModel: false, e.g. the setup tool); every other selection
|
|
224
283
|
// — the session surface's model pick, an heir — keeps it.
|
|
225
|
-
const leadRoute = persist.persistAdoptedModelSettings(
|
|
284
|
+
const leadRoute = persist.persistAdoptedModelSettings(persistedRoute, {
|
|
226
285
|
keepMainModel: options?.keepMainModel !== false,
|
|
227
286
|
onlyIfAbsent: options?.onlyIfEmpty === true,
|
|
228
287
|
});
|
|
@@ -340,6 +399,7 @@ export function createSetRoute(deps, persist) {
|
|
|
340
399
|
return modelSwitch ? { ...getRoute(), modelSwitch } : getRoute();
|
|
341
400
|
}
|
|
342
401
|
persist.applySessionTuning();
|
|
402
|
+
refreshSessionFallbacks(deps, session);
|
|
343
403
|
return getRoute();
|
|
344
404
|
}
|
|
345
405
|
// An addressed runtime keeps its durable id: the empty session is updated
|
|
@@ -101,7 +101,7 @@ async function queueResult(row, item, entry, { deliver, recordDelivery, onDelive
|
|
|
101
101
|
/**
|
|
102
102
|
* `row` is `{ name, ownerAgentId }`; `run({ signal })` resolves `{ sessionId,
|
|
103
103
|
* result }` (`signal` is the caller's cancellation, if any). Resolves the
|
|
104
|
-
* outcome, or `{ skipped: true, reason: 'owner' | 'overlap' | 'backoff' }`
|
|
104
|
+
* outcome, or `{ skipped: true, reason: 'owner' | 'overlap' | 'backoff' | 'paused' }`
|
|
105
105
|
* (an owner skip also names `ownerProblem` and its `message`); a failed run
|
|
106
106
|
* rejects.
|
|
107
107
|
*/
|
|
@@ -141,6 +141,13 @@ export async function runOwnedAutomation(kind, row, run, deps = {}) {
|
|
|
141
141
|
const state = await Promise.resolve()
|
|
142
142
|
.then(() => record.state(name))
|
|
143
143
|
.catch(() => null);
|
|
144
|
+
// Switched off (by the user, or by the failure limit): the cron claim and
|
|
145
|
+
// the webhook handler already refuse it, but a one-shot timer or a
|
|
146
|
+
// dispatch that raced the pause must not run it either.
|
|
147
|
+
if (state?.enabled === false) {
|
|
148
|
+
log(`${kind} "${name}": skipped, switched off`);
|
|
149
|
+
return await skip('paused');
|
|
150
|
+
}
|
|
144
151
|
const wait = routineBackoffRemaining(state, now(), limits);
|
|
145
152
|
if (wait > 0) {
|
|
146
153
|
log(`${kind} "${name}": skipped, backing off ${Math.ceil(wait / 1000)}s after failures in a row`);
|
|
@@ -45,8 +45,15 @@ export function hydrateProviderModelRow(cfg, row) {
|
|
|
45
45
|
const modelParameterOptions = addedOptions.length
|
|
46
46
|
? [...existingOptions.filter((option) => !addedOptions.some((added) => added.id === option?.id)), ...addedOptions]
|
|
47
47
|
: row.modelParameterOptions;
|
|
48
|
+
const isCustom = row.provider?.startsWith?.('custom-');
|
|
49
|
+
const customName = isCustom ? String(cfg?.providers?.[row.provider]?.name || '').trim() : '';
|
|
50
|
+
// A custom provider's name always comes from the current configuration; a
|
|
51
|
+
// row's own (possibly renamed or removed) name is dropped.
|
|
52
|
+
const base = { ...row };
|
|
53
|
+
if (isCustom) delete base.providerName;
|
|
48
54
|
return {
|
|
49
|
-
...
|
|
55
|
+
...base,
|
|
56
|
+
...(customName ? { providerName: customName } : {}),
|
|
50
57
|
...(alias ? { display: alias, displayAlias: alias } : {}),
|
|
51
58
|
...(modelParameterOptions ? { modelParameterOptions } : {}),
|
|
52
59
|
effortOptions: effortItemsFor(row.provider, row, null),
|
|
@@ -5,10 +5,12 @@ import { getModelMetadataSync } from '../../runtime/agent/orchestrator/providers
|
|
|
5
5
|
import { isCustomProviderName } from '../../runtime/agent/orchestrator/providers/custom-reasoning.mjs';
|
|
6
6
|
|
|
7
7
|
const CUSTOM_DECLARED_FIELDS = [
|
|
8
|
+
'supportsVision',
|
|
8
9
|
'supportsReasoning',
|
|
9
10
|
'reasoningOptions',
|
|
10
11
|
'reasoningLevels',
|
|
11
12
|
'reasoningContentField',
|
|
13
|
+
'providerName',
|
|
12
14
|
'hidden',
|
|
13
15
|
'manual',
|
|
14
16
|
'customReasoning',
|