mixdog 0.7.1
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/.claude-plugin/marketplace.json +31 -0
- package/.claude-plugin/plugin.json +20 -0
- package/.gitattributes +34 -0
- package/.mcp.json +14 -0
- package/ARCHITECTURE.md +77 -0
- package/CHANGELOG.md +7 -0
- package/CONTRIBUTING.md +45 -0
- package/DATA-FLOW.md +79 -0
- package/LICENSE +21 -0
- package/README.md +389 -0
- package/SECURITY.md +138 -0
- package/UNINSTALL.md +112 -0
- package/agents/maintenance.md +5 -0
- package/agents/memory-classification.md +30 -0
- package/agents/scheduler-task.md +18 -0
- package/agents/webhook-handler.md +27 -0
- package/agents/worker.md +24 -0
- package/bin/bridge +133 -0
- package/bin/statusline-launcher.mjs +78 -0
- package/bin/statusline-lib.mjs +550 -0
- package/bin/statusline.mjs +607 -0
- package/bun.lock +802 -0
- package/commands/config.md +16 -0
- package/commands/doctor.md +13 -0
- package/commands/setup.md +17 -0
- package/defaults/cycle3-review-prompt.md +90 -0
- package/defaults/hidden-roles.json +65 -0
- package/defaults/memory-chunk-prompt.md +63 -0
- package/defaults/memory-promote-prompt.md +135 -0
- package/defaults/mixdog-config.template.json +27 -0
- package/defaults/user-workflow.json +8 -0
- package/defaults/user-workflow.md +12 -0
- package/hooks/hooks.json +73 -0
- package/hooks/lib/active-instance.cjs +77 -0
- package/hooks/lib/permission-evaluator.cjs +411 -0
- package/hooks/lib/permission-route.cjs +63 -0
- package/hooks/lib/permission-rules.cjs +170 -0
- package/hooks/lib/settings-loader.cjs +116 -0
- package/hooks/post-tool-use.cjs +84 -0
- package/hooks/pre-mcp-sandbox.cjs +158 -0
- package/hooks/pre-tool-subagent.cjs +253 -0
- package/hooks/session-start.cjs +1372 -0
- package/hooks/turn-timer.cjs +82 -0
- package/lib/claude-md-writer.cjs +386 -0
- package/lib/config-cjs.cjs +61 -0
- package/lib/hook-pipe-path.cjs +10 -0
- package/lib/keychain-cjs.cjs +263 -0
- package/lib/plugin-paths.cjs +61 -0
- package/lib/rules-builder.cjs +241 -0
- package/lib/text-utils.cjs +61 -0
- package/native/README.md +117 -0
- package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
- package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
- package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
- package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
- package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
- package/package.json +107 -0
- package/prompts/code-review.txt +16 -0
- package/prompts/security-audit.txt +17 -0
- package/rules/bridge/00-common.md +39 -0
- package/rules/bridge/20-skip-protocol.md +18 -0
- package/rules/bridge/30-explorer.md +33 -0
- package/rules/bridge/40-cycle1-agent.md +52 -0
- package/rules/bridge/41-cycle2-agent.md +62 -0
- package/rules/bridge/42-cycle3-agent.md +44 -0
- package/rules/lead/00-tool-lead.md +61 -0
- package/rules/lead/01-general.md +23 -0
- package/rules/lead/02-channels.md +49 -0
- package/rules/lead/03-team.md +27 -0
- package/rules/lead/04-workflow.md +20 -0
- package/rules/shared/00-language.md +14 -0
- package/rules/shared/01-tool.md +138 -0
- package/scripts/bootstrap.mjs +184 -0
- package/scripts/bridge-unify-smoke.mjs +308 -0
- package/scripts/build-runtime-linux.sh +348 -0
- package/scripts/build-runtime-macos.sh +217 -0
- package/scripts/build-runtime-windows.ps1 +242 -0
- package/scripts/builtin-utils-smoke.mjs +392 -0
- package/scripts/check-json.mjs +45 -0
- package/scripts/check-syntax-changed.mjs +102 -0
- package/scripts/check-syntax.mjs +58 -0
- package/scripts/code-graph-batch.test.mjs +33 -0
- package/scripts/config-preserve-smoke.mjs +180 -0
- package/scripts/doctor.mjs +484 -0
- package/scripts/edit-normalize-fuzz.mjs +130 -0
- package/scripts/edit-normalize-smoke.mjs +401 -0
- package/scripts/edit-operation-smoke.mjs +369 -0
- package/scripts/edit2-smoke.mjs +63 -0
- package/scripts/fuzzy-e2e.mjs +28 -0
- package/scripts/fuzzy-smoke.mjs +26 -0
- package/scripts/generate-runtime-manifest.mjs +166 -0
- package/scripts/guard-smoke.mjs +66 -0
- package/scripts/hidden-role-schema-smoke.mjs +162 -0
- package/scripts/hook-routing-smoke.mjs +29 -0
- package/scripts/inject-input.ps1 +204 -0
- package/scripts/io-complex-smoke.mjs +667 -0
- package/scripts/io-explore-bench.mjs +424 -0
- package/scripts/io-guardrails-smoke.mjs +205 -0
- package/scripts/io-mini-bench-baseline.json +11 -0
- package/scripts/io-mini-bench.mjs +216 -0
- package/scripts/io-route-harness.mjs +933 -0
- package/scripts/io-telemetry-report.mjs +691 -0
- package/scripts/mutation-bench.mjs +564 -0
- package/scripts/mutation-io-smoke.mjs +1081 -0
- package/scripts/native-patch-bridge-smoke.mjs +288 -0
- package/scripts/native-patch-smoke.mjs +304 -0
- package/scripts/patch-interior-context-smoke.mjs +49 -0
- package/scripts/patch-newline-utf8-smoke.mjs +157 -0
- package/scripts/perf-hook-smoke.mjs +71 -0
- package/scripts/permission-eval-smoke.mjs +426 -0
- package/scripts/prep-patch.mjs +53 -0
- package/scripts/prep-shim.mjs +96 -0
- package/scripts/provider-cache-smoke.mjs +687 -0
- package/scripts/report-runtime-health.mjs +132 -0
- package/scripts/run-mcp.mjs +1547 -0
- package/scripts/salvage-v4a-shatter.test.mjs +58 -0
- package/scripts/scoped-cache-io-smoke.mjs +103 -0
- package/scripts/shell-policy-round3-smoke.mjs +46 -0
- package/scripts/smoke-runtime-negative.ps1 +100 -0
- package/scripts/smoke-runtime-negative.sh +95 -0
- package/scripts/stall-policy-smoke.mjs +50 -0
- package/scripts/start-memory-worker.mjs +23 -0
- package/scripts/statusline-launcher-smoke.mjs +82 -0
- package/scripts/stress-atomic-write.mjs +1028 -0
- package/scripts/test-config-rmw-restore.mjs +122 -0
- package/scripts/test-fault-inject.mjs +164 -0
- package/scripts/test-large-file.mjs +174 -0
- package/scripts/tool-edge-smoke.mjs +209 -0
- package/scripts/uninstall.mjs +201 -0
- package/scripts/webhook-selfheal-smoke.mjs +29 -0
- package/scripts/write-overwrite-guard-smoke.mjs +56 -0
- package/server-main.mjs +3055 -0
- package/server.mjs +468 -0
- package/setup/config-merge.mjs +254 -0
- package/setup/install.mjs +120 -0
- package/setup/launch-core.mjs +507 -0
- package/setup/launch.mjs +101 -0
- package/setup/setup-server.mjs +3206 -0
- package/setup/setup.html +3693 -0
- package/skills/retro-skill-proposer/SKILL.md +92 -0
- package/skills/schedule-add/SKILL.md +77 -0
- package/skills/setup/SKILL.md +346 -0
- package/skills/webhook-add/SKILL.md +81 -0
- package/src/agent/bridge-stall-watchdog.mjs +337 -0
- package/src/agent/index.mjs +2138 -0
- package/src/agent/orchestrator/activity-bus.mjs +38 -0
- package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +1010 -0
- package/src/agent/orchestrator/bridge-retry.mjs +220 -0
- package/src/agent/orchestrator/bridge-trace.mjs +583 -0
- package/src/agent/orchestrator/cache-mtime.mjs +58 -0
- package/src/agent/orchestrator/config.mjs +358 -0
- package/src/agent/orchestrator/context/collect.mjs +651 -0
- package/src/agent/orchestrator/dispatch-persist.mjs +549 -0
- package/src/agent/orchestrator/drain-registry.mjs +50 -0
- package/src/agent/orchestrator/explore-validator.mjs +8 -0
- package/src/agent/orchestrator/internal-roles.mjs +118 -0
- package/src/agent/orchestrator/internal-tools.mjs +88 -0
- package/src/agent/orchestrator/jobs.mjs +116 -0
- package/src/agent/orchestrator/mcp/client.mjs +364 -0
- package/src/agent/orchestrator/providers/anthropic-betas.mjs +21 -0
- package/src/agent/orchestrator/providers/anthropic-oauth.mjs +1745 -0
- package/src/agent/orchestrator/providers/anthropic.mjs +437 -0
- package/src/agent/orchestrator/providers/gemini.mjs +1175 -0
- package/src/agent/orchestrator/providers/grok-oauth.mjs +782 -0
- package/src/agent/orchestrator/providers/model-catalog.mjs +241 -0
- package/src/agent/orchestrator/providers/openai-compat.mjs +1467 -0
- package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +1890 -0
- package/src/agent/orchestrator/providers/openai-oauth.mjs +1307 -0
- package/src/agent/orchestrator/providers/openai-ws.mjs +104 -0
- package/src/agent/orchestrator/providers/registry.mjs +192 -0
- package/src/agent/orchestrator/providers/retry-classifier.mjs +325 -0
- package/src/agent/orchestrator/session/abort-lookup.mjs +13 -0
- package/src/agent/orchestrator/session/cache/post-edit-marks.mjs +42 -0
- package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
- package/src/agent/orchestrator/session/cache/read-cache.mjs +319 -0
- package/src/agent/orchestrator/session/cache/scoped-cache-outcome.mjs +11 -0
- package/src/agent/orchestrator/session/cache/scoped-cache.mjs +361 -0
- package/src/agent/orchestrator/session/cache/util.mjs +49 -0
- package/src/agent/orchestrator/session/loop.mjs +1478 -0
- package/src/agent/orchestrator/session/manager.mjs +1975 -0
- package/src/agent/orchestrator/session/read-dedup.mjs +6 -0
- package/src/agent/orchestrator/session/result-classification.mjs +65 -0
- package/src/agent/orchestrator/session/save-session-worker.mjs +18 -0
- package/src/agent/orchestrator/session/store.mjs +624 -0
- package/src/agent/orchestrator/session/stream-watchdog.mjs +130 -0
- package/src/agent/orchestrator/session/tool-result-offload.mjs +166 -0
- package/src/agent/orchestrator/session/trim.mjs +491 -0
- package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +115 -0
- package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +327 -0
- package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +150 -0
- package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +228 -0
- package/src/agent/orchestrator/smart-bridge/index.mjs +215 -0
- package/src/agent/orchestrator/smart-bridge/profiles.mjs +37 -0
- package/src/agent/orchestrator/smart-bridge/registry.mjs +348 -0
- package/src/agent/orchestrator/smart-bridge/session-builder.mjs +116 -0
- package/src/agent/orchestrator/stall-policy.mjs +195 -0
- package/src/agent/orchestrator/tool-loop-guard.mjs +75 -0
- package/src/agent/orchestrator/tools/bash-policy-scan.mjs +77 -0
- package/src/agent/orchestrator/tools/bash-session.mjs +721 -0
- package/src/agent/orchestrator/tools/builtin/advisory-lock.mjs +171 -0
- package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +455 -0
- package/src/agent/orchestrator/tools/builtin/atomic-write.mjs +236 -0
- package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +480 -0
- package/src/agent/orchestrator/tools/builtin/binary-file.mjs +76 -0
- package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +256 -0
- package/src/agent/orchestrator/tools/builtin/cache-layers.mjs +386 -0
- package/src/agent/orchestrator/tools/builtin/cwd-utils.mjs +37 -0
- package/src/agent/orchestrator/tools/builtin/device-paths.mjs +154 -0
- package/src/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +292 -0
- package/src/agent/orchestrator/tools/builtin/diff-utils.mjs +109 -0
- package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +58 -0
- package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +240 -0
- package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +113 -0
- package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +74 -0
- package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +242 -0
- package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +211 -0
- package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +1364 -0
- package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +126 -0
- package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +141 -0
- package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +194 -0
- package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +60 -0
- package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +168 -0
- package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +173 -0
- package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +48 -0
- package/src/agent/orchestrator/tools/builtin/fs-reachability.mjs +48 -0
- package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +99 -0
- package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +170 -0
- package/src/agent/orchestrator/tools/builtin/grep-formatting.mjs +113 -0
- package/src/agent/orchestrator/tools/builtin/hash-utils.mjs +6 -0
- package/src/agent/orchestrator/tools/builtin/list-formatting.mjs +7 -0
- package/src/agent/orchestrator/tools/builtin/list-tool.mjs +593 -0
- package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +89 -0
- package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +300 -0
- package/src/agent/orchestrator/tools/builtin/open-config-tool.mjs +26 -0
- package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +152 -0
- package/src/agent/orchestrator/tools/builtin/path-locks.mjs +35 -0
- package/src/agent/orchestrator/tools/builtin/path-utils.mjs +201 -0
- package/src/agent/orchestrator/tools/builtin/read-args.mjs +103 -0
- package/src/agent/orchestrator/tools/builtin/read-batch.mjs +172 -0
- package/src/agent/orchestrator/tools/builtin/read-constants.mjs +40 -0
- package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
- package/src/agent/orchestrator/tools/builtin/read-image-resize.mjs +189 -0
- package/src/agent/orchestrator/tools/builtin/read-image.mjs +88 -0
- package/src/agent/orchestrator/tools/builtin/read-lines.mjs +12 -0
- package/src/agent/orchestrator/tools/builtin/read-mode-tool.mjs +455 -0
- package/src/agent/orchestrator/tools/builtin/read-open.mjs +190 -0
- package/src/agent/orchestrator/tools/builtin/read-range-index.mjs +271 -0
- package/src/agent/orchestrator/tools/builtin/read-ranges.mjs +26 -0
- package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +728 -0
- package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +173 -0
- package/src/agent/orchestrator/tools/builtin/read-special-files.mjs +268 -0
- package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
- package/src/agent/orchestrator/tools/builtin/read-tool.mjs +530 -0
- package/src/agent/orchestrator/tools/builtin/read-windows.mjs +107 -0
- package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +196 -0
- package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +422 -0
- package/src/agent/orchestrator/tools/builtin/search-builders.mjs +158 -0
- package/src/agent/orchestrator/tools/builtin/search-tool.mjs +869 -0
- package/src/agent/orchestrator/tools/builtin/shell-analysis.mjs +653 -0
- package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +936 -0
- package/src/agent/orchestrator/tools/builtin/shell-output.mjs +36 -0
- package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +214 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +143 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +206 -0
- package/src/agent/orchestrator/tools/builtin/snapshot-validation.mjs +98 -0
- package/src/agent/orchestrator/tools/builtin/text-stats.mjs +69 -0
- package/src/agent/orchestrator/tools/builtin/windows-roots.mjs +23 -0
- package/src/agent/orchestrator/tools/builtin/write-tool.mjs +401 -0
- package/src/agent/orchestrator/tools/builtin.mjs +500 -0
- package/src/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +39 -0
- package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
- package/src/agent/orchestrator/tools/code-graph.mjs +4095 -0
- package/src/agent/orchestrator/tools/cwd-tool.mjs +298 -0
- package/src/agent/orchestrator/tools/destructive-warning.mjs +323 -0
- package/src/agent/orchestrator/tools/edit-normalize.mjs +603 -0
- package/src/agent/orchestrator/tools/env-scrub.mjs +100 -0
- package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +144 -0
- package/src/agent/orchestrator/tools/graph-manifest.json +26 -0
- package/src/agent/orchestrator/tools/host-input.mjs +204 -0
- package/src/agent/orchestrator/tools/mutation-content-cache.mjs +67 -0
- package/src/agent/orchestrator/tools/mutation-planner.mjs +75 -0
- package/src/agent/orchestrator/tools/next-call-utils.mjs +48 -0
- package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +133 -0
- package/src/agent/orchestrator/tools/patch-manifest.json +26 -0
- package/src/agent/orchestrator/tools/patch-tool-defs.mjs +20 -0
- package/src/agent/orchestrator/tools/patch.mjs +2754 -0
- package/src/agent/orchestrator/tools/progress-message.mjs +118 -0
- package/src/agent/orchestrator/tools/result-compression.mjs +279 -0
- package/src/agent/orchestrator/tools/shell-command.mjs +865 -0
- package/src/agent/orchestrator/tools/shell-exec-policy.mjs +89 -0
- package/src/agent/orchestrator/tools/shell-policy-danger-target.mjs +27 -0
- package/src/agent/orchestrator/tools/shell-policy-imports.mjs +7 -0
- package/src/agent/orchestrator/tools/shell-policy.mjs +345 -0
- package/src/agent/orchestrator/tools/shell-snapshot.mjs +313 -0
- package/src/agent/orchestrator/workflow-store.mjs +93 -0
- package/src/agent/tool-defs.mjs +103 -0
- package/src/channels/backends/discord.mjs +784 -0
- package/src/channels/data/voice-runtime-manifest.json +138 -0
- package/src/channels/index.mjs +3229 -0
- package/src/channels/lib/cli-worker-host.mjs +12 -0
- package/src/channels/lib/config-lock.mjs +13 -0
- package/src/channels/lib/config.mjs +292 -0
- package/src/channels/lib/drop-trace.mjs +71 -0
- package/src/channels/lib/event-pipeline.mjs +81 -0
- package/src/channels/lib/event-queue.mjs +345 -0
- package/src/channels/lib/executor.mjs +168 -0
- package/src/channels/lib/format.mjs +188 -0
- package/src/channels/lib/holidays.mjs +138 -0
- package/src/channels/lib/hook-pipe-server.mjs +802 -0
- package/src/channels/lib/interaction-workflows.mjs +184 -0
- package/src/channels/lib/memory-client.mjs +149 -0
- package/src/channels/lib/output-forwarder.mjs +765 -0
- package/src/channels/lib/runtime-paths.mjs +479 -0
- package/src/channels/lib/scheduler.mjs +723 -0
- package/src/channels/lib/session-control.mjs +36 -0
- package/src/channels/lib/session-discovery.mjs +103 -0
- package/src/channels/lib/settings.mjs +11 -0
- package/src/channels/lib/state-file.mjs +68 -0
- package/src/channels/lib/status-snapshot.mjs +219 -0
- package/src/channels/lib/tool-format.mjs +140 -0
- package/src/channels/lib/transcript-discovery.mjs +195 -0
- package/src/channels/lib/voice-runtime-fetcher.mjs +734 -0
- package/src/channels/lib/webhook.mjs +1179 -0
- package/src/channels/lib/whisper-server.mjs +477 -0
- package/src/channels/tool-defs.mjs +170 -0
- package/src/daemon/host.mjs +118 -0
- package/src/daemon/mcp-transport.mjs +47 -0
- package/src/daemon/session.mjs +100 -0
- package/src/daemon/thin-client.mjs +71 -0
- package/src/daemon/transport.mjs +163 -0
- package/src/memory/data/runtime-manifest.json +40 -0
- package/src/memory/index.mjs +3305 -0
- package/src/memory/lib/agent-ipc.mjs +93 -0
- package/src/memory/lib/bridge-trace-queries.mjs +120 -0
- package/src/memory/lib/core-memory-store.mjs +330 -0
- package/src/memory/lib/embedding-provider.mjs +269 -0
- package/src/memory/lib/embedding-worker.mjs +323 -0
- package/src/memory/lib/llm-worker-host.mjs +17 -0
- package/src/memory/lib/memory-cycle.mjs +11 -0
- package/src/memory/lib/memory-cycle1.mjs +641 -0
- package/src/memory/lib/memory-cycle2.mjs +1284 -0
- package/src/memory/lib/memory-cycle3.mjs +540 -0
- package/src/memory/lib/memory-embed.mjs +299 -0
- package/src/memory/lib/memory-extraction.mjs +5 -0
- package/src/memory/lib/memory-maintenance-store.mjs +32 -0
- package/src/memory/lib/memory-ops-policy.mjs +190 -0
- package/src/memory/lib/memory-recall-id-patch.mjs +15 -0
- package/src/memory/lib/memory-recall-read-query.mjs +7 -0
- package/src/memory/lib/memory-recall-scope-filter.mjs +63 -0
- package/src/memory/lib/memory-recall-store.mjs +621 -0
- package/src/memory/lib/memory-retrievers.mjs +112 -0
- package/src/memory/lib/memory-score.mjs +71 -0
- package/src/memory/lib/memory-text-utils.mjs +58 -0
- package/src/memory/lib/memory.mjs +412 -0
- package/src/memory/lib/model-profile.mjs +85 -0
- package/src/memory/lib/pg/adapter.mjs +308 -0
- package/src/memory/lib/pg/process.mjs +360 -0
- package/src/memory/lib/pg/supervisor.mjs +396 -0
- package/src/memory/lib/project-id-resolver.mjs +86 -0
- package/src/memory/lib/runtime-fetcher.mjs +442 -0
- package/src/memory/lib/trace-store.mjs +728 -0
- package/src/memory/tool-defs.mjs +79 -0
- package/src/search/index.mjs +1173 -0
- package/src/search/lib/backends/anthropic-oauth.mjs +98 -0
- package/src/search/lib/backends/exa.mjs +50 -0
- package/src/search/lib/backends/firecrawl.mjs +61 -0
- package/src/search/lib/backends/gemini-api.mjs +83 -0
- package/src/search/lib/backends/grok-oauth.mjs +86 -0
- package/src/search/lib/backends/index.mjs +150 -0
- package/src/search/lib/backends/openai-api.mjs +144 -0
- package/src/search/lib/backends/openai-oauth.mjs +98 -0
- package/src/search/lib/backends/openai-web-search.mjs +76 -0
- package/src/search/lib/backends/tavily.mjs +55 -0
- package/src/search/lib/backends/xai-api.mjs +113 -0
- package/src/search/lib/cache.mjs +131 -0
- package/src/search/lib/config.mjs +192 -0
- package/src/search/lib/formatter.mjs +115 -0
- package/src/search/lib/provider-usage.mjs +67 -0
- package/src/search/lib/providers.mjs +47 -0
- package/src/search/lib/search-intent.mjs +109 -0
- package/src/search/lib/setup-handler.mjs +261 -0
- package/src/search/lib/state.mjs +201 -0
- package/src/search/lib/web-tools.mjs +1207 -0
- package/src/search/tool-defs.mjs +83 -0
- package/src/setup/defender-exclusion.mjs +183 -0
- package/src/shared/abort-controller.mjs +15 -0
- package/src/shared/atomic-file.mjs +420 -0
- package/src/shared/config.mjs +350 -0
- package/src/shared/daemon-recycle.mjs +108 -0
- package/src/shared/disable-claude-builtins.mjs +88 -0
- package/src/shared/err-text.mjs +12 -0
- package/src/shared/llm/cost.mjs +66 -0
- package/src/shared/llm/http-agent.mjs +123 -0
- package/src/shared/llm/index.mjs +41 -0
- package/src/shared/llm/pid-cleanup.mjs +27 -0
- package/src/shared/llm/usage-log.mjs +47 -0
- package/src/shared/plugin-paths.mjs +58 -0
- package/src/shared/schedules-store.mjs +70 -0
- package/src/shared/seed.mjs +119 -0
- package/src/shared/user-cwd.mjs +213 -0
- package/src/shared/user-data-guard.mjs +238 -0
- package/src/status/aggregator.mjs +584 -0
- package/src/status/server.mjs +413 -0
- package/tools.json +1653 -0
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { resolvePluginData } from '../../shared/plugin-paths.mjs';
|
|
2
|
+
import { readSection, updateSection, getAgentApiKey } from '../../shared/config.mjs';
|
|
3
|
+
import { hasAnthropicOAuthCredentials } from './providers/anthropic-oauth.mjs';
|
|
4
|
+
import { hasOpenAIOAuthCredentials } from './providers/openai-oauth.mjs';
|
|
5
|
+
import { hasGrokOAuthCredentials } from './providers/grok-oauth.mjs';
|
|
6
|
+
|
|
7
|
+
// Thin wrapper around resolvePluginData so callers in this orchestrator tree
|
|
8
|
+
// can import a single helper without reaching into shared/.
|
|
9
|
+
export function getPluginData() {
|
|
10
|
+
return resolvePluginData();
|
|
11
|
+
}
|
|
12
|
+
const ENV_KEY_MAP = {
|
|
13
|
+
openai: 'OPENAI_API_KEY',
|
|
14
|
+
anthropic: 'ANTHROPIC_API_KEY',
|
|
15
|
+
gemini: 'GEMINI_API_KEY',
|
|
16
|
+
deepseek: 'DEEPSEEK_API_KEY',
|
|
17
|
+
xai: 'XAI_API_KEY',
|
|
18
|
+
nvidia: 'NVIDIA_API_KEY',
|
|
19
|
+
};
|
|
20
|
+
// Canonical maintenance defaults. Single source of truth — imported by
|
|
21
|
+
// llm/index.mjs and setup-server.mjs so UI/runtime cannot drift from config.
|
|
22
|
+
//
|
|
23
|
+
// Every hidden maintenance slot carries a CONCRETE preset here, so
|
|
24
|
+
// resolvePresetName() (bridge-llm) always resolves a model directly from
|
|
25
|
+
// `maint[slot]` — no shared `defaultPreset` fallback is needed or used.
|
|
26
|
+
// Memory cycles + Lead helper fan-out (explore/cycle1/cycle2/cycle3) and
|
|
27
|
+
// entry-driven dispatch (scheduler/webhook) all default to `haiku`.
|
|
28
|
+
// scheduler/webhook still let a per-entry config.json model win first (the
|
|
29
|
+
// caller passes it explicitly via opts.preset); the haiku default below only
|
|
30
|
+
// applies when an entry omits its own model.
|
|
31
|
+
export const DEFAULT_MAINTENANCE = Object.freeze({
|
|
32
|
+
explore: 'haiku',
|
|
33
|
+
cycle1: 'haiku',
|
|
34
|
+
cycle2: 'haiku',
|
|
35
|
+
cycle3: 'haiku',
|
|
36
|
+
scheduler: 'haiku',
|
|
37
|
+
webhook: 'haiku',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Slots surfaced as tunable rows in the Maintenance Setup panel. This is the
|
|
41
|
+
// UI / allow-list view (GET cleanup + POST validation) and is intentionally a
|
|
42
|
+
// SUBSET of DEFAULT_MAINTENANCE: scheduler/webhook carry a per-entry model and
|
|
43
|
+
// are not shown as shared rows, but still inherit the haiku default above when
|
|
44
|
+
// an entry omits its own model.
|
|
45
|
+
export const MAINTENANCE_SLOTS = Object.freeze(['explore', 'cycle1', 'cycle2', 'cycle3']);
|
|
46
|
+
|
|
47
|
+
// Map short Anthropic family labels to the full model ids used by the API.
|
|
48
|
+
// Honors ANTHROPIC_DEFAULT_{OPUS|SONNET|HAIKU}_MODEL env overrides.
|
|
49
|
+
const ANTHROPIC_FAMILY_MODEL = Object.freeze({
|
|
50
|
+
opus: 'claude-opus-4-8',
|
|
51
|
+
sonnet: 'claude-sonnet-4-6',
|
|
52
|
+
haiku: 'claude-haiku-4-5-20251001',
|
|
53
|
+
});
|
|
54
|
+
function resolveAnthropicFamilyModel(family) {
|
|
55
|
+
const key = String(family || '').toLowerCase();
|
|
56
|
+
if (!key) return null;
|
|
57
|
+
const envVar = `ANTHROPIC_DEFAULT_${key.toUpperCase()}_MODEL`;
|
|
58
|
+
if (process.env[envVar]) return process.env[envVar];
|
|
59
|
+
return ANTHROPIC_FAMILY_MODEL[key] || null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Seed presets keyed by preset.name so workflow/maintenance references stay
|
|
63
|
+
// consistent with the resolve-by-name lookup in presetKey().
|
|
64
|
+
export const DEFAULT_PRESETS = Object.freeze([
|
|
65
|
+
Object.freeze({ id: 'haiku', name: 'HAIKU', type: 'bridge', provider: 'anthropic-oauth', model: resolveAnthropicFamilyModel('haiku'), tools: 'full' }),
|
|
66
|
+
Object.freeze({ id: 'sonnet-mid', name: 'SONNET MID', type: 'bridge', provider: 'anthropic-oauth', model: resolveAnthropicFamilyModel('sonnet'), effort: 'medium', tools: 'full' }),
|
|
67
|
+
Object.freeze({ id: 'sonnet-high', name: 'SONNET HIGH', type: 'bridge', provider: 'anthropic-oauth', model: resolveAnthropicFamilyModel('sonnet'), effort: 'high', tools: 'full' }),
|
|
68
|
+
Object.freeze({ id: 'opus-mid', name: 'OPUS MID', type: 'bridge', provider: 'anthropic-oauth', model: resolveAnthropicFamilyModel('opus'), effort: 'medium', tools: 'full' }),
|
|
69
|
+
Object.freeze({ id: 'opus-high', name: 'OPUS HIGH', type: 'bridge', provider: 'anthropic-oauth', model: resolveAnthropicFamilyModel('opus'), effort: 'high', tools: 'full' }),
|
|
70
|
+
]);
|
|
71
|
+
function buildDefaultConfig() {
|
|
72
|
+
const providers = {};
|
|
73
|
+
// API providers — enabled if env key exists
|
|
74
|
+
for (const [name, envKey] of Object.entries(ENV_KEY_MAP)) {
|
|
75
|
+
const apiKey = process.env[envKey];
|
|
76
|
+
providers[name] = {
|
|
77
|
+
enabled: !!apiKey,
|
|
78
|
+
apiKey: apiKey || undefined,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// OAuth provider detection delegates to each provider module so the
|
|
82
|
+
// canonical credential loader (loadTokens / loadCredentials) is the
|
|
83
|
+
// single source of truth. WebSocket transport is on by default —
|
|
84
|
+
// measured ~96% cross-session cache hit with delta payloads. Users who
|
|
85
|
+
// need to force SSE (e.g. a corporate proxy blocking WSS) can set
|
|
86
|
+
// `websocket: false` in mixdog-config.json (agent.providers.openai-oauth).
|
|
87
|
+
providers['openai-oauth'] = { enabled: hasOpenAIOAuthCredentials(), websocket: true };
|
|
88
|
+
providers['anthropic-oauth'] = { enabled: hasAnthropicOAuthCredentials() };
|
|
89
|
+
// Grok CLI OAuth ("Grok Build"). Like the other OAuth entries it is not
|
|
90
|
+
// stored in mixdog-config.json — enabled at runtime from the presence of
|
|
91
|
+
// either token source (own store or ~/.grok/auth.json) via
|
|
92
|
+
// hasGrokOAuthCredentials().
|
|
93
|
+
providers['grok-oauth'] = { enabled: hasGrokOAuthCredentials() };
|
|
94
|
+
// Local providers — opt-in via setup UI after HTTP ping confirms server is running
|
|
95
|
+
providers.ollama = { enabled: false, baseURL: 'http://localhost:11434/v1' };
|
|
96
|
+
providers.lmstudio = { enabled: false, baseURL: 'http://localhost:1234/v1' };
|
|
97
|
+
return { providers };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function hasKeys(value) {
|
|
101
|
+
return !!value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length > 0;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Persist the agent section. `build` receives the section value read INSIDE
|
|
105
|
+
// the file lock (current on-disk state) and returns the full replacement.
|
|
106
|
+
// Building from `current` rather than a snapshot taken before the lock keeps
|
|
107
|
+
// the whole-section save linearizable: a concurrent writer (each Claude Code
|
|
108
|
+
// session runs its own server under MIXDOG_MULTI_INSTANCE) that lands between
|
|
109
|
+
// our read and write is rebased onto, not silently clobbered (lost-update).
|
|
110
|
+
function persistAgentConfig(build) {
|
|
111
|
+
updateSection('agent', (current) => build(hasKeys(current) ? current : {}));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function loadConfig() {
|
|
115
|
+
const sectionRaw = readSection('agent');
|
|
116
|
+
if (hasKeys(sectionRaw)) {
|
|
117
|
+
try {
|
|
118
|
+
let raw = sectionRaw;
|
|
119
|
+
if (raw.agent && raw.agent.providers) {
|
|
120
|
+
raw = raw.agent;
|
|
121
|
+
}
|
|
122
|
+
const defaults = buildDefaultConfig();
|
|
123
|
+
// Deep-merge provider subkeys: unknown per-provider values are
|
|
124
|
+
// preserved through save/load so future fields round-trip
|
|
125
|
+
// without schema updates here.
|
|
126
|
+
const mergedProviders = { ...defaults.providers };
|
|
127
|
+
if (raw.providers && typeof raw.providers === 'object') {
|
|
128
|
+
for (const [name, val] of Object.entries(raw.providers)) {
|
|
129
|
+
if (val && typeof val === 'object') {
|
|
130
|
+
mergedProviders[name] = { ...(mergedProviders[name] || {}), ...val };
|
|
131
|
+
} else {
|
|
132
|
+
mergedProviders[name] = val;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Provider API keys live in the OS keychain (std env / MIXDOG_AGENT_*
|
|
137
|
+
// -> keychain), never plaintext in config. Overlay them so the
|
|
138
|
+
// provider clients see config.apiKey populated.
|
|
139
|
+
for (const name of Object.keys(ENV_KEY_MAP)) {
|
|
140
|
+
const kc = getAgentApiKey(name);
|
|
141
|
+
if (kc) mergedProviders[name] = { ...(mergedProviders[name] || {}), apiKey: kc, enabled: true };
|
|
142
|
+
}
|
|
143
|
+
// Drop unknown maintenance keys (e.g. truly legacy slot names from
|
|
144
|
+
// pre-removal installs). Every valid slot — incl. scheduler/webhook —
|
|
145
|
+
// lives in DEFAULT_MAINTENANCE, so the allow-list below is the single
|
|
146
|
+
// ingress gate and unknown keys are dropped here.
|
|
147
|
+
const allowedMaintKeys = new Set([...Object.keys(DEFAULT_MAINTENANCE), ...MAINTENANCE_SLOTS]);
|
|
148
|
+
const rawMaint = {};
|
|
149
|
+
for (const [k, v] of Object.entries(raw.maintenance || {})) {
|
|
150
|
+
if (allowedMaintKeys.has(k)) rawMaint[k] = v;
|
|
151
|
+
}
|
|
152
|
+
// Self-ref guard: mcpServers.mixdog / mcpServers["trib-plugin"]
|
|
153
|
+
// would self-spawn through the in-process tool bridge. Strip on
|
|
154
|
+
// ingress so user-edited configs cannot brick the agent boot.
|
|
155
|
+
const mcpServers = (raw.mcpServers && typeof raw.mcpServers === 'object') ? { ...raw.mcpServers } : {};
|
|
156
|
+
if (mcpServers['mixdog'] || mcpServers['trib-plugin']) {
|
|
157
|
+
delete mcpServers['mixdog'];
|
|
158
|
+
delete mcpServers['trib-plugin'];
|
|
159
|
+
raw.mcpServers = mcpServers;
|
|
160
|
+
try {
|
|
161
|
+
// Rebase the self-ref strip onto the in-lock current so a
|
|
162
|
+
// concurrent writer's unrelated edits are not reverted by
|
|
163
|
+
// this read-time sanitize.
|
|
164
|
+
persistAgentConfig((current) => {
|
|
165
|
+
const cur = { ...current };
|
|
166
|
+
// Strip self-refs at the same level loadConfig reads
|
|
167
|
+
// mcpServers from: the legacy nested shape keeps them
|
|
168
|
+
// under cur.agent, the flat shape at top level. Cleaning
|
|
169
|
+
// only the top level would leave a nested config dirty
|
|
170
|
+
// on disk even though runtime is sanitized.
|
|
171
|
+
const target = (cur.agent && cur.agent.providers)
|
|
172
|
+
? (cur.agent = { ...cur.agent })
|
|
173
|
+
: cur;
|
|
174
|
+
const curMcp = (target.mcpServers && typeof target.mcpServers === 'object') ? { ...target.mcpServers } : {};
|
|
175
|
+
delete curMcp['mixdog'];
|
|
176
|
+
delete curMcp['trib-plugin'];
|
|
177
|
+
target.mcpServers = curMcp;
|
|
178
|
+
return cur;
|
|
179
|
+
});
|
|
180
|
+
} catch (err) {
|
|
181
|
+
process.stderr.write(`[config] persist sanitized config failed: ${err?.message}\n`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const rawPresets = Array.isArray(raw.presets) ? raw.presets : [];
|
|
185
|
+
const normalizedPresets = rawPresets.map(p => normalizePreset(p)).filter(Boolean);
|
|
186
|
+
return {
|
|
187
|
+
providers: mergedProviders,
|
|
188
|
+
mcpServers,
|
|
189
|
+
presets: normalizedPresets,
|
|
190
|
+
default: raw.default || null,
|
|
191
|
+
maintenance: { ...DEFAULT_MAINTENANCE, ...rawMaint },
|
|
192
|
+
agentMaintenance: { enabled: true, interval: '1h', ...raw.agentMaintenance },
|
|
193
|
+
trajectory: { enabled: true, ...raw.trajectory },
|
|
194
|
+
bridge: raw.bridge && typeof raw.bridge === 'object' ? raw.bridge : {},
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
catch { /* fall through */ }
|
|
198
|
+
}
|
|
199
|
+
const defaults = buildDefaultConfig();
|
|
200
|
+
return {
|
|
201
|
+
...defaults,
|
|
202
|
+
mcpServers: {},
|
|
203
|
+
presets: DEFAULT_PRESETS.map(p => ({ ...p })),
|
|
204
|
+
default: 'opus-high',
|
|
205
|
+
maintenance: { ...DEFAULT_MAINTENANCE },
|
|
206
|
+
agentMaintenance: { enabled: true, interval: '1h' },
|
|
207
|
+
trajectory: { enabled: true },
|
|
208
|
+
bridge: {},
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Atomically save the agent section in mixdog-config.json. Caller passes the
|
|
213
|
+
* full config object. Only persists mcpServers, presets, default, and user-set
|
|
214
|
+
* provider entries (enabled, baseURL) — defaults are recomputed on next load.
|
|
215
|
+
* apiKey is NEVER persisted: provider keys live only in the OS keychain, and
|
|
216
|
+
* loadConfig overlays them into memory, so they must be stripped on save or
|
|
217
|
+
* they would leak back into mixdog-config.json as plaintext.
|
|
218
|
+
*
|
|
219
|
+
* WARNING: whole-section overwrite. Managed fields (presets/default/mcpServers/
|
|
220
|
+
* maintenance/...) are replaced from the passed snapshot (last-writer-wins);
|
|
221
|
+
* only unmanaged keys are rebased on the in-lock current. Safe only for a
|
|
222
|
+
* caller holding a fresh full config. For a single-field change, patch in-lock
|
|
223
|
+
* via persistAgentConfig((current) => ({ ...current, <field> })) — see
|
|
224
|
+
* setDefaultPreset — so a concurrent instance's edits are not reverted.
|
|
225
|
+
*/
|
|
226
|
+
export function saveConfig(config) {
|
|
227
|
+
// Strip ephemeral defaults from providers but preserve any unknown
|
|
228
|
+
// per-provider subkey so future schema additions round-trip through the
|
|
229
|
+
// setup UI without changes here. apiKey is intentionally omitted —
|
|
230
|
+
// provider keys are keychain-only (loadConfig overlays them into memory;
|
|
231
|
+
// persisting would leak plaintext back into mixdog-config.json). It stays
|
|
232
|
+
// in KNOWN_PROVIDER_KEYS so the generic passthrough loop also skips it.
|
|
233
|
+
const KNOWN_PROVIDER_KEYS = new Set(['apiKey', 'enabled', 'baseURL']);
|
|
234
|
+
const persistedProviders = {};
|
|
235
|
+
if (config.providers) {
|
|
236
|
+
for (const [name, val] of Object.entries(config.providers)) {
|
|
237
|
+
if (!val || typeof val !== 'object') continue;
|
|
238
|
+
const slim = {};
|
|
239
|
+
if (typeof val.enabled === 'boolean') slim.enabled = val.enabled;
|
|
240
|
+
if (val.baseURL) slim.baseURL = val.baseURL;
|
|
241
|
+
for (const [k, v] of Object.entries(val)) {
|
|
242
|
+
if (KNOWN_PROVIDER_KEYS.has(k)) continue;
|
|
243
|
+
if (v === undefined) continue;
|
|
244
|
+
slim[k] = v;
|
|
245
|
+
}
|
|
246
|
+
if (Object.keys(slim).length)
|
|
247
|
+
persistedProviders[name] = slim;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Build the replacement from `existingRaw` — the section read INSIDE the
|
|
251
|
+
// file lock — not a snapshot taken before it, so unmanaged keys written by
|
|
252
|
+
// a concurrent instance survive the save (lost-update guard).
|
|
253
|
+
persistAgentConfig((existingRaw) => ({
|
|
254
|
+
...existingRaw,
|
|
255
|
+
guide: config.guide || existingRaw.guide || undefined,
|
|
256
|
+
providers: persistedProviders,
|
|
257
|
+
mcpServers: config.mcpServers || {},
|
|
258
|
+
presets: Array.isArray(config.presets) ? config.presets : [],
|
|
259
|
+
default: config.default || null,
|
|
260
|
+
maintenance: config.maintenance || {},
|
|
261
|
+
agentMaintenance: config.agentMaintenance || {},
|
|
262
|
+
trajectory: config.trajectory || {},
|
|
263
|
+
bridge: config.bridge || {},
|
|
264
|
+
}));
|
|
265
|
+
}
|
|
266
|
+
// --- Preset helpers ---
|
|
267
|
+
// preset shape: { id, name, type: 'bridge', provider, model, effort?, fast?, tools? }
|
|
268
|
+
const AGENT_PROVIDER_ALIASES = Object.freeze({
|
|
269
|
+
'openai-api': 'openai',
|
|
270
|
+
'gemini-api': 'gemini',
|
|
271
|
+
'xai-api': 'xai',
|
|
272
|
+
});
|
|
273
|
+
const FAST_CAPABLE_PRESET_PROVIDERS = new Set([
|
|
274
|
+
'anthropic',
|
|
275
|
+
'anthropic-oauth',
|
|
276
|
+
'openai',
|
|
277
|
+
'openai-oauth',
|
|
278
|
+
]);
|
|
279
|
+
function normalizeAgentProviderId(provider) {
|
|
280
|
+
const id = String(provider || '').trim();
|
|
281
|
+
return AGENT_PROVIDER_ALIASES[id] || id;
|
|
282
|
+
}
|
|
283
|
+
function presetKey(p) { return p?.id || p?.name || ''; }
|
|
284
|
+
function normalizePreset(preset) {
|
|
285
|
+
if (!preset || typeof preset !== 'object')
|
|
286
|
+
return null;
|
|
287
|
+
const id = String(preset.id || preset.name || '').trim();
|
|
288
|
+
const name = String(preset.name || preset.id || '').trim();
|
|
289
|
+
const model = String(preset.model || '').trim();
|
|
290
|
+
const provider = normalizeAgentProviderId(preset.provider);
|
|
291
|
+
if (!name || !model || !provider) return null;
|
|
292
|
+
const out = { id, name, type: 'bridge', provider, model };
|
|
293
|
+
if (preset.effort)
|
|
294
|
+
out.effort = String(preset.effort).trim();
|
|
295
|
+
if (preset.fast === true && FAST_CAPABLE_PRESET_PROVIDERS.has(provider))
|
|
296
|
+
out.fast = true;
|
|
297
|
+
out.tools = ['full', 'readonly', 'mcp'].includes(preset.tools) ? preset.tools : 'full';
|
|
298
|
+
return out;
|
|
299
|
+
}
|
|
300
|
+
export function getPreset(config, key) {
|
|
301
|
+
const presets = Array.isArray(config?.presets) ? config.presets : [];
|
|
302
|
+
if (key == null || key === '')
|
|
303
|
+
return null;
|
|
304
|
+
// Numeric → index
|
|
305
|
+
if (typeof key === 'number' || /^\d+$/.test(String(key))) {
|
|
306
|
+
const idx = Number(key);
|
|
307
|
+
return presets[idx] || null;
|
|
308
|
+
}
|
|
309
|
+
// String → name or id match
|
|
310
|
+
return presets.find(p => p && presetKey(p) === key) || null;
|
|
311
|
+
}
|
|
312
|
+
export function getDefaultPreset(config) {
|
|
313
|
+
if (!config?.default)
|
|
314
|
+
return null;
|
|
315
|
+
return getPreset(config, config.default);
|
|
316
|
+
}
|
|
317
|
+
export function listPresets(config) {
|
|
318
|
+
return Array.isArray(config?.presets) ? config.presets : [];
|
|
319
|
+
}
|
|
320
|
+
// --- Lane-scoped runtime spec ---
|
|
321
|
+
// Phase D-2: scopeKey is (role, provider, model), not (role, preset). Spec
|
|
322
|
+
// §4.5 calls for "at most one live session per Sub role × provider"; we
|
|
323
|
+
// widen provider to (provider, model) because two presets on the same
|
|
324
|
+
// provider that differ only in effort/fast should keep sharing a session
|
|
325
|
+
// (both cache shards are identical there), while swapping the model itself
|
|
326
|
+
// legitimately needs a fresh session (cache shard is model-specific). Two
|
|
327
|
+
// presets mapping to the same (provider, model) therefore collapse into
|
|
328
|
+
// one Bridge session, so opus-mid / opus-max no longer fragment the pool.
|
|
329
|
+
//
|
|
330
|
+
// bridge lane: "bridge:<agentId>:<provider>:<model>" — per Sub role
|
|
331
|
+
// other lane: "bridge:<provider>:<model>" — shared utility
|
|
332
|
+
export function resolveRuntimeSpec(preset, ctx) {
|
|
333
|
+
const lane = ctx.lane || 'bridge';
|
|
334
|
+
const provider = String(preset?.provider || '').trim() || 'unknown';
|
|
335
|
+
const model = String(preset?.model || '').trim() || '_';
|
|
336
|
+
let scopeKey;
|
|
337
|
+
if (lane === 'bridge') {
|
|
338
|
+
if (!ctx.agentId) throw new Error('bridge lane requires agentId');
|
|
339
|
+
scopeKey = `bridge:${ctx.agentId}:${provider}:${model}`;
|
|
340
|
+
} else {
|
|
341
|
+
scopeKey = `bridge:${provider}:${model}`;
|
|
342
|
+
}
|
|
343
|
+
return { lane, scopeKey, reuse: true, preset };
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export function setDefaultPreset(config, key) {
|
|
347
|
+
const preset = getPreset(config, key);
|
|
348
|
+
if (!preset)
|
|
349
|
+
throw new Error(`preset "${key}" not found`);
|
|
350
|
+
const nextDefault = presetKey(preset);
|
|
351
|
+
// Patch only `default` under the file lock. saveConfig(config) would
|
|
352
|
+
// rewrite the whole agent section from this possibly-stale snapshot and
|
|
353
|
+
// could revert a concurrent instance's preset edits; an in-lock single
|
|
354
|
+
// field patch cannot.
|
|
355
|
+
persistAgentConfig((current) => ({ ...current, default: nextDefault }));
|
|
356
|
+
config.default = nextDefault;
|
|
357
|
+
return preset;
|
|
358
|
+
}
|