mixdog 1.2.1 → 1.2.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 +18 -0
- package/package.json +2 -1
- package/scripts/gate-local.mjs +19 -3
- package/scripts/model-catalog-audit.mjs +1 -15
- package/scripts/provider-pingpong-live.mjs +509 -0
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- package/src/agents/reviewer/AGENT.md +3 -3
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +6 -0
- package/src/defaults/skills/setup/SKILL.md +6 -1
- package/src/defaults/skills/setup/references/actions.md +44 -22
- package/src/defaults/skills/setup/references/surfaces.md +10 -8
- package/src/headless-exec.mjs +15 -8
- package/src/lib/keychain-cjs.cjs +7 -4
- package/src/output-styles/common.md +11 -10
- package/src/repl/slash-commands.mjs +16 -1
- package/src/rules/agent/AGENT.md +5 -5
- package/src/rules/lead/LEAD.md +5 -5
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
- package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
- package/src/runtime/agent/orchestrator/config.mjs +5 -0
- package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
- package/src/runtime/agent/orchestrator/mcp/client-config.mjs +36 -7
- package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +49 -10
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +40 -3
- package/src/runtime/agent/orchestrator/mcp/client.mjs +230 -96
- package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
- package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
- package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +188 -29
- package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +98 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +48 -37
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +10 -7
- package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +102 -45
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +40 -7
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +88 -21
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +106 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +94 -15
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
- package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +75 -10
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +103 -23
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +27 -3
- package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
- package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
- package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
- package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +80 -18
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +46 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +273 -0
- package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
- package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +369 -112
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +140 -35
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +70 -24
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +80 -29
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +69 -19
- package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
- package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
- package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
- package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
- package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
- package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
- package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
- package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +123 -61
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +27 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
- package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +64 -23
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +79 -33
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +144 -15
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +9 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +109 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +27 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +34 -20
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +37 -28
- package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +43 -15
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +7 -3
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +37 -4
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +76 -33
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
- package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
- package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
- package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
- package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
- package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +41 -22
- package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
- package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
- package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +720 -0
- package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +123 -219
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
- package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
- package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
- package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
- package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
- package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
- package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
- package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
- package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -97
- package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
- package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
- package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
- package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
- package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
- package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
- package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
- package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
- package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
- package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
- package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +104 -19
- package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +30 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +57 -21
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +5 -10
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +16 -4
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
- package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
- package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +168 -29
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
- package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
- package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
- package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
- package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
- package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +13 -1
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
- package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +20 -1
- package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
- package/src/runtime/computer-bridge/action-schema.mjs +44 -21
- package/src/runtime/github/tool.mjs +92 -2
- package/src/runtime/memory/index.mjs +1 -0
- package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
- package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
- package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
- package/src/runtime/memory/lib/pg/process.mjs +65 -50
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +124 -16
- package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
- package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
- package/src/runtime/office/README.md +2 -2
- package/src/runtime/office/authoring/html-document-author.mjs +2 -0
- package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
- package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
- package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
- package/src/runtime/office/core/office-actions-read.mjs +3 -0
- package/src/runtime/office/core/office-render-preview.mjs +2 -0
- package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
- package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
- package/src/runtime/office/core/office-sessions.mjs +5 -0
- package/src/runtime/office/core/office-transactions.mjs +3 -0
- package/src/runtime/office/core/office-write-ledger.mjs +98 -0
- package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
- package/src/runtime/office/index.mjs +30 -0
- package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
- package/src/runtime/office/pdf/pdf-render.mjs +23 -7
- package/src/runtime/office/pdf/pdf-security.mjs +2 -0
- package/src/runtime/office/portable/portable-opc.mjs +4 -1
- package/src/runtime/office/quality/visual-diff.mjs +2 -0
- package/src/runtime/office/shared/values.mjs +0 -5
- package/src/runtime/shared/background-tasks.mjs +92 -14
- package/src/runtime/shared/bounded-file-read.mjs +13 -0
- package/src/runtime/shared/bounded-line-diff.mjs +182 -0
- package/src/runtime/shared/buffered-appender.mjs +18 -0
- package/src/runtime/shared/config.mjs +78 -18
- package/src/runtime/shared/err-text.mjs +31 -0
- package/src/runtime/shared/error-presentation.mjs +159 -19
- package/src/runtime/shared/file-permissions.d.mts +6 -1
- package/src/runtime/shared/file-permissions.mjs +54 -6
- package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
- package/src/runtime/shared/llm/anthropic-effort.mjs +129 -134
- package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
- package/src/runtime/shared/llm/model-catalog.mjs +53 -40
- package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
- package/src/runtime/shared/llm/provider-catalog-registry.mjs +11 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
- package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
- package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
- package/src/runtime/shared/loopback-listener.mjs +9 -0
- package/src/runtime/shared/model-display.mjs +13 -0
- package/src/runtime/shared/provider-api-key.mjs +2 -0
- package/src/runtime/shared/quota-resume-store.mjs +11 -0
- package/src/runtime/shared/review-diff.mjs +52 -0
- package/src/runtime/shared/session-baseline-store.mjs +960 -0
- package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
- package/src/runtime/shared/session-sidebar-host.mjs +38 -0
- package/src/runtime/shared/slow-span.mjs +114 -0
- package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
- package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
- package/src/runtime/shared/task-notification-envelope.mjs +2 -2
- package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
- package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
- package/src/runtime/shared/tool-card-model.mjs +5 -2
- package/src/runtime/shared/tool-output-limit.mjs +4 -0
- package/src/runtime/shared/tool-primitives.mjs +13 -0
- package/src/runtime/shared/tool-result-summary.mjs +8 -1
- package/src/runtime/shared/tool-surface.mjs +18 -3
- package/src/runtime/shared/tool-work-units.mjs +40 -4
- package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
- package/src/runtime/shared/transcript-writer.mjs +10 -2
- package/src/runtime/shared/turn-changes.mjs +670 -274
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +94 -2
- package/src/runtime/shared/turn-snapshot.mjs +986 -690
- package/src/runtime/shared/turn-worktree-snapshot.mjs +279 -262
- package/src/runtime/shared/user-data-guard.mjs +262 -49
- package/src/runtime/shared/worktrees/carry.mjs +531 -0
- package/src/runtime/shared/worktrees/contract.mjs +34 -24
- package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
- package/src/runtime/shared/worktrees/git-head.mjs +205 -0
- package/src/runtime/shared/worktrees/git.mjs +8 -3
- package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
- package/src/runtime/shared/worktrees/manager.mjs +156 -8
- package/src/runtime/shared/worktrees/merge.mjs +31 -21
- package/src/runtime/shared/worktrees/paths.d.mts +6 -0
- package/src/runtime/shared/worktrees/test-support.mjs +19 -4
- package/src/runtime/terminal-bridge/client.mjs +44 -11
- package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
- package/src/runtime/tidy/apply.mjs +47 -2
- package/src/runtime/tidy/run-engines.mjs +11 -5
- package/src/session-runtime/agent-tool-routing.mjs +19 -13
- package/src/session-runtime/boot/apis.mjs +19 -5
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +12 -1
- package/src/session-runtime/boot/session.mjs +0 -1
- package/src/session-runtime/boot/tools.mjs +4 -1
- package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
- package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
- package/src/session-runtime/internal-tool-executor.mjs +6 -2
- package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
- package/src/session-runtime/lifecycle/session-catalog.mjs +14 -3
- package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
- package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
- package/src/session-runtime/lifecycle/teardown.mjs +73 -8
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +46 -14
- package/src/session-runtime/mcp-glue/server-catalog.mjs +20 -3
- package/src/session-runtime/mcp-glue.mjs +3 -0
- package/src/session-runtime/mcp-oauth-login.mjs +174 -0
- package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
- package/src/session-runtime/model-route/set-route.mjs +85 -17
- package/src/session-runtime/model-route/web-search-route.mjs +1 -1
- package/src/session-runtime/native-web-search/routes.mjs +22 -3
- package/src/session-runtime/native-web-search-usage.mjs +51 -0
- package/src/session-runtime/native-web-search.mjs +10 -1
- package/src/session-runtime/new-session-config.mjs +4 -2
- package/src/session-runtime/provider-auth/login.mjs +4 -0
- package/src/session-runtime/provider-models/model-meta.mjs +12 -3
- package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
- package/src/session-runtime/quick-web-search-models.mjs +13 -38
- package/src/session-runtime/resource-extension-sync.mjs +4 -0
- package/src/session-runtime/resource-mcp-api.mjs +98 -2
- package/src/session-runtime/resource-scope-decorate.mjs +10 -3
- package/src/session-runtime/runtime-review-api.mjs +21 -2
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
- package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
- package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
- package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
- package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
- package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
- package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
- package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
- package/src/session-runtime/services/agent-tool.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +19 -3
- package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
- package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
- package/src/session-runtime/services/provider-admin.mjs +81 -15
- package/src/session-runtime/session-transcript-purge.mjs +32 -0
- package/src/session-runtime/session-turn-api.mjs +14 -5
- package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
- package/src/session-runtime/settings-compaction-api.mjs +1 -0
- package/src/session-runtime/setup-tool/executor.mjs +36 -6
- package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
- package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
- package/src/session-runtime/skills-api.mjs +3 -5
- package/src/session-runtime/tool-surface.mjs +5 -1
- package/src/session-runtime/turn/compaction-gate.mjs +25 -0
- package/src/session-runtime/turn/session-ops.mjs +7 -5
- package/src/session-runtime/turn/side-question-ops.mjs +22 -0
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
- package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +25 -9
- package/src/session-runtime/usage-stats-api.mjs +43 -11
- package/src/session-runtime/workspace/project-branches.mjs +7 -5
- package/src/session-runtime/workspace/transition-steps.mjs +129 -31
- package/src/session-runtime/workspace/transitions.mjs +190 -15
- package/src/standalone/daemon-agent-control.mjs +9 -1
- package/src/standalone/daemon-drain-policy.mjs +8 -0
- package/src/standalone/daemon-local-session-bridge.mjs +14 -1
- package/src/standalone/daemon-owner.mjs +17 -4
- package/src/standalone/daemon-pg-stop.mjs +51 -0
- package/src/standalone/daemon-stop-budget.d.mts +2 -0
- package/src/standalone/daemon-stop-budget.mjs +18 -0
- package/src/standalone/daemon-stored-session-views.mjs +2 -0
- package/src/standalone/daemon-telemetry.mjs +74 -0
- package/src/standalone/daemon.mjs +64 -8
- package/src/standalone/desktop-service-registry.mjs +5 -0
- package/src/standalone/local-session-runtime.mjs +70 -19
- package/src/standalone/session-client.mjs +42 -0
- package/src/standalone/session-protocol.mjs +14 -0
- package/src/standalone/session-proxy/projection.mjs +41 -4
- package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
- package/src/standalone/session-runtime-inline-host.mjs +1 -0
- package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
- package/src/standalone/session-service/agent-tree.mjs +12 -0
- package/src/standalone/session-service/quota-resume.mjs +8 -0
- package/src/standalone/session-service/retention/busy.mjs +15 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
- package/src/standalone/session-service-api.mjs +11 -1
- package/src/standalone/session-service.mjs +1 -0
- package/src/standalone/session-state-patch.d.mts +2 -1
- package/src/standalone/session-state-patch.mjs +41 -1
- package/src/tui/App.jsx +25 -0
- package/src/tui/app/app-view/floating-panel.jsx +26 -1
- package/src/tui/app/app-view.jsx +1 -0
- package/src/tui/app/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +6 -0
- package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
- package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
- package/src/tui/app/extension-pickers.mjs +2 -1
- package/src/tui/app/model-options.mjs +11 -16
- package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
- package/src/tui/app/shell-layout/surfaces.mjs +3 -1
- package/src/tui/app/slash-commands.mjs +20 -5
- package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
- package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
- package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
- package/src/tui/app/use-global-key-input.mjs +5 -12
- package/src/tui/app/use-prompt-handlers.mjs +11 -0
- package/src/tui/components/BtwPanel.jsx +53 -0
- package/src/tui/components/QuestionPanel.jsx +275 -0
- package/src/tui/components/StatusLine.jsx +2 -0
- package/src/tui/components/question-panel-model.mjs +156 -0
- package/src/tui/components/status-line/local-line.mjs +5 -2
- package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
- package/src/tui/dist/index.mjs +3221 -1500
- package/src/tui/session/context-state.mjs +4 -2
- package/src/tui/session/quota-resume.mjs +46 -14
- package/src/tui/session/session-api/commands.mjs +43 -24
- package/src/tui/session/session-api/controls.mjs +2 -2
- package/src/tui/session/session-api/extensions.mjs +22 -0
- package/src/tui/session/session-api/integrations.mjs +16 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +7 -2
- package/src/tui/session/session-api/routes.mjs +71 -7
- package/src/tui/session/session-api/settings.mjs +11 -14
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/session-flow/drain.mjs +7 -1
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
- package/src/tui/session/tool-approval.mjs +10 -7
- package/src/tui/session/transcript-spill.mjs +14 -7
- package/src/tui/session/turn-stream.mjs +174 -31
- package/src/tui/session/turn.mjs +46 -16
- package/src/tui/statusline-ansi-bridge.mjs +1 -1
- package/src/ui/statusline-agents.mjs +15 -4
- package/src/ui/statusline.mjs +7 -3
- package/src/ui/streaming-markdown-heal.mjs +34 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
- package/src/workflows/default/WORKFLOW.md +3 -1
- package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
- package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// Shared by xai-tool-search.test.mjs and the one-off generator that produced
|
|
2
|
+
// xai-tool-search-head-parity.json by running these same captures against the
|
|
3
|
+
// pre-change xAI send path. The WebSocket transport is driven through the real
|
|
4
|
+
// sendViaWebSocket with a scripted socket, so the real stream collector and
|
|
5
|
+
// delta framing run; only the connection is replaced.
|
|
6
|
+
import { mock } from 'node:test';
|
|
7
|
+
import { EventEmitter } from 'node:events';
|
|
8
|
+
import * as realWs from './openai-oauth-ws.mjs';
|
|
9
|
+
|
|
10
|
+
export const ws = { bodies: [], frames: [], scripts: [] };
|
|
11
|
+
|
|
12
|
+
function scriptedEntry() {
|
|
13
|
+
const socket = new EventEmitter();
|
|
14
|
+
socket.readyState = 1;
|
|
15
|
+
socket.close = () => {
|
|
16
|
+
socket.readyState = 3;
|
|
17
|
+
};
|
|
18
|
+
socket.terminate = socket.close;
|
|
19
|
+
return { socket, ephemeral: true };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
mock.module(new URL('./openai-oauth-ws.mjs', import.meta.url).href, {
|
|
23
|
+
namedExports: {
|
|
24
|
+
...realWs,
|
|
25
|
+
sendViaWebSocket: (args) => {
|
|
26
|
+
ws.bodies.push(structuredClone(args.body));
|
|
27
|
+
return realWs.sendViaWebSocket({
|
|
28
|
+
...args,
|
|
29
|
+
_acquireWithRetryFn: async () => ({ entry: scriptedEntry(), reused: false }),
|
|
30
|
+
_sendFrameFn: async (entry, frame) => {
|
|
31
|
+
ws.frames.push(structuredClone(frame));
|
|
32
|
+
const events = ws.scripts.shift() || [COMPLETED_REPLY];
|
|
33
|
+
setImmediate(() => {
|
|
34
|
+
for (const event of events) entry.socket.emit('message', Buffer.from(JSON.stringify(event)));
|
|
35
|
+
});
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const { sendXaiResponses, sendXaiResponsesWebSocket } = await import('./openai-compat-xai-send.mjs');
|
|
43
|
+
const { nativeHistory, oauthHistory } = await import('./openai-compat-responses-parity.fixtures.mjs');
|
|
44
|
+
export { sendXaiResponses, sendXaiResponsesWebSocket, nativeHistory, oauthHistory };
|
|
45
|
+
|
|
46
|
+
export const REPLY = { type: 'message', role: 'assistant', content: [{ type: 'output_text', text: 'ok' }] };
|
|
47
|
+
export const COMPLETED_REPLY = {
|
|
48
|
+
type: 'response.completed',
|
|
49
|
+
response: { id: 'resp-1', model: 'grok-4', status: 'completed', output: [REPLY] },
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// A recorded xAI server-side tool-search turn (shapes per xAI's OpenAPI schema
|
|
53
|
+
// ToolSearchCall / ToolSearchOutput: execution always "server", call_id null).
|
|
54
|
+
export const ENCRYPTED_REASONING = { type: 'reasoning', id: 'rs_1', encrypted_content: 'ENC', summary: [] };
|
|
55
|
+
export const TS_CALL = {
|
|
56
|
+
type: 'tool_search_call',
|
|
57
|
+
id: 'tsc_1',
|
|
58
|
+
call_id: null,
|
|
59
|
+
execution: 'server',
|
|
60
|
+
status: 'completed',
|
|
61
|
+
arguments: { query: 'mcp__weather__forecast', limit: 1 },
|
|
62
|
+
};
|
|
63
|
+
export const TS_OUTPUT = {
|
|
64
|
+
type: 'tool_search_output',
|
|
65
|
+
id: 'tso_1',
|
|
66
|
+
call_id: null,
|
|
67
|
+
execution: 'server',
|
|
68
|
+
status: 'completed',
|
|
69
|
+
tools: [
|
|
70
|
+
{
|
|
71
|
+
type: 'function',
|
|
72
|
+
name: 'mcp__weather__forecast',
|
|
73
|
+
description: 'Forecast',
|
|
74
|
+
parameters: { type: 'object', properties: { city: { type: 'string' } } },
|
|
75
|
+
defer_loading: true,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
};
|
|
79
|
+
export const FN_CALL = {
|
|
80
|
+
type: 'function_call',
|
|
81
|
+
id: 'fc_1',
|
|
82
|
+
call_id: 'call_w',
|
|
83
|
+
name: 'mcp__weather__forecast',
|
|
84
|
+
arguments: '{"city":"Seoul"}',
|
|
85
|
+
status: 'completed',
|
|
86
|
+
};
|
|
87
|
+
export const TURN_OUTPUT = [ENCRYPTED_REASONING, TS_CALL, TS_OUTPUT, FN_CALL];
|
|
88
|
+
|
|
89
|
+
/** The stream events one server tool-search turn emits, in wire order. */
|
|
90
|
+
export function serverSearchEvents(model = 'grok-4') {
|
|
91
|
+
return [
|
|
92
|
+
{ type: 'response.created', response: { id: 'resp_ts', model } },
|
|
93
|
+
{ type: 'response.output_item.done', item: ENCRYPTED_REASONING },
|
|
94
|
+
{ type: 'response.output_item.added', item: { ...TS_CALL, status: 'in_progress' } },
|
|
95
|
+
{ type: 'response.output_item.done', item: TS_CALL },
|
|
96
|
+
{ type: 'response.output_item.added', item: TS_OUTPUT },
|
|
97
|
+
{ type: 'response.output_item.done', item: TS_OUTPUT },
|
|
98
|
+
{ type: 'response.output_item.added', item: { ...FN_CALL, arguments: '', status: 'in_progress' } },
|
|
99
|
+
{ type: 'response.function_call_arguments.done', item_id: 'fc_1', arguments: FN_CALL.arguments },
|
|
100
|
+
{ type: 'response.output_item.done', item: FN_CALL },
|
|
101
|
+
{
|
|
102
|
+
type: 'response.completed',
|
|
103
|
+
response: { id: 'resp_ts', model, status: 'completed', output: TURN_OUTPUT },
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export const SESSION_TOOLS = [
|
|
109
|
+
{ name: 'Read', description: 'Read a file', inputSchema: { type: 'object', properties: { path: { type: 'string' } } } },
|
|
110
|
+
{ name: 'load_tool', description: 'Load tools', inputSchema: { type: 'object', properties: { names: { type: 'array' } } } },
|
|
111
|
+
];
|
|
112
|
+
export const DEFERRED_TOOLS = [
|
|
113
|
+
...SESSION_TOOLS,
|
|
114
|
+
{
|
|
115
|
+
name: 'mcp__weather__forecast',
|
|
116
|
+
description: 'Forecast',
|
|
117
|
+
inputSchema: { type: 'object', properties: { city: { type: 'string' } } },
|
|
118
|
+
deferLoading: true,
|
|
119
|
+
},
|
|
120
|
+
];
|
|
121
|
+
|
|
122
|
+
export function xaiProvider(config = {}, events = null) {
|
|
123
|
+
const requests = [];
|
|
124
|
+
const provider = {
|
|
125
|
+
name: 'xai',
|
|
126
|
+
config: { apiKey: 'test-key', preconnect: false, ...config },
|
|
127
|
+
nativePdf: true,
|
|
128
|
+
client: {
|
|
129
|
+
responses: {
|
|
130
|
+
create: async (params) => {
|
|
131
|
+
requests.push(structuredClone(params));
|
|
132
|
+
return (async function* () {
|
|
133
|
+
for (const event of events || [COMPLETED_REPLY]) yield event;
|
|
134
|
+
})();
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
return { provider, requests };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** The history left by a recorded server tool-search turn (replay owner xai-responses). */
|
|
143
|
+
export function serverSearchHistory() {
|
|
144
|
+
return [
|
|
145
|
+
{ role: 'user', content: 'weather in Seoul?' },
|
|
146
|
+
{
|
|
147
|
+
role: 'assistant',
|
|
148
|
+
content: '',
|
|
149
|
+
toolCalls: [{ id: 'call_w', name: 'mcp__weather__forecast', arguments: { city: 'Seoul' } }],
|
|
150
|
+
providerReplay: { version: 1, provider: 'xai-responses', items: structuredClone(TURN_OUTPUT) },
|
|
151
|
+
},
|
|
152
|
+
{ role: 'tool', toolCallId: 'call_w', content: 'sunny' },
|
|
153
|
+
{ role: 'user', content: 'and Busan?' },
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export const CASES = [
|
|
158
|
+
['native/plain-tools', () => nativeHistory(), SESSION_TOOLS],
|
|
159
|
+
['oauth/plain-tools', () => oauthHistory(), SESSION_TOOLS],
|
|
160
|
+
['server-replay/plain-tools', () => serverSearchHistory(), SESSION_TOOLS],
|
|
161
|
+
['server-replay/deferred-tools', () => serverSearchHistory(), DEFERRED_TOOLS],
|
|
162
|
+
['native/deferred-tools', () => nativeHistory(), DEFERRED_TOOLS],
|
|
163
|
+
];
|
|
164
|
+
|
|
165
|
+
/** The request body each transport sends for `history`, plus any option overrides. */
|
|
166
|
+
export async function captureBodies(history, tools, { config = {}, opts = {} } = {}) {
|
|
167
|
+
const http = xaiProvider(config);
|
|
168
|
+
await sendXaiResponses(http.provider, history, 'grok-4', tools, { sessionId: 'sess-1', ...opts });
|
|
169
|
+
const before = ws.bodies.length;
|
|
170
|
+
const socket = xaiProvider(config);
|
|
171
|
+
await sendXaiResponsesWebSocket(socket.provider, history, 'grok-4', tools, { sessionId: 'sess-1', iteration: 1, ...opts });
|
|
172
|
+
return { http: http.requests[0], ws: ws.bodies[before] };
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export async function captureAll() {
|
|
176
|
+
const out = {};
|
|
177
|
+
for (const [label, build, tools] of CASES) {
|
|
178
|
+
const { http, ws: socketBody } = await captureBodies(build(), tools);
|
|
179
|
+
out[`http/${label}`] = http;
|
|
180
|
+
out[`ws/${label}`] = socketBody;
|
|
181
|
+
}
|
|
182
|
+
return out;
|
|
183
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
export const ASK_USER_MAX_QUESTIONS = 4;
|
|
2
|
+
export const ASK_USER_MAX_TEXT = 4000;
|
|
3
|
+
export const ASK_USER_MAX_LABEL = 80;
|
|
4
|
+
|
|
5
|
+
export const ASK_USER_TOOL_DEFS = Object.freeze([
|
|
6
|
+
{
|
|
7
|
+
name: 'ask_user',
|
|
8
|
+
title: 'Ask User',
|
|
9
|
+
trigger: 'Ask the user 1–4 multiple-choice questions and wait; when a plan needs the user to pick between clear options, instead of listing them in chat.',
|
|
10
|
+
description:
|
|
11
|
+
'Ask the user multiple-choice questions and wait. Only while planning, for a decision only the user can make with clear options; open questions, minor choices and plan approval go in chat. Do not repeat the options in your message.',
|
|
12
|
+
annotations: {
|
|
13
|
+
title: 'Ask User',
|
|
14
|
+
readOnlyHint: true,
|
|
15
|
+
destructiveHint: false,
|
|
16
|
+
idempotentHint: false,
|
|
17
|
+
openWorldHint: false,
|
|
18
|
+
agentHidden: true,
|
|
19
|
+
},
|
|
20
|
+
inputSchema: {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
questions: {
|
|
24
|
+
type: 'array',
|
|
25
|
+
minItems: 1,
|
|
26
|
+
maxItems: ASK_USER_MAX_QUESTIONS,
|
|
27
|
+
items: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
question: { type: 'string', description: 'Full question, without the options.' },
|
|
31
|
+
header: { type: 'string', maxLength: 12, description: 'Chip label.' },
|
|
32
|
+
options: {
|
|
33
|
+
type: 'array',
|
|
34
|
+
minItems: 2,
|
|
35
|
+
maxItems: 4,
|
|
36
|
+
description: 'Distinct; free text is added, never "Other".',
|
|
37
|
+
items: {
|
|
38
|
+
type: 'object',
|
|
39
|
+
properties: {
|
|
40
|
+
label: { type: 'string', maxLength: 80, description: '1-5 words.' },
|
|
41
|
+
description: { type: 'string', description: 'One-sentence tradeoff.' },
|
|
42
|
+
},
|
|
43
|
+
required: ['label', 'description'],
|
|
44
|
+
additionalProperties: false,
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
multi_select: { type: 'boolean' },
|
|
48
|
+
recommended: { type: 'integer', minimum: 0, description: 'Recommended option index.' },
|
|
49
|
+
},
|
|
50
|
+
required: ['question', 'header', 'options'],
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
required: ['questions'],
|
|
55
|
+
additionalProperties: false,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
/** Throws a clear error when the questions are malformed; returns the list. */
|
|
61
|
+
export function validateAskUserQuestions(args) {
|
|
62
|
+
const questions = args?.questions;
|
|
63
|
+
if (!Array.isArray(questions) || questions.length < 1 || questions.length > ASK_USER_MAX_QUESTIONS) {
|
|
64
|
+
throw new Error(`ask_user requires 1-${ASK_USER_MAX_QUESTIONS} questions`);
|
|
65
|
+
}
|
|
66
|
+
const seenQuestions = new Set();
|
|
67
|
+
questions.forEach((q, i) => {
|
|
68
|
+
const at = `ask_user question ${i + 1}`;
|
|
69
|
+
if (!q || typeof q !== 'object') throw new Error(`${at} must be an object`);
|
|
70
|
+
if (typeof q.question !== 'string' || !q.question.trim()) throw new Error(`${at} needs question text`);
|
|
71
|
+
if (typeof q.header !== 'string' || !q.header.trim() || q.header.length > 12) {
|
|
72
|
+
throw new Error(`${at} needs a header of at most 12 characters`);
|
|
73
|
+
}
|
|
74
|
+
if (seenQuestions.has(q.question)) throw new Error(`${at} duplicates another question text`);
|
|
75
|
+
seenQuestions.add(q.question);
|
|
76
|
+
if (!Array.isArray(q.options) || q.options.length < 2 || q.options.length > 4) {
|
|
77
|
+
throw new Error(`${at} needs 2-4 options`);
|
|
78
|
+
}
|
|
79
|
+
const labels = new Set();
|
|
80
|
+
for (const option of q.options) {
|
|
81
|
+
if (!option || typeof option.label !== 'string' || !option.label.trim()) {
|
|
82
|
+
throw new Error(`${at} has an option without a label`);
|
|
83
|
+
}
|
|
84
|
+
if (option.label.length > 80) throw new Error(`${at} has an option label over 80 characters`);
|
|
85
|
+
if (typeof option.description !== 'string' || !option.description.trim()) {
|
|
86
|
+
throw new Error(`${at} option "${option.label}" needs a one-sentence description`);
|
|
87
|
+
}
|
|
88
|
+
if (option.description.length > 200) throw new Error(`${at} has an option description over 200 characters`);
|
|
89
|
+
if (Object.keys(option).some((key) => key !== 'label' && key !== 'description')) {
|
|
90
|
+
throw new Error(`${at}: options take only a label and a description`);
|
|
91
|
+
}
|
|
92
|
+
if (labels.has(option.label)) throw new Error(`${at} has duplicate option label "${option.label}"`);
|
|
93
|
+
labels.add(option.label);
|
|
94
|
+
}
|
|
95
|
+
if (q.recommended != null && (!Number.isInteger(q.recommended) || q.recommended < 0 || q.recommended >= q.options.length)) {
|
|
96
|
+
throw new Error(`${at} recommended must be an index below ${q.options.length}`);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
return questions;
|
|
100
|
+
}
|
|
@@ -351,6 +351,9 @@ export function normalizeCompactionConfig(value = {}) {
|
|
|
351
351
|
return {
|
|
352
352
|
...next,
|
|
353
353
|
auto: raw.auto !== false && raw.enabled !== false,
|
|
354
|
+
// Compact a conversation on its current model before switching it to
|
|
355
|
+
// another one in place (default on).
|
|
356
|
+
onModelChange: raw.onModelChange !== false,
|
|
354
357
|
};
|
|
355
358
|
}
|
|
356
359
|
|
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
const lowerName = (name) => String(name || '').toLowerCase();
|
|
2
|
+
|
|
3
|
+
/** The persisted schema allowlist (also the execution allowlist) leaves `name` out. */
|
|
4
|
+
export function sessionAllowlistExcludes(session, name) {
|
|
5
|
+
if (!Array.isArray(session?.schemaAllowedTools)) return false;
|
|
6
|
+
return !session.schemaAllowedTools.some((allowed) => lowerName(allowed) === lowerName(name));
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/** The session's denied tools name `name`. */
|
|
10
|
+
export function sessionDisallows(session, name) {
|
|
11
|
+
return Array.isArray(session?.disallowedTools) && session.disallowedTools.some((denied) => lowerName(denied) === lowerName(name));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The session's own tool policy permits `name`: discovery (load_tool by name
|
|
16
|
+
* or query) shows, selects and describes only what execution would run.
|
|
17
|
+
*/
|
|
18
|
+
export function isToolPermittedBySessionPolicy(session, name) {
|
|
19
|
+
return !sessionAllowlistExcludes(session, name) && !sessionDisallows(session, name);
|
|
20
|
+
}
|
|
21
|
+
|
|
1
22
|
// Discovery history retains definitions; only the latest scoped MCP snapshot
|
|
2
23
|
// grants availability. An absent snapshot preserves pre-initialization behavior.
|
|
3
24
|
export function isDeferredToolAvailable(session, name) {
|
|
@@ -114,6 +114,21 @@ function catalogEffortOptions(provider, model) {
|
|
|
114
114
|
return providerAllowed ? [...providerAllowed] : [];
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
const warnedEmptyLadders = new Set();
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Auto effort skipped a judgment because the base is off the model's ladder.
|
|
121
|
+
* A user-chosen max/ultra is expected to skip; any other base means the route
|
|
122
|
+
* has no usable ladder, so say so once per provider/model per process.
|
|
123
|
+
*/
|
|
124
|
+
export function warnEmptyAutoEffortLadder(provider, model, base) {
|
|
125
|
+
if (base === 'max' || base === 'ultra') return;
|
|
126
|
+
const key = `${provider}/${model}`;
|
|
127
|
+
if (warnedEmptyLadders.has(key)) return;
|
|
128
|
+
warnedEmptyLadders.add(key);
|
|
129
|
+
process.stderr.write(`[auto-effort] no effort ladder for ${key}; judge skipped\n`);
|
|
130
|
+
}
|
|
131
|
+
|
|
117
132
|
export function coerceEffortFor(provider, model, effort) {
|
|
118
133
|
if (!effort) return null;
|
|
119
134
|
if (model?.customReasoning) return snapCustomEffort(customEffortLevels(model), effort);
|
|
@@ -80,21 +80,3 @@ export function acknowledgePendingGoalReminder(session, revision) {
|
|
|
80
80
|
session.updatedAt = Date.now();
|
|
81
81
|
return true;
|
|
82
82
|
}
|
|
83
|
-
|
|
84
|
-
export function prependGoalReminderToLatestUserMessage(messages, content) {
|
|
85
|
-
const reminder = clean(content);
|
|
86
|
-
const out = Array.isArray(messages) ? [...messages] : [];
|
|
87
|
-
if (!reminder) return out;
|
|
88
|
-
for (let index = out.length - 1; index >= 0; index -= 1) {
|
|
89
|
-
const message = out[index];
|
|
90
|
-
if (message?.role !== 'user') continue;
|
|
91
|
-
const current = message.content;
|
|
92
|
-
const nextContent = Array.isArray(current)
|
|
93
|
-
? [{ type: 'text', text: `${reminder}\n\n` }, ...current]
|
|
94
|
-
: `${reminder}\n\n${String(current ?? '')}`;
|
|
95
|
-
out[index] = { ...message, content: nextContent };
|
|
96
|
-
return out;
|
|
97
|
-
}
|
|
98
|
-
out.push({ role: 'user', content: reminder });
|
|
99
|
-
return out;
|
|
100
|
-
}
|
|
@@ -7,6 +7,7 @@ import { modelSupportsServiceTier } from '../providers/model-service-tiers.mjs';
|
|
|
7
7
|
import { openAiDirectSupportsFast, openAiDirectSupportsUltrafast } from '../providers/openai-direct-request.mjs';
|
|
8
8
|
import { supportsAnthropicFastMode } from '../../../shared/llm/anthropic-betas.mjs';
|
|
9
9
|
import { normalizeContextTokens } from '../../../shared/llm/default-context-window.mjs';
|
|
10
|
+
import { getModelMetadataSync } from '../../../shared/llm/model-catalog.mjs';
|
|
10
11
|
|
|
11
12
|
const FAST_CAPABLE_PROVIDERS = new Set([
|
|
12
13
|
'anthropic',
|
|
@@ -24,41 +25,59 @@ export function routeFastKey(provider, model) {
|
|
|
24
25
|
return p && m ? `${p}/${m}` : '';
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
// What one catalog row states about hosted web search: its own
|
|
29
|
+
// `supportsWebSearch` flag (true or false), else a web_search tool in its tool
|
|
30
|
+
// lists. Null when the row says nothing, which leaves the answer to the id
|
|
31
|
+
// fallback of each family.
|
|
32
|
+
function rowWebSearchDeclaration(row) {
|
|
33
|
+
if (!row || typeof row !== 'object') return null;
|
|
34
|
+
if (typeof row.supportsWebSearch === 'boolean') return row.supportsWebSearch;
|
|
31
35
|
const tools = [
|
|
32
|
-
...(Array.isArray(
|
|
33
|
-
...(Array.isArray(
|
|
34
|
-
...(Array.isArray(
|
|
36
|
+
...(Array.isArray(row.supportedTools) ? row.supportedTools : []),
|
|
37
|
+
...(Array.isArray(row.tools) ? row.tools : []),
|
|
38
|
+
...(Array.isArray(row.capabilities?.tools) ? row.capabilities.tools : []),
|
|
35
39
|
].map((tool) => clean(tool?.type || tool?.name || tool).toLowerCase());
|
|
36
|
-
|
|
37
|
-
if (/codex|image|audio|tts|stt|embedding|rerank|moderation|search-preview/.test(id)) return false;
|
|
38
|
-
return /^gpt-(5(?:\.|$|-)|4\.1(?:-|$)|4o(?:-|$)|4\.5(?:-|$))/.test(id) || /^o[34](?:-|$)/.test(id);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function grokModelSupportsHostedWebSearch(model) {
|
|
42
|
-
const id = clean(model?.id || model).toLowerCase();
|
|
43
|
-
if (!id || /imagine|image|video|composer/.test(id)) return false;
|
|
44
|
-
if (id === 'grok-build') return false;
|
|
45
|
-
return /^grok-/.test(id);
|
|
40
|
+
return tools.some((tool) => tool === 'web_search' || tool === 'web_search_preview') ? true : null;
|
|
46
41
|
}
|
|
47
42
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return /^gemini-(3(?:\.|-|$)|2\.5-|2\.0-flash)/.test(id);
|
|
43
|
+
// The route's own row first, then the provider catalog's row for the model.
|
|
44
|
+
function hostedWebSearchDeclared(model, catalogRow) {
|
|
45
|
+
return rowWebSearchDeclaration(model) ?? rowWebSearchDeclaration(catalogRow);
|
|
52
46
|
}
|
|
53
47
|
|
|
54
|
-
|
|
48
|
+
// When neither the route row nor the catalog states hosted web search, the
|
|
49
|
+
// vendor family (already fixed by the provider) is taken as capable unless the
|
|
50
|
+
// id names a non-chat modality or a retired generation. Only those closed,
|
|
51
|
+
// frozen sets are matched by id, so a model released later needs no entry here;
|
|
52
|
+
// guessing "capable" wrongly would hard-fail the request, which is why the
|
|
53
|
+
// retired generations stay excluded.
|
|
54
|
+
function hostedWebSearchFallback(model, catalogRow, unsupportedId) {
|
|
55
55
|
const id = clean(model?.id || model).toLowerCase();
|
|
56
56
|
if (!id) return false;
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
return (
|
|
57
|
+
const declared = hostedWebSearchDeclared(model, catalogRow);
|
|
58
|
+
if (declared !== null) return declared;
|
|
59
|
+
return !unsupportedId.test(id);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
const NON_CHAT_ID = 'embedding|rerank|moderation|image|imagen|imagine|video|veo|audio|tts|stt|aqa|search-preview';
|
|
63
|
+
|
|
64
|
+
const OPENAI_UNSUPPORTED = new RegExp(
|
|
65
|
+
`${NON_CHAT_ID}|codex|^gpt-(?:3|4(?:$|-))|^o[12](?:-|$)|^(?:babbage|davinci|text-)`
|
|
66
|
+
);
|
|
67
|
+
const GROK_UNSUPPORTED = new RegExp(`${NON_CHAT_ID}|composer|^grok-build$|^grok-[123](?:[.-]|$)`);
|
|
68
|
+
// The Gemini family is also reached through a relay serving other vendors'
|
|
69
|
+
// models, whose hosted search is Gemini's alone, so a non-Gemini id is out.
|
|
70
|
+
const GEMINI_UNSUPPORTED = new RegExp(
|
|
71
|
+
`${NON_CHAT_ID}|^(?!gemini-)|computer-use|customtools|^gemini-(?:1[.-]|pro|ultra)|^gemini-2\\.0-(?!flash)`
|
|
72
|
+
);
|
|
73
|
+
const ANTHROPIC_UNSUPPORTED = /^claude-(?:\d|instant)|^claude-[a-z]+-[123](?:[-.]|$)/;
|
|
74
|
+
|
|
75
|
+
const openAiModelSupportsHostedWebSearch = (model, row) => hostedWebSearchFallback(model, row, OPENAI_UNSUPPORTED);
|
|
76
|
+
const grokModelSupportsHostedWebSearch = (model, row) => hostedWebSearchFallback(model, row, GROK_UNSUPPORTED);
|
|
77
|
+
const geminiModelSupportsHostedWebSearch = (model, row) => hostedWebSearchFallback(model, row, GEMINI_UNSUPPORTED);
|
|
78
|
+
const anthropicModelSupportsHostedWebSearch = (model, row) =>
|
|
79
|
+
hostedWebSearchFallback(model, row, ANTHROPIC_UNSUPPORTED);
|
|
80
|
+
|
|
62
81
|
export function fastCapableFor(provider, model, effort = null, modelParameters = {}) {
|
|
63
82
|
const p = clean(provider);
|
|
64
83
|
if (!FAST_CAPABLE_PROVIDERS.has(p)) return false;
|
|
@@ -77,8 +96,13 @@ export function fastCapableFor(provider, model, effort = null, modelParameters =
|
|
|
77
96
|
}
|
|
78
97
|
return !selectedEffort || fastEfforts.length === 0 || fastEfforts.includes(selectedEffort);
|
|
79
98
|
}
|
|
80
|
-
if (p === 'openai') return openAiDirectSupportsFast(model);
|
|
81
99
|
if (p === 'openai-oauth') return modelSupportsServiceTier(model, 'priority');
|
|
100
|
+
// The route row's own declaration first, then the catalog via the helpers.
|
|
101
|
+
if (typeof model?.supportsFastMode === 'boolean') return model.supportsFastMode;
|
|
102
|
+
const modelId = clean(model?.id || model);
|
|
103
|
+
const declaredFast = modelId ? getModelMetadataSync(modelId, p)?.supportsFastMode : undefined;
|
|
104
|
+
if (typeof declaredFast === 'boolean') return declaredFast;
|
|
105
|
+
if (p === 'openai') return openAiDirectSupportsFast(model);
|
|
82
106
|
if (p === 'anthropic' || p === 'anthropic-oauth') return supportsAnthropicFastMode(clean(model?.id || model));
|
|
83
107
|
return false;
|
|
84
108
|
}
|
|
@@ -100,10 +124,15 @@ const HOSTED_WEB_SEARCH_BY_FAMILY = {
|
|
|
100
124
|
// webSearchCapableFor needs the web-search family mapping, which lives in
|
|
101
125
|
// workflow.mjs and is pure. Wire it in via a factory to keep this module free
|
|
102
126
|
// of a circular import at load time.
|
|
103
|
-
|
|
127
|
+
// `catalogRowFor(provider, id)` is the provider catalog's row for the model;
|
|
128
|
+
// callers that hold only a bare id (or a row the provider list left silent)
|
|
129
|
+
// still get the catalog's answer before the id fallback applies.
|
|
130
|
+
export function makeWebSearchCapableFor(webSearchProviderFamily, catalogRowFor = getModelMetadataSync) {
|
|
104
131
|
return function webSearchCapableFor(provider, model) {
|
|
105
132
|
const supports = HOSTED_WEB_SEARCH_BY_FAMILY[webSearchProviderFamily(provider)];
|
|
106
|
-
|
|
133
|
+
if (!supports) return false;
|
|
134
|
+
const id = clean(model?.id || model);
|
|
135
|
+
return supports(model, id ? catalogRowFor(id, provider) : null);
|
|
107
136
|
};
|
|
108
137
|
}
|
|
109
138
|
|
|
@@ -2,16 +2,14 @@ import { normalizeOrchestrationMode } from '../../../shared/orchestration.mjs';
|
|
|
2
2
|
|
|
3
3
|
const BATCHING = {
|
|
4
4
|
focused: `Lead executes the main scope directly. Delegate only substantial,
|
|
5
|
-
self-contained supporting work
|
|
6
|
-
|
|
7
|
-
balanced: `Delegate independent work by coherent feature or module
|
|
8
|
-
tasks within the same change scope
|
|
9
|
-
splitting every file or step
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
output dependency. Prefer parallel scopes over sequential slices in one agent.
|
|
14
|
-
If the plan has only one scope, Lead executes it directly.`,
|
|
5
|
+
self-contained supporting work, one agent per role; batch related tasks
|
|
6
|
+
rather than splitting them for parallelism.`,
|
|
7
|
+
balanced: `Delegate independent work by coherent feature or module, one agent per
|
|
8
|
+
scope. Batch related tasks within the same change scope rather than
|
|
9
|
+
splitting every file or step.`,
|
|
10
|
+
swarm: `Delegate every independent scope to its own agent. Treat disjoint file or
|
|
11
|
+
module sets as independent and merge scopes only on a true output
|
|
12
|
+
dependency. Prefer parallel scopes over sequential slices in one agent.`,
|
|
15
13
|
};
|
|
16
14
|
|
|
17
15
|
const SOLO = `# Orchestration Mode: Solo
|
|
@@ -27,6 +25,12 @@ export function orchestrationInstructions(value) {
|
|
|
27
25
|
|
|
28
26
|
${BATCHING[mode]}
|
|
29
27
|
|
|
28
|
+
The mode sets how work splits; an agent's description sets its role and when
|
|
29
|
+
it runs. Splitting applies to every role alike — implementation, review,
|
|
30
|
+
investigation, writing — by file, module, commit range or risk area.
|
|
31
|
+
If the plan has only one implementation scope, Lead executes it directly; a
|
|
32
|
+
role tied to a point in the work, such as the final check, still runs then.
|
|
33
|
+
|
|
30
34
|
Delegation is for work whose size justifies a brief. When the brief would have
|
|
31
35
|
to spell out the edits themselves — a few localized changes whose sites Lead
|
|
32
36
|
already holds — Lead makes them directly in every mode; the number of files or
|
|
@@ -34,10 +38,9 @@ scopes does not change this.
|
|
|
34
38
|
|
|
35
39
|
Dispatch all ready independent scopes in one turn. Only a scope that requires
|
|
36
40
|
another's output waits. Brief each agent as the Lead rules describe.
|
|
37
|
-
Use only available agents;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Do not skip review or describe Lead's own review as independent review.`;
|
|
41
|
+
Use only available agents; when none fits a role, Lead does that work itself
|
|
42
|
+
and never changes settings to enable one. If the reviewer is disabled or
|
|
43
|
+
unavailable, Lead alone reviews the result against the approved scope and
|
|
44
|
+
performs the required verification, without a substitute agent; never skip
|
|
45
|
+
review or describe Lead's own review as independent.`;
|
|
43
46
|
}
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
// Plugin/project MCP server discovery + normalization, and skill-file counting.
|
|
2
|
-
import {
|
|
3
|
-
chmodSync,
|
|
4
|
-
closeSync,
|
|
5
|
-
existsSync,
|
|
6
|
-
fsyncSync,
|
|
7
|
-
openSync,
|
|
8
|
-
readFileSync,
|
|
9
|
-
readdirSync,
|
|
10
|
-
renameSync,
|
|
11
|
-
statSync,
|
|
12
|
-
unlinkSync,
|
|
13
|
-
writeFileSync,
|
|
14
|
-
} from 'node:fs';
|
|
2
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
15
3
|
import { join, relative, sep } from 'node:path';
|
|
16
4
|
import { clean } from './session-text.mjs';
|
|
17
5
|
import {
|
|
@@ -54,90 +42,6 @@ export function mergeMcpServerConfig(existing, next) {
|
|
|
54
42
|
return { ...merged, ...next };
|
|
55
43
|
}
|
|
56
44
|
|
|
57
|
-
function readProjectMcpDocument(cwd, allowMissing = false) {
|
|
58
|
-
const path = join(cwd || '.', '.mcp.json');
|
|
59
|
-
if (!existsSync(path)) {
|
|
60
|
-
if (allowMissing) return { path, raw: { mcpServers: {} }, usesWrapper: true };
|
|
61
|
-
throw new Error(`MCP config file not found: ${path}`);
|
|
62
|
-
}
|
|
63
|
-
let raw;
|
|
64
|
-
try {
|
|
65
|
-
raw = JSON.parse(readFileSync(path, 'utf8'));
|
|
66
|
-
} catch (error) {
|
|
67
|
-
throw new Error(`cannot read ${path}: ${error?.message || String(error)}`);
|
|
68
|
-
}
|
|
69
|
-
if (!isPlainObject(raw)) throw new Error(`unexpected .mcp.json shape at ${path}`);
|
|
70
|
-
if (Object.hasOwn(raw, 'mcpServers') && !isPlainObject(raw.mcpServers)) {
|
|
71
|
-
throw new Error(`unexpected .mcp.json shape at ${path}`);
|
|
72
|
-
}
|
|
73
|
-
const usesWrapper = isPlainObject(raw.mcpServers);
|
|
74
|
-
return { path, raw, usesWrapper };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function writeProjectMcpDocument(path, raw) {
|
|
78
|
-
let mode = 0o644;
|
|
79
|
-
try {
|
|
80
|
-
mode = statSync(path).mode;
|
|
81
|
-
} catch {
|
|
82
|
-
/* new file */
|
|
83
|
-
}
|
|
84
|
-
const tempPath = `${path}.tmp-${process.pid}-${Date.now()}`;
|
|
85
|
-
let fd = null;
|
|
86
|
-
try {
|
|
87
|
-
fd = openSync(tempPath, 'w', mode);
|
|
88
|
-
writeFileSync(fd, `${JSON.stringify(raw, null, 2)}\n`, 'utf8');
|
|
89
|
-
fsyncSync(fd);
|
|
90
|
-
closeSync(fd);
|
|
91
|
-
fd = null;
|
|
92
|
-
chmodSync(tempPath, mode);
|
|
93
|
-
renameSync(tempPath, path);
|
|
94
|
-
} catch (error) {
|
|
95
|
-
if (fd !== null) {
|
|
96
|
-
try {
|
|
97
|
-
closeSync(fd);
|
|
98
|
-
} catch {
|
|
99
|
-
/* best effort */
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
try {
|
|
103
|
-
unlinkSync(tempPath);
|
|
104
|
-
} catch {
|
|
105
|
-
/* best effort */
|
|
106
|
-
}
|
|
107
|
-
throw error;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// The stored key for `key`: an exact own key first, else one that trims to it.
|
|
112
|
-
function mcpEntryKey(map, key) {
|
|
113
|
-
return Object.hasOwn(map, key) ? key : Object.keys(map).find((candidate) => String(candidate || '').trim() === key);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export function readProjectMcpServerConfig(cwd, name) {
|
|
117
|
-
const { raw, usesWrapper } = readProjectMcpDocument(cwd);
|
|
118
|
-
const map = usesWrapper ? raw.mcpServers : raw;
|
|
119
|
-
const entryKey = mcpEntryKey(map, String(name || '').trim());
|
|
120
|
-
return entryKey && isPlainObject(map[entryKey]) ? { name: entryKey, config: { ...map[entryKey] } } : null;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export function saveProjectMcpServer(cwd, { originalName = '', name, config }) {
|
|
124
|
-
const { path, raw, usesWrapper } = readProjectMcpDocument(cwd, !originalName);
|
|
125
|
-
const map = usesWrapper ? raw.mcpServers : raw;
|
|
126
|
-
const target = String(name || '').trim();
|
|
127
|
-
const original = String(originalName || '').trim();
|
|
128
|
-
if (!target) throw new Error('MCP server name is required');
|
|
129
|
-
const entryKey = original ? mcpEntryKey(map, original) : null;
|
|
130
|
-
if (original && !entryKey) throw new Error(`MCP server not defined in ${path}: ${original}`);
|
|
131
|
-
if (target !== entryKey && Object.hasOwn(map, target)) {
|
|
132
|
-
throw new Error(`MCP server already exists in ${path}: ${target}`);
|
|
133
|
-
}
|
|
134
|
-
const existing = entryKey ? map[entryKey] : {};
|
|
135
|
-
if (entryKey && entryKey !== target) delete map[entryKey];
|
|
136
|
-
map[target] = mergeMcpServerConfig(existing, config);
|
|
137
|
-
writeProjectMcpDocument(path, raw);
|
|
138
|
-
return { name: target, source: 'project', path, config: { ...map[target] } };
|
|
139
|
-
}
|
|
140
|
-
|
|
141
45
|
// Manifest + contained-path resolution live in the shared module so skill
|
|
142
46
|
// discovery and this status surface read the same roots.
|
|
143
47
|
export { pluginManifest, resolveContainedPluginPath };
|