mixdog 0.9.1 → 0.9.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/package.json +9 -1
- package/scripts/_bench-cwc.json +20 -0
- package/scripts/agent-loop-policy-test.mjs +37 -0
- package/scripts/agent-parallel-smoke.mjs +54 -10
- package/scripts/anthropic-maxtokens-test.mjs +119 -0
- package/scripts/background-task-meta-smoke.mjs +1 -1
- package/scripts/bench-run.mjs +262 -0
- package/scripts/build-tui.mjs +13 -1
- package/scripts/compact-smoke.mjs +12 -0
- package/scripts/compact-trigger-migration-smoke.mjs +67 -1
- package/scripts/explore-bench.mjs +124 -0
- package/scripts/hook-bus-test.mjs +191 -0
- package/scripts/ingest-pure-conversation-smoke.mjs +148 -0
- package/scripts/internal-comms-bench.mjs +727 -0
- package/scripts/internal-comms-smoke.mjs +75 -0
- package/scripts/lead-workflow-smoke.mjs +4 -4
- package/scripts/live-worker-smoke.mjs +9 -9
- package/scripts/output-style-bench.mjs +285 -0
- package/scripts/output-style-smoke.mjs +13 -10
- package/scripts/patch-replay.mjs +90 -0
- package/scripts/path-suffix-test.mjs +57 -0
- package/scripts/provider-stream-stall-test.mjs +276 -0
- package/scripts/provider-toolcall-test.mjs +599 -1
- package/scripts/recall-bench.mjs +207 -0
- package/scripts/routing-corpus.mjs +281 -0
- package/scripts/session-bench.mjs +1526 -0
- package/scripts/session-diag.mjs +595 -0
- package/scripts/task-bench.mjs +207 -0
- package/scripts/tool-failures.mjs +6 -6
- package/scripts/tool-smoke.mjs +310 -67
- package/scripts/toolcall-args-test.mjs +81 -0
- package/src/agents/debugger/AGENT.md +4 -4
- package/src/agents/heavy-worker/AGENT.md +20 -9
- package/src/agents/reviewer/AGENT.md +4 -4
- package/src/agents/worker/AGENT.md +17 -9
- package/src/app.mjs +10 -6
- package/src/defaults/{hidden-roles.json → agents.json} +7 -7
- package/src/examples/schedules/SCHEDULE.example.md +32 -0
- package/src/examples/webhooks/WEBHOOK.example.md +40 -0
- package/src/headless-role.mjs +14 -14
- package/src/help.mjs +1 -0
- package/src/lib/rules-builder.cjs +32 -54
- package/src/mixdog-session-runtime.mjs +1040 -2036
- package/src/output-styles/default.md +12 -7
- package/src/output-styles/minimal.md +25 -0
- package/src/output-styles/oneline.md +21 -0
- package/src/output-styles/simple.md +10 -9
- package/src/repl.mjs +17 -7
- package/src/rules/agent/00-common.md +7 -5
- package/src/rules/agent/30-explorer.md +8 -12
- package/src/rules/lead/01-general.md +3 -1
- package/src/rules/lead/lead-tool.md +13 -2
- package/src/rules/shared/01-tool.md +23 -12
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +90 -32
- package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +32 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +18 -6
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +23 -20
- package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +48 -14
- package/src/runtime/agent/orchestrator/agent-trace.mjs +87 -12
- package/src/runtime/agent/orchestrator/config.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +182 -67
- package/src/runtime/agent/orchestrator/{internal-roles.mjs → internal-agents.mjs} +72 -72
- package/src/runtime/agent/orchestrator/internal-tools.mjs +13 -26
- package/src/runtime/agent/orchestrator/mcp/client.mjs +100 -18
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +188 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-leaked-toolcall.mjs +444 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +93 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +313 -84
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +104 -38
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +28 -33
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +184 -17
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +8 -1
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +32 -0
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +18 -8
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +54 -20
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +227 -31
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +83 -6
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +229 -115
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +213 -33
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +49 -17
- package/src/runtime/agent/orchestrator/providers/registry.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +22 -17
- package/src/runtime/agent/orchestrator/session/compact.mjs +560 -51
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +250 -3
- package/src/runtime/agent/orchestrator/session/loop/compact-debug.mjs +28 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +262 -0
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +38 -0
- package/src/runtime/agent/orchestrator/session/loop/env.mjs +14 -0
- package/src/runtime/agent/orchestrator/session/loop/hidden-agents.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +49 -0
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +63 -0
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +52 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +218 -0
- package/src/runtime/agent/orchestrator/session/loop/transcript-repair.mjs +101 -0
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +35 -0
- package/src/runtime/agent/orchestrator/session/loop.mjs +513 -1000
- package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +227 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +235 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +137 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +155 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +303 -0
- package/src/runtime/agent/orchestrator/session/manager.mjs +232 -1152
- package/src/runtime/agent/orchestrator/session/store.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +61 -0
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +5 -0
- package/src/runtime/agent/orchestrator/stall-policy.mjs +63 -15
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +194 -24
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +143 -0
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +34 -18
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +241 -0
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +162 -0
- package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/list-formatting.mjs +10 -0
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +5 -4
- package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +42 -2
- package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +15 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +9 -44
- package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +14 -5
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +11 -4
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +10 -17
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +23 -2
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +50 -39
- package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/builtin/tool-output-limit.mjs +10 -0
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +70 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +303 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +43 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +382 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +497 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +295 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +158 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/lang-predicates.mjs +128 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.mjs +66 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +44 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1192 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +81 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +19 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +280 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +347 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +39 -4189
- package/src/runtime/agent/orchestrator/tools/patch.mjs +119 -5
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +1 -2
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +2 -4
- package/src/runtime/channels/backends/discord.mjs +99 -9
- package/src/runtime/channels/backends/telegram.mjs +501 -0
- package/src/runtime/channels/index.mjs +437 -1439
- package/src/runtime/channels/lib/boot-profile.mjs +23 -0
- package/src/runtime/channels/lib/config.mjs +54 -2
- package/src/runtime/channels/lib/crash-log.mjs +106 -0
- package/src/runtime/channels/lib/format.mjs +4 -2
- package/src/runtime/channels/lib/index-drop-trace.mjs +72 -0
- package/src/runtime/channels/lib/output-forwarder.mjs +88 -67
- package/src/runtime/channels/lib/runtime-paths.mjs +29 -0
- package/src/runtime/channels/lib/scheduler.mjs +1 -1
- package/src/runtime/channels/lib/telegram-format.mjs +280 -0
- package/src/runtime/channels/lib/tool-format.mjs +1 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +19 -1
- package/src/runtime/channels/lib/webhook.mjs +59 -31
- package/src/runtime/channels/lib/whisper-language.mjs +42 -0
- package/src/runtime/channels/tool-defs.mjs +1 -1
- package/src/runtime/memory/index.mjs +465 -345
- package/src/runtime/memory/lib/agent-ipc.mjs +2 -2
- package/src/runtime/memory/lib/core-memory-store.mjs +352 -2
- package/src/runtime/memory/lib/cycle-signatures.mjs +34 -0
- package/src/runtime/memory/lib/http-wire.mjs +57 -0
- package/src/runtime/memory/lib/memory-cycle1.mjs +1 -1
- package/src/runtime/memory/lib/memory-cycle2.mjs +65 -9
- package/src/runtime/memory/lib/memory-cycle3.mjs +1 -1
- package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +24 -0
- package/src/runtime/memory/lib/memory-retrievers.mjs +8 -0
- package/src/runtime/memory/lib/memory.mjs +121 -4
- package/src/runtime/memory/lib/pg/adapter.mjs +139 -15
- package/src/runtime/memory/lib/promotion-fingerprint.mjs +50 -0
- package/src/runtime/memory/lib/recall-format.mjs +183 -0
- package/src/runtime/memory/lib/session-ingest.mjs +107 -0
- package/src/runtime/memory/lib/trace-store.mjs +69 -22
- package/src/runtime/memory/tool-defs.mjs +10 -7
- package/src/runtime/shared/abort-controller.mjs +1 -1
- package/src/runtime/shared/background-tasks.mjs +2 -3
- package/src/runtime/shared/buffered-appender.mjs +149 -0
- package/src/runtime/shared/channel-notification-routing.mjs +12 -0
- package/src/runtime/shared/channel-notification-routing.test.mjs +45 -0
- package/src/runtime/shared/config.mjs +9 -0
- package/src/runtime/shared/llm/http-agent.mjs +12 -5
- package/src/runtime/shared/schedules-store.mjs +21 -19
- package/src/runtime/shared/task-notification-envelope.mjs +98 -0
- package/src/runtime/shared/task-notification-envelope.test.mjs +107 -0
- package/src/runtime/shared/tool-execution-contract.mjs +2 -2
- package/src/runtime/shared/tool-surface.mjs +98 -13
- package/src/runtime/shared/transcript-writer.mjs +156 -0
- package/src/runtime/shared/update-checker.mjs +214 -0
- package/src/session-runtime/config-helpers.mjs +209 -0
- package/src/session-runtime/effort.mjs +128 -0
- package/src/session-runtime/fs-utils.mjs +10 -0
- package/src/session-runtime/model-capabilities.mjs +130 -0
- package/src/session-runtime/output-styles.mjs +124 -0
- package/src/session-runtime/plugin-mcp.mjs +114 -0
- package/src/session-runtime/session-text.mjs +100 -0
- package/src/session-runtime/statusline-route.mjs +35 -0
- package/src/session-runtime/tool-catalog.mjs +720 -0
- package/src/session-runtime/workflow.mjs +358 -0
- package/src/standalone/agent-tool.mjs +302 -117
- package/src/standalone/channel-admin.mjs +133 -40
- package/src/standalone/channel-worker.mjs +10 -292
- package/src/standalone/explore-tool.mjs +12 -5
- package/src/standalone/hook-bus.mjs +165 -8
- package/src/standalone/memory-runtime-proxy.mjs +3 -1
- package/src/standalone/opencode-go-login.mjs +121 -0
- package/src/standalone/provider-admin.mjs +25 -3
- package/src/standalone/usage-dashboard.mjs +1 -1
- package/src/tui/App.jsx +2883 -778
- package/src/tui/components/ConfirmBar.jsx +47 -0
- package/src/tui/components/ContextPanel.jsx +5 -3
- package/src/tui/components/ItemRightHintOverprint.jsx +54 -0
- package/src/tui/components/Markdown.jsx +22 -98
- package/src/tui/components/Message.jsx +14 -35
- package/src/tui/components/Picker.jsx +87 -12
- package/src/tui/components/PromptInput.jsx +355 -22
- package/src/tui/components/QueuedCommands.jsx +1 -1
- package/src/tui/components/SlashCommandPalette.jsx +8 -5
- package/src/tui/components/Spinner.jsx +7 -7
- package/src/tui/components/StatusLine.jsx +40 -21
- package/src/tui/components/TextEntryPanel.jsx +51 -7
- package/src/tui/components/ToolExecution.jsx +183 -101
- package/src/tui/components/TurnDone.jsx +4 -4
- package/src/tui/components/UsagePanel.jsx +1 -1
- package/src/tui/components/tool-output-format.mjs +161 -23
- package/src/tui/components/tool-output-format.test.mjs +87 -0
- package/src/tui/display-width.mjs +69 -0
- package/src/tui/display-width.test.mjs +35 -0
- package/src/tui/dist/index.mjs +6731 -2333
- package/src/tui/engine/agent-envelope.mjs +296 -0
- package/src/tui/engine/boot-profile.mjs +21 -0
- package/src/tui/engine/labels.mjs +67 -0
- package/src/tui/engine/notice-text.mjs +112 -0
- package/src/tui/engine/queue-helpers.mjs +161 -0
- package/src/tui/engine/session-stats.mjs +46 -0
- package/src/tui/engine/tool-call-fields.mjs +23 -0
- package/src/tui/engine/tool-result-text.mjs +126 -0
- package/src/tui/engine.mjs +569 -948
- package/src/tui/index.jsx +117 -7
- package/src/tui/input-editing.mjs +58 -8
- package/src/tui/input-editing.selection.test.mjs +75 -0
- package/src/tui/keyboard-protocol.mjs +42 -0
- package/src/tui/lib/voice-recorder.mjs +469 -0
- package/src/tui/markdown/format-token.mjs +128 -76
- package/src/tui/markdown/format-token.test.mjs +61 -19
- package/src/tui/markdown/measure-rendered-rows.mjs +85 -0
- package/src/tui/markdown/render-ansi.test.mjs +1 -1
- package/src/tui/markdown/streaming-markdown.mjs +167 -0
- package/src/tui/markdown/streaming-markdown.test.mjs +70 -0
- package/src/tui/markdown/table-layout.mjs +9 -9
- package/src/tui/paste-attachments.mjs +36 -9
- package/src/tui/paste-fix.test.mjs +119 -0
- package/src/tui/prompt-history-store.mjs +129 -0
- package/src/tui/prompt-history-store.test.mjs +52 -0
- package/src/tui/statusline-ansi-bridge.test.mjs +3 -3
- package/src/tui/theme.mjs +41 -657
- package/src/tui/themes/base.mjs +86 -0
- package/src/tui/themes/basic.mjs +85 -0
- package/src/tui/themes/catppuccin.mjs +72 -0
- package/src/tui/themes/dracula.mjs +70 -0
- package/src/tui/themes/everforest.mjs +71 -0
- package/src/tui/themes/gruvbox.mjs +71 -0
- package/src/tui/themes/index.mjs +71 -0
- package/src/tui/themes/indigo.mjs +78 -0
- package/src/tui/themes/kanagawa.mjs +80 -0
- package/src/tui/themes/light.mjs +81 -0
- package/src/tui/themes/nord.mjs +72 -0
- package/src/tui/themes/onedark.mjs +16 -0
- package/src/tui/themes/rosepine.mjs +70 -0
- package/src/tui/themes/teal.mjs +80 -0
- package/src/tui/themes/tokyonight.mjs +79 -0
- package/src/tui/themes/utils.mjs +106 -0
- package/src/tui/themes/warm.mjs +79 -0
- package/src/tui/transcript-tool-failures.mjs +13 -2
- package/src/ui/markdown.mjs +1 -1
- package/src/ui/model-display.mjs +2 -2
- package/src/ui/statusline.mjs +75 -27
- package/src/vendor/statusline/bin/statusline-route.mjs +5 -12
- package/src/vendor/statusline/src/gateway/claude-current.mjs +3 -3
- package/src/vendor/statusline/src/gateway/route-meta.mjs +30 -16
- package/src/workflows/default/WORKFLOW.md +46 -12
- package/src/workflows/sequential/WORKFLOW.md +51 -0
- package/src/workflows/solo/WORKFLOW.md +12 -1
- package/vendor/ink/build/display-width.js +62 -0
- package/vendor/ink/build/ink.js +100 -12
- package/vendor/ink/build/measure-text.js +4 -1
- package/vendor/ink/build/output.js +115 -9
- package/vendor/ink/build/render-node-to-output.js +4 -1
- package/vendor/ink/build/render.js +4 -0
- package/src/output-styles/extreme-simple.md +0 -20
- package/src/rules/lead/04-workflow.md +0 -51
- package/src/workflows/default/workflow.json +0 -13
- package/src/workflows/solo/workflow.json +0 -7
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Internal hidden
|
|
2
|
+
* Internal hidden agents — Mixdog-managed, user-untouchable.
|
|
3
3
|
*
|
|
4
|
-
* Unlike public workflow agents, these hidden
|
|
4
|
+
* Unlike public workflow agents, these hidden agents are NEVER exposed to callers of the `agent` tool. They are
|
|
5
5
|
* invoked only by internal handlers (explore / recall / search) and carry
|
|
6
6
|
* their own system prompt + tool-set policy.
|
|
7
7
|
*
|
|
8
8
|
* Lookup order (agent-dispatch.resolvePresetName):
|
|
9
9
|
* 1. explicit preset arg
|
|
10
10
|
* 2. opts.preset
|
|
11
|
-
* 3. hidden-
|
|
11
|
+
* 3. hidden-agent registry (defaults/agents.json + systemFile frontmatter)
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Agent definitions live in defaults/agents.json and the referenced
|
|
14
14
|
* systemFile markdown frontmatter. Editing those files is a Mixdog source change.
|
|
15
15
|
*
|
|
16
16
|
* The preset names refer to entries seeded in mixdog-config.json (agent.presets)
|
|
17
17
|
* via DEFAULT_PRESETS (see config.mjs). If the user deletes the referenced preset
|
|
18
|
-
* from their config the hidden
|
|
18
|
+
* from their config the hidden agents degrade gracefully — `resolvePresetName`
|
|
19
19
|
* returns a name, but session creation will fail with a clear "preset not
|
|
20
20
|
* found" error rather than silently mis-dispatching.
|
|
21
21
|
*
|
|
22
22
|
* Kind classification:
|
|
23
|
-
* - 'retrieval' : short-lived hidden retrieval
|
|
24
|
-
* - 'maintenance' : background-trigger hidden
|
|
23
|
+
* - 'retrieval' : short-lived hidden retrieval agents (explore).
|
|
24
|
+
* - 'maintenance' : background-trigger hidden agents (memory cycle, scheduler,
|
|
25
25
|
* webhook). Receive only their own self section in BP2.
|
|
26
26
|
*
|
|
27
27
|
* Permission classification:
|
|
28
28
|
* - 'read' : read-only — apply_patch/shell blocked at loop.mjs runtime
|
|
29
|
-
* guard with the same error string public read-only
|
|
30
|
-
* - 'read-write' : full tool surface — used by hidden
|
|
29
|
+
* guard with the same error string public read-only agents see.
|
|
30
|
+
* - 'read-write' : full tool surface — used by hidden agents that legitimately
|
|
31
31
|
* mutate state (scheduler-task launches commands,
|
|
32
32
|
* webhook-handler persists payloads). agent-dispatch honors this
|
|
33
|
-
* declaratively instead of forcing every hidden
|
|
33
|
+
* declaratively instead of forcing every hidden agent to 'read'.
|
|
34
34
|
*
|
|
35
35
|
* Tool schema profile:
|
|
36
|
-
* - 'none' : no tools exposed; pure transform/classifier
|
|
36
|
+
* - 'none' : no tools exposed; pure transform/classifier agents.
|
|
37
37
|
* - 'read' : read/search/code-navigation tools only.
|
|
38
38
|
* - 'full' : shared agent tool schema for provider cache reuse.
|
|
39
39
|
*
|
|
40
|
-
*
|
|
40
|
+
* Agent-specific instruction metadata (consumed by rules-builder.cjs
|
|
41
41
|
* buildAgentRoleSpecificContent + collect.mjs):
|
|
42
|
-
* - inboundEvent :
|
|
42
|
+
* - inboundEvent : agent reports results back to Lead and must carry the
|
|
43
43
|
* skip-protocol rule (rules/agent/20-skip-protocol.md)
|
|
44
|
-
* in its BP2
|
|
44
|
+
* in its BP2 agent-rule block so no-op outputs opt out of the Lead
|
|
45
45
|
* inject.
|
|
46
46
|
* - instructionDir : DATA_DIR subdir whose *.md tree is folded into the
|
|
47
|
-
*
|
|
47
|
+
* agent's BP4-adjacent user/task data (webhook-handler →
|
|
48
48
|
* webhooks, scheduler-task → schedules).
|
|
49
49
|
*/
|
|
50
50
|
|
|
@@ -56,24 +56,24 @@ import {
|
|
|
56
56
|
parseMarkdownFrontmatter,
|
|
57
57
|
} from '../../shared/markdown-frontmatter.mjs'
|
|
58
58
|
|
|
59
|
-
// Resolve the path to defaults/
|
|
59
|
+
// Resolve the path to defaults/agents.json once.
|
|
60
60
|
const _MIXDOG_ROOT = mixdogRoot()
|
|
61
|
-
const
|
|
62
|
-
return join(_MIXDOG_ROOT, 'defaults', '
|
|
61
|
+
const _AGENTS_PATH = (() => {
|
|
62
|
+
return join(_MIXDOG_ROOT, 'defaults', 'agents.json')
|
|
63
63
|
})()
|
|
64
64
|
|
|
65
65
|
/** @type {{ mtime: number, map: object } | null} */
|
|
66
|
-
let
|
|
66
|
+
let _hiddenAgentsCache = null
|
|
67
67
|
|
|
68
68
|
function _mtimeSafe(file) {
|
|
69
69
|
try { return statSync(file).mtimeMs } catch { return 0 }
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
function
|
|
73
|
-
let mtime = _mtimeSafe(
|
|
72
|
+
function _hiddenAgentsDependencyMtime() {
|
|
73
|
+
let mtime = _mtimeSafe(_AGENTS_PATH)
|
|
74
74
|
try {
|
|
75
|
-
const raw = JSON.parse(readFileSync(
|
|
76
|
-
for (const entry of (raw.
|
|
75
|
+
const raw = JSON.parse(readFileSync(_AGENTS_PATH, 'utf8'))
|
|
76
|
+
for (const entry of (raw.agents || [])) {
|
|
77
77
|
const systemFile = typeof entry?.systemFile === 'string' ? entry.systemFile.trim() : ''
|
|
78
78
|
if (!systemFile) continue
|
|
79
79
|
mtime = Math.max(mtime, _mtimeSafe(join(_MIXDOG_ROOT, systemFile)))
|
|
@@ -82,7 +82,7 @@ function _hiddenRolesDependencyMtime() {
|
|
|
82
82
|
return mtime
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
function
|
|
85
|
+
function _loadHiddenAgentFrontmatter(systemFile) {
|
|
86
86
|
const rel = typeof systemFile === 'string' ? systemFile.trim() : ''
|
|
87
87
|
if (!rel) return {}
|
|
88
88
|
try {
|
|
@@ -92,8 +92,8 @@ function _loadHiddenRoleFrontmatter(systemFile) {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
function
|
|
96
|
-
const fm =
|
|
95
|
+
function _mergeHiddenAgentFrontmatter(entry) {
|
|
96
|
+
const fm = _loadHiddenAgentFrontmatter(entry.systemFile)
|
|
97
97
|
const merged = { ...entry }
|
|
98
98
|
const permission = normalizeAgentPermissionOrNone(fm.permission)
|
|
99
99
|
if (permission) merged.permission = permission
|
|
@@ -111,62 +111,62 @@ function _mergeHiddenRoleFrontmatter(entry) {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
* Read and parse defaults/
|
|
114
|
+
* Read and parse defaults/agents.json. Throws on missing/malformed.
|
|
115
115
|
*/
|
|
116
|
-
function
|
|
116
|
+
function _loadHiddenAgents() {
|
|
117
117
|
try {
|
|
118
|
-
const raw = JSON.parse(readFileSync(
|
|
118
|
+
const raw = JSON.parse(readFileSync(_AGENTS_PATH, 'utf8'))
|
|
119
119
|
const map = Object.create(null)
|
|
120
|
-
for (const entry of (raw.
|
|
121
|
-
if (entry && entry.
|
|
120
|
+
for (const entry of (raw.agents || [])) {
|
|
121
|
+
if (entry && entry.agent) map[entry.agent] = Object.freeze(_mergeHiddenAgentFrontmatter(entry))
|
|
122
122
|
}
|
|
123
123
|
return Object.freeze(map)
|
|
124
124
|
} catch (err) {
|
|
125
|
-
// Fail loudly — a missing or malformed
|
|
126
|
-
throw new Error(`[internal-
|
|
125
|
+
// Fail loudly — a missing or malformed agents.json breaks dispatch.
|
|
126
|
+
throw new Error(`[internal-agents] failed to load defaults/agents.json: ${err.message}`)
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
/**
|
|
131
|
-
* Return the hidden-
|
|
131
|
+
* Return the hidden-agent map, re-reading from disk when the file mtime has
|
|
132
132
|
* changed since the last load. This ensures that BP2 cache rebuilds triggered
|
|
133
|
-
* by
|
|
133
|
+
* by an agents.json modification (tracked via maxMtimeRecursive in
|
|
134
134
|
* collect.mjs) consume fresh metadata in the same process.
|
|
135
135
|
*/
|
|
136
|
-
function
|
|
136
|
+
function _getHiddenAgents() {
|
|
137
137
|
try {
|
|
138
|
-
const mtime =
|
|
139
|
-
if (
|
|
140
|
-
return
|
|
138
|
+
const mtime = _hiddenAgentsDependencyMtime()
|
|
139
|
+
if (_hiddenAgentsCache && mtime <= _hiddenAgentsCache.mtime) {
|
|
140
|
+
return _hiddenAgentsCache.map
|
|
141
141
|
}
|
|
142
|
-
const map =
|
|
143
|
-
|
|
142
|
+
const map = _loadHiddenAgents()
|
|
143
|
+
_hiddenAgentsCache = { mtime, map }
|
|
144
144
|
return map
|
|
145
145
|
} catch (err) {
|
|
146
146
|
// Fail loudly — re-throw with a clear message. A cache hit is never used
|
|
147
147
|
// when statSync fails because the caller expects current data.
|
|
148
|
-
throw new Error(`[internal-
|
|
148
|
+
throw new Error(`[internal-agents] failed to load defaults/agents.json: ${err.message}`)
|
|
149
149
|
}
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
// Eager validate at module init so startup failures are immediate.
|
|
153
|
-
|
|
153
|
+
_getHiddenAgents()
|
|
154
154
|
|
|
155
155
|
/**
|
|
156
|
-
* Return the hidden-
|
|
156
|
+
* Return the hidden-agent definition, or null if the name is not internal.
|
|
157
157
|
*/
|
|
158
|
-
export function
|
|
158
|
+
export function getHiddenAgent(name) {
|
|
159
159
|
if (!name) return null
|
|
160
|
-
return
|
|
160
|
+
return _getHiddenAgents()[name] || null
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/**
|
|
164
|
-
* Resolve permission stamped on a agent session. Hidden
|
|
164
|
+
* Resolve permission stamped on a agent session. Hidden agents declared
|
|
165
165
|
* `permission: 'read'` are read-locked — caller opts cannot upgrade them.
|
|
166
166
|
* Other built-in permissions include `none`, `read-write`, `mcp`, and `full`.
|
|
167
167
|
*/
|
|
168
|
-
export function resolveAgentSessionPermission(
|
|
169
|
-
const hidden =
|
|
168
|
+
export function resolveAgentSessionPermission(agent, callerPermission) {
|
|
169
|
+
const hidden = getHiddenAgent(agent)
|
|
170
170
|
if (hidden && hidden.permission === 'read') return 'read'
|
|
171
171
|
if (callerPermission != null && callerPermission !== '') return callerPermission
|
|
172
172
|
if (hidden?.permission) return hidden.permission
|
|
@@ -176,61 +176,61 @@ export function resolveAgentSessionPermission(role, callerPermission) {
|
|
|
176
176
|
/**
|
|
177
177
|
* Boolean check — useful for branching inside agent-dispatch / session-manager.
|
|
178
178
|
*/
|
|
179
|
-
export function
|
|
179
|
+
export function isHiddenAgent(name) {
|
|
180
180
|
if (!name) return false
|
|
181
|
-
return Object.prototype.hasOwnProperty.call(
|
|
181
|
+
return Object.prototype.hasOwnProperty.call(_getHiddenAgents(), name)
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
/**
|
|
185
|
-
* List all hidden
|
|
186
|
-
* a user-defined
|
|
185
|
+
* List all hidden agent names. Used by diagnostics / setup UI guards to ensure
|
|
186
|
+
* a user-defined agent doesn't collide with an internal one.
|
|
187
187
|
*/
|
|
188
|
-
export function
|
|
189
|
-
return Object.keys(
|
|
188
|
+
export function listHiddenAgentNames() {
|
|
189
|
+
return Object.keys(_getHiddenAgents())
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
/**
|
|
193
|
-
* List hidden
|
|
194
|
-
* Consumed by collect.mjs to drive BP2
|
|
195
|
-
* instead of hard-coding
|
|
193
|
+
* List hidden agent names matching a given kind ('retrieval' | 'maintenance').
|
|
194
|
+
* Consumed by collect.mjs to drive BP2 agent-shard classification dynamically
|
|
195
|
+
* instead of hard-coding agent-name sets.
|
|
196
196
|
*/
|
|
197
|
-
export function
|
|
197
|
+
export function listHiddenAgentsByKind(kind) {
|
|
198
198
|
const out = []
|
|
199
|
-
for (const [name, def] of Object.entries(
|
|
199
|
+
for (const [name, def] of Object.entries(_getHiddenAgents())) {
|
|
200
200
|
if (def.kind === kind) out.push(name)
|
|
201
201
|
}
|
|
202
202
|
return out
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
|
-
* Return the agents/<name>.md sections a hidden
|
|
206
|
+
* Return the agents/<name>.md sections a hidden agent shares in its BP2 catalog
|
|
207
207
|
* (in addition to its own self section). Drives the explorer→worker cache
|
|
208
|
-
* alignment declaratively instead of a hard-coded
|
|
209
|
-
* collect.mjs. Returns [] when the
|
|
208
|
+
* alignment declaratively instead of a hard-coded agent-name branch in
|
|
209
|
+
* collect.mjs. Returns [] when the agent declares none.
|
|
210
210
|
*/
|
|
211
|
-
export function
|
|
212
|
-
const hidden =
|
|
211
|
+
export function getAgentCatalogShareAgents(name) {
|
|
212
|
+
const hidden = getHiddenAgent(name)
|
|
213
213
|
if (!hidden || !Array.isArray(hidden.catalogShareAgents)) return []
|
|
214
214
|
return hidden.catalogShareAgents.map((n) => String(n || '').trim()).filter(Boolean)
|
|
215
215
|
}
|
|
216
216
|
|
|
217
217
|
/**
|
|
218
|
-
* True when a hidden
|
|
219
|
-
* skip-protocol rule in its BP2
|
|
218
|
+
* True when a hidden agent reports results back to Lead and must carry the
|
|
219
|
+
* skip-protocol rule in its BP2 agent-rule block. Replaces the hard-coded
|
|
220
220
|
* INBOUND_EVENT_ROLES set in collect.mjs.
|
|
221
221
|
*/
|
|
222
|
-
export function
|
|
223
|
-
const hidden =
|
|
222
|
+
export function isInboundEventAgent(name) {
|
|
223
|
+
const hidden = getHiddenAgent(name)
|
|
224
224
|
return !!(hidden && hidden.inboundEvent === true)
|
|
225
225
|
}
|
|
226
226
|
|
|
227
227
|
/**
|
|
228
228
|
* Return the DATA_DIR subdir whose *.md tree rides as BP4-adjacent
|
|
229
|
-
* user/task data, or null when the
|
|
229
|
+
* user/task data, or null when the agent declares none. Replaces the
|
|
230
230
|
* webhook/scheduler ternary in rules-builder.cjs buildAgentRoleSpecificContent.
|
|
231
231
|
*/
|
|
232
|
-
export function
|
|
233
|
-
const hidden =
|
|
232
|
+
export function getAgentInstructionDir(name) {
|
|
233
|
+
const hidden = getHiddenAgent(name)
|
|
234
234
|
const dir = hidden && typeof hidden.instructionDir === 'string' ? hidden.instructionDir.trim() : ''
|
|
235
235
|
return dir || null
|
|
236
236
|
}
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
* no-tool role guard) — not a permission check. No gating is needed here.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
import { isToolEnvelope, makeToolEnvelope } from './session/tool-envelope.mjs';
|
|
19
|
+
|
|
18
20
|
let _executor = null;
|
|
19
21
|
let _tools = [];
|
|
20
22
|
let _names = new Set();
|
|
@@ -24,35 +26,14 @@ let _bootResolver = null;
|
|
|
24
26
|
const _bootPromise = new Promise((r) => { _bootResolver = r; });
|
|
25
27
|
export function markBootReady() { if (_bootReady) return; _bootReady = true; _bootResolver(); }
|
|
26
28
|
|
|
27
|
-
// Per-tool executor overrides. Populated by addInternalTools() for extra
|
|
28
|
-
// internal tools that bypass the main dispatch (tools.json + dispatchTool).
|
|
29
|
-
const _overrides = new Map();
|
|
30
|
-
|
|
31
29
|
export function setInternalToolsProvider({ executor, tools }) {
|
|
32
30
|
if (typeof executor !== 'function') throw new Error('internal-tools: executor must be a function');
|
|
33
31
|
_executor = executor;
|
|
34
32
|
const base = Array.isArray(tools) ? [...tools] : [];
|
|
35
|
-
// Re-registration (handleToolCall idempotent fallback) must preserve any
|
|
36
|
-
// override-backed tools previously registered via addInternalTools.
|
|
37
|
-
if (_overrides.size > 0) {
|
|
38
|
-
const baseNames = new Set(base.map(t => t?.name).filter(Boolean));
|
|
39
|
-
for (const [name] of _overrides) {
|
|
40
|
-
if (baseNames.has(name)) continue;
|
|
41
|
-
const existing = _tools.find(t => t?.name === name);
|
|
42
|
-
if (existing) base.push(existing);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
33
|
_tools = base;
|
|
46
34
|
_names = new Set(_tools.map(t => t?.name).filter(Boolean));
|
|
47
35
|
}
|
|
48
36
|
|
|
49
|
-
/**
|
|
50
|
-
* Register additional tools that aren't declared in tools.json — each comes
|
|
51
|
-
* with its own executor.
|
|
52
|
-
*
|
|
53
|
-
* Re-registration is idempotent; later calls overwrite earlier entries with
|
|
54
|
-
* the same name.
|
|
55
|
-
*/
|
|
56
37
|
export function getInternalTools() {
|
|
57
38
|
return _tools;
|
|
58
39
|
}
|
|
@@ -63,11 +44,6 @@ export function isInternalTool(name) {
|
|
|
63
44
|
|
|
64
45
|
export async function executeInternalTool(name, args, callerCtx = {}) {
|
|
65
46
|
if (!_names.has(name)) throw new Error(`internal-tools: "${name}" is not registered`);
|
|
66
|
-
const override = _overrides.get(name);
|
|
67
|
-
if (override) {
|
|
68
|
-
const result = await override(args ?? {}, callerCtx);
|
|
69
|
-
return _normalize(result);
|
|
70
|
-
}
|
|
71
47
|
if (!_executor) throw new Error(`internal-tools: executor not initialized (tool=${name})`);
|
|
72
48
|
const result = await _executor(name, args ?? {}, callerCtx);
|
|
73
49
|
return _normalize(result);
|
|
@@ -77,6 +53,17 @@ export async function executeInternalTool(name, args, callerCtx = {}) {
|
|
|
77
53
|
// plain string either way. Worker/module handlers return the MCP-shaped
|
|
78
54
|
// `{ content: [{type:'text', text}] }` envelope directly.
|
|
79
55
|
function _normalize(result) {
|
|
56
|
+
// General newMessages tool-result channel: a tool may return a
|
|
57
|
+
// `{ __toolEnvelope, result, newMessages }` envelope (e.g. Skill, whose
|
|
58
|
+
// body rides ONE injected user message). Preserve the envelope shape, only
|
|
59
|
+
// normalizing its inner `result` to a string, so the agent loop's central
|
|
60
|
+
// normalizeToolEnvelope still splits it into stub + injected user body.
|
|
61
|
+
// Without this guard the envelope object would fall through to
|
|
62
|
+
// JSON.stringify below and the loop would see the stringified envelope as
|
|
63
|
+
// the tool_result (body inlined + duplicated, no newMessages).
|
|
64
|
+
if (isToolEnvelope(result)) {
|
|
65
|
+
return makeToolEnvelope(_normalize(result.result), result.newMessages);
|
|
66
|
+
}
|
|
80
67
|
if (result && typeof result === 'object' && Array.isArray(result.content)) {
|
|
81
68
|
return result.content
|
|
82
69
|
.map((c) => (c?.type === 'text' ? c.text || '' : JSON.stringify(c)))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { readFileSync, existsSync, mkdirSync
|
|
1
|
+
import { readFileSync, existsSync, mkdirSync } from 'fs';
|
|
2
|
+
import { writeFile } from 'fs/promises';
|
|
2
3
|
import { join } from 'path';
|
|
3
4
|
import { tmpdir } from 'os';
|
|
4
5
|
import { randomUUID } from 'crypto';
|
|
@@ -37,13 +38,58 @@ async function loadMcpSdk() {
|
|
|
37
38
|
import('@modelcontextprotocol/sdk/client/index.js'),
|
|
38
39
|
import('@modelcontextprotocol/sdk/client/stdio.js'),
|
|
39
40
|
import('@modelcontextprotocol/sdk/client/streamableHttp.js'),
|
|
40
|
-
|
|
41
|
+
import('@modelcontextprotocol/sdk/client/sse.js'),
|
|
42
|
+
import('@modelcontextprotocol/sdk/client/websocket.js'),
|
|
43
|
+
]).then(([clientMod, stdioMod, httpMod, sseMod, wsMod]) => ({
|
|
41
44
|
Client: clientMod.Client,
|
|
42
45
|
StdioClientTransport: stdioMod.StdioClientTransport,
|
|
43
46
|
StreamableHTTPClientTransport: httpMod.StreamableHTTPClientTransport,
|
|
47
|
+
SSEClientTransport: sseMod.SSEClientTransport,
|
|
48
|
+
WebSocketClientTransport: wsMod.WebSocketClientTransport,
|
|
44
49
|
}));
|
|
45
50
|
return mcpSdkPromise;
|
|
46
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Expand `${VAR}` and `${env:VAR}` references in string values using the
|
|
54
|
+
* provided env map (defaults to process.env). Recurses into arrays/objects.
|
|
55
|
+
* Unknown vars expand to an empty string. No shell execution.
|
|
56
|
+
*/
|
|
57
|
+
export function expandEnvVars(value, env = process.env) {
|
|
58
|
+
if (typeof value === 'string') {
|
|
59
|
+
return value.replace(/\$\{(?:env:)?([A-Za-z_][A-Za-z0-9_]*)\}/g, (_m, name) => {
|
|
60
|
+
const v = env?.[name];
|
|
61
|
+
return v == null ? '' : String(v);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(value)) {
|
|
65
|
+
return value.map((v) => expandEnvVars(v, env));
|
|
66
|
+
}
|
|
67
|
+
if (value && typeof value === 'object') {
|
|
68
|
+
const out = {};
|
|
69
|
+
for (const [k, v] of Object.entries(value)) {
|
|
70
|
+
out[k] = expandEnvVars(v, env);
|
|
71
|
+
}
|
|
72
|
+
return out;
|
|
73
|
+
}
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Resolve the canonical transport kind for an MCP server config entry.
|
|
78
|
+
* Returns one of: 'autoDetect' | 'stdio' | 'http' | 'sse' | 'ws'.
|
|
79
|
+
* Throws when no transport can be determined.
|
|
80
|
+
*/
|
|
81
|
+
export function resolveMcpTransportKind(cfg) {
|
|
82
|
+
if (cfg?.autoDetect) return 'autoDetect';
|
|
83
|
+
if (cfg?.type != null && cfg.type !== '') {
|
|
84
|
+
let t = String(cfg.type).toLowerCase();
|
|
85
|
+
if (t === 'streamable-http' || t === 'streamablehttp') t = 'http';
|
|
86
|
+
if (t === 'stdio' || t === 'http' || t === 'sse' || t === 'ws') return t;
|
|
87
|
+
}
|
|
88
|
+
if (cfg?.transport === 'http') return 'http';
|
|
89
|
+
if (cfg?.command) return 'stdio';
|
|
90
|
+
if (cfg?.url) return 'http';
|
|
91
|
+
throw new Error(`Invalid config: need autoDetect, type (stdio/http/sse/ws), url (http), or command (stdio)`);
|
|
92
|
+
}
|
|
47
93
|
// --- Public API ---
|
|
48
94
|
/**
|
|
49
95
|
* Connect to MCP servers defined in config.
|
|
@@ -92,11 +138,13 @@ export function getMcpServerStatus() {
|
|
|
92
138
|
name: tool.name,
|
|
93
139
|
description: tool.description || '',
|
|
94
140
|
})),
|
|
95
|
-
transport:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
141
|
+
transport: (() => {
|
|
142
|
+
try {
|
|
143
|
+
return resolveMcpTransportKind(server.cfg);
|
|
144
|
+
} catch {
|
|
145
|
+
return 'stdio';
|
|
146
|
+
}
|
|
147
|
+
})(),
|
|
100
148
|
}));
|
|
101
149
|
}
|
|
102
150
|
/**
|
|
@@ -226,7 +274,10 @@ function capMcpOutput(content) {
|
|
|
226
274
|
const dir = join(tmpdir(), 'mixdog-mcp-output');
|
|
227
275
|
mkdirSync(dir, { recursive: true });
|
|
228
276
|
spillPath = join(dir, `mcp-${Date.now()}-${randomUUID().slice(0, 8)}.txt`);
|
|
229
|
-
|
|
277
|
+
// Fire-and-forget: the spill path is returned to the caller
|
|
278
|
+
// immediately (below) for later recovery; the write itself must not
|
|
279
|
+
// block this hot tool-result path.
|
|
280
|
+
writeFile(spillPath, s, 'utf-8').catch(() => { /* spill best-effort */ });
|
|
230
281
|
} catch { /* spill best-effort */ }
|
|
231
282
|
const spillNote = spillPath
|
|
232
283
|
? `\n\n... [full output spilled to ${spillPath}] ...`
|
|
@@ -275,11 +326,18 @@ export async function disconnectAll() {
|
|
|
275
326
|
_invalidateMcpToolFieldMemo();
|
|
276
327
|
}
|
|
277
328
|
async function connectServer(name, cfg) {
|
|
278
|
-
const {
|
|
329
|
+
const {
|
|
330
|
+
Client,
|
|
331
|
+
StdioClientTransport,
|
|
332
|
+
StreamableHTTPClientTransport,
|
|
333
|
+
SSEClientTransport,
|
|
334
|
+
WebSocketClientTransport,
|
|
335
|
+
} = await loadMcpSdk();
|
|
279
336
|
const client = new Client({ name: `mixdog-agent/${name}`, version: '1.0.0' });
|
|
280
337
|
let transport;
|
|
338
|
+
const kind = resolveMcpTransportKind(cfg);
|
|
281
339
|
// Auto-detect: read port from a running service's port file
|
|
282
|
-
if (
|
|
340
|
+
if (kind === 'autoDetect') {
|
|
283
341
|
const spec = AUTO_DETECT_PORTS[cfg.autoDetect];
|
|
284
342
|
if (!spec)
|
|
285
343
|
throw new Error(`Unknown autoDetect target: "${cfg.autoDetect}"`);
|
|
@@ -314,16 +372,40 @@ async function connectServer(name, cfg) {
|
|
|
314
372
|
transport = new StreamableHTTPClientTransport(new URL(url));
|
|
315
373
|
mcpLog(`[mcp-client] Connecting "${name}" via autoDetect HTTP: ${url}\n`);
|
|
316
374
|
}
|
|
317
|
-
else if (
|
|
318
|
-
|
|
319
|
-
|
|
375
|
+
else if (kind === 'http') {
|
|
376
|
+
const url = expandEnvVars(String(cfg.url ?? ''));
|
|
377
|
+
const headers = expandEnvVars(cfg.headers && typeof cfg.headers === 'object' ? cfg.headers : {});
|
|
378
|
+
const opts = (headers && Object.keys(headers).length > 0)
|
|
379
|
+
? { requestInit: { headers } }
|
|
380
|
+
: undefined;
|
|
381
|
+
transport = opts
|
|
382
|
+
? new StreamableHTTPClientTransport(new URL(url), opts)
|
|
383
|
+
: new StreamableHTTPClientTransport(new URL(url));
|
|
384
|
+
mcpLog(`[mcp-client] Connecting "${name}" via HTTP: ${url}\n`);
|
|
385
|
+
}
|
|
386
|
+
else if (kind === 'sse') {
|
|
387
|
+
const url = expandEnvVars(String(cfg.url ?? ''));
|
|
388
|
+
const headers = expandEnvVars(cfg.headers && typeof cfg.headers === 'object' ? cfg.headers : {});
|
|
389
|
+
const opts = (headers && Object.keys(headers).length > 0)
|
|
390
|
+
? { requestInit: { headers } }
|
|
391
|
+
: undefined;
|
|
392
|
+
transport = opts
|
|
393
|
+
? new SSEClientTransport(new URL(url), opts)
|
|
394
|
+
: new SSEClientTransport(new URL(url));
|
|
395
|
+
mcpLog(`[mcp-client] Connecting "${name}" via SSE: ${url}\n`);
|
|
396
|
+
}
|
|
397
|
+
else if (kind === 'ws') {
|
|
398
|
+
// WebSocketClientTransport ctor takes only a URL; headers are ignored.
|
|
399
|
+
const url = expandEnvVars(String(cfg.url ?? ''));
|
|
400
|
+
transport = new WebSocketClientTransport(new URL(url));
|
|
401
|
+
mcpLog(`[mcp-client] Connecting "${name}" via WebSocket: ${url}\n`);
|
|
320
402
|
}
|
|
321
|
-
else if (
|
|
403
|
+
else if (kind === 'stdio') {
|
|
322
404
|
transport = new StdioClientTransport({
|
|
323
|
-
command: cfg.command,
|
|
324
|
-
args: cfg.args,
|
|
405
|
+
command: expandEnvVars(String(cfg.command ?? '')),
|
|
406
|
+
args: Array.isArray(cfg.args) ? expandEnvVars(cfg.args) : cfg.args,
|
|
325
407
|
cwd: cfg.cwd,
|
|
326
|
-
env: { ...process.env, ...cfg.env },
|
|
408
|
+
env: { ...process.env, ...expandEnvVars(cfg.env && typeof cfg.env === 'object' ? cfg.env : {}) },
|
|
327
409
|
stderr: cfg.stderr ?? 'pipe',
|
|
328
410
|
});
|
|
329
411
|
transport.stderr?.on?.('data', (chunk) => {
|
|
@@ -331,7 +413,7 @@ async function connectServer(name, cfg) {
|
|
|
331
413
|
});
|
|
332
414
|
}
|
|
333
415
|
else {
|
|
334
|
-
throw new Error(`Invalid config for "${name}": need autoDetect, url (http), or command (stdio)`);
|
|
416
|
+
throw new Error(`Invalid config for "${name}": need autoDetect, type (stdio/http/sse/ws), url (http), or command (stdio)`);
|
|
335
417
|
}
|
|
336
418
|
await client.connect(transport);
|
|
337
419
|
const toolsResult = await client.listTools();
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { EFFORT_BETA_HEADER } from './anthropic-effort.mjs';
|
|
2
|
+
|
|
1
3
|
export const EXTENDED_CACHE_TTL_BETA_HEADER = 'extended-cache-ttl-2025-04-11';
|
|
2
4
|
export const INTERLEAVED_THINKING_BETA_HEADER = 'interleaved-thinking-2025-05-14';
|
|
3
5
|
export const FAST_MODE_BETA_HEADER = 'fast-mode-2026-02-01';
|
|
4
6
|
export const TOOL_SEARCH_BETA_HEADER = 'advanced-tool-use-2025-11-20';
|
|
7
|
+
export { EFFORT_BETA_HEADER };
|
|
5
8
|
|
|
6
9
|
export function supportsAnthropicFastMode(model) {
|
|
7
10
|
const id = String(model || '').toLowerCase().replace(/\./g, '-');
|
|
@@ -12,6 +15,7 @@ export function buildAnthropicBetaHeaders({
|
|
|
12
15
|
base = `${INTERLEAVED_THINKING_BETA_HEADER},${EXTENDED_CACHE_TTL_BETA_HEADER}`,
|
|
13
16
|
fastMode = false,
|
|
14
17
|
toolSearch = false,
|
|
18
|
+
effort = false,
|
|
15
19
|
} = {}) {
|
|
16
20
|
const headers = String(base || '')
|
|
17
21
|
.split(',')
|
|
@@ -23,5 +27,8 @@ export function buildAnthropicBetaHeaders({
|
|
|
23
27
|
if (toolSearch && !headers.includes(TOOL_SEARCH_BETA_HEADER)) {
|
|
24
28
|
headers.push(TOOL_SEARCH_BETA_HEADER);
|
|
25
29
|
}
|
|
30
|
+
if (effort && !headers.includes(EFFORT_BETA_HEADER)) {
|
|
31
|
+
headers.push(EFFORT_BETA_HEADER);
|
|
32
|
+
}
|
|
26
33
|
return headers.join(',');
|
|
27
34
|
}
|