mixdog 1.2.2 → 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/provider-pingpong-live.mjs +509 -0
- package/src/agents/advisor/AGENT.md +1 -1
- package/src/agents/advisor/agent.json +1 -1
- package/src/defaults/shipped-history.json +5 -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/rules/agent/AGENT.md +5 -5
- package/src/rules/lead/LEAD.md +5 -5
- 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/providers/anthropic-api-request.mjs +48 -20
- package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +7 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +29 -10
- 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 +2 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +6 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +58 -7
- package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
- package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +16 -3
- package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +12 -6
- package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +114 -72
- package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +37 -5
- package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +3 -0
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +9 -2
- 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 +3 -1
- package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
- package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +25 -8
- package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +87 -5
- package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
- package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +13 -13
- package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +355 -37
- package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +93 -47
- package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +55 -10
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +26 -8
- package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
- 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/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/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 +121 -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 +5 -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-error-contract.mjs +1 -1
- 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 +42 -24
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
- 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.mjs +53 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
- 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 +25 -4
- 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 +4 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +71 -24
- 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-ws-delta.mjs +7 -16
- 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-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.mjs +11 -3
- 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 +147 -8
- package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +5 -0
- 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/deferred-tool-availability.mjs +21 -0
- package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
- 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 +3 -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 +63 -20
- package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +2 -1
- 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 +4 -1
- 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 +16 -0
- 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/prompt-utils.mjs +208 -14
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +15 -3
- 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.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 +13 -0
- 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/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-summary-archived-agent.mjs +34 -15
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -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/tools/bash-policy-scan.mjs +8 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
- 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 +31 -26
- package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
- package/src/runtime/memory/lib/pg/supervisor.mjs +108 -3
- 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 +1 -1
- 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/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 +6 -0
- 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-effort.mjs +6 -0
- 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/loopback-listener.mjs +9 -0
- package/src/runtime/shared/provider-api-key.mjs +2 -0
- package/src/runtime/shared/review-diff.mjs +52 -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-segments.mjs +28 -4
- 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 +268 -100
- package/src/runtime/shared/turn-review-reply.mjs +8 -39
- package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
- package/src/runtime/shared/turn-snapshot.mjs +857 -683
- package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
- 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 -0
- 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/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 +13 -5
- package/src/session-runtime/boot/facade.mjs +1 -0
- package/src/session-runtime/boot/infrastructure.mjs +6 -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 +12 -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 +72 -7
- package/src/session-runtime/lifecycle-api.mjs +1 -0
- package/src/session-runtime/mcp-glue/connect.mjs +17 -5
- package/src/session-runtime/model-route/set-route.mjs +2 -2
- 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/resource-scope-decorate.mjs +10 -3
- package/src/session-runtime/runtime-review-api.mjs +8 -2
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
- 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/tag-registry.mjs +15 -1
- 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.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/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-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 +19 -0
- package/src/standalone/daemon.mjs +61 -1
- 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 +7 -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/session-calls/session-action.mjs +18 -3
- package/src/standalone/session-service-api.mjs +6 -1
- 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/btw-controller.mjs +118 -0
- package/src/tui/app/create-app-pickers.mjs +2 -0
- 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 +13 -3
- 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/question-panel-model.mjs +156 -0
- package/src/tui/dist/index.mjs +2413 -1465
- package/src/tui/session/context-state.mjs +4 -2
- package/src/tui/session/session-api/commands.mjs +10 -0
- package/src/tui/session/session-api/controls.mjs +2 -2
- package/src/tui/session/session-api/integrations.mjs +9 -2
- package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
- package/src/tui/session/session-api/lifecycle.mjs +2 -1
- package/src/tui/session/session-api/settings.mjs +6 -0
- package/src/tui/session/session-api.mjs +1 -0
- 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 +12 -5
- package/src/workflows/default/WORKFLOW.md +3 -1
|
@@ -14,16 +14,36 @@ import {
|
|
|
14
14
|
toOpenAITools,
|
|
15
15
|
parseToolCalls,
|
|
16
16
|
knownToolNamesFromOpenAITools,
|
|
17
|
-
deepseekReplaysReasoningContent,
|
|
18
17
|
} from './openai-compat-wire.mjs';
|
|
19
|
-
import { applyCompatProviderChatOptions } from './openai-compat-options.mjs';
|
|
18
|
+
import { applyCompatProviderChatOptions, deepseekThinkingMode } from './openai-compat-options.mjs';
|
|
20
19
|
import { normalizeCompatChatResponse } from './openai-compat-response-normalization.mjs';
|
|
21
20
|
import { applyCompatToolChoice, compatStreamRetryReporter } from './compat-request-policy.mjs';
|
|
22
21
|
import { ensureChatToolPairs } from './lib/wire-pairing.mjs';
|
|
23
22
|
import { xaiCacheRouting } from './openai-compat-xai.mjs';
|
|
24
23
|
import { compatRetryOptions, withCompatRetryProfile } from './openai-compat-retry-profile.mjs';
|
|
25
24
|
import { preparePdfTextForProvider } from './media-normalization.mjs';
|
|
26
|
-
import { isCustomProviderName, resolveCustomReasoning } from './custom-reasoning.mjs';
|
|
25
|
+
import { customWireFormat, isCustomProviderName, resolveCustomReasoning } from './custom-reasoning.mjs';
|
|
26
|
+
import { geminiAcceptedTools } from './gemini-schema.mjs';
|
|
27
|
+
import { acceptedWireTools } from './lib/claude-bridge-schema.mjs';
|
|
28
|
+
import { isGeminiFamilyModel } from './gemini-family.mjs';
|
|
29
|
+
import { compatReasoningShape, isTogetherBaseURL, readChatMessage } from './openai-compat-reasoning-field.mjs';
|
|
30
|
+
|
|
31
|
+
// Endpoint families with their own reasoning field (Together, vLLM, Groq,
|
|
32
|
+
// Mistral, OpenRouter); a custom provider's row may declare the vLLM format.
|
|
33
|
+
function reasoningShapeFor(provider, modelInfo) {
|
|
34
|
+
return compatReasoningShape({
|
|
35
|
+
providerName: provider.name,
|
|
36
|
+
baseURL: provider.baseURL,
|
|
37
|
+
wireFormat: isCustomProviderName(provider.name) ? customWireFormat(modelInfo, provider.baseURL) : undefined,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// The `developer` role is documented by MiMo and by Together's gpt-oss models;
|
|
42
|
+
// every other chat endpoint only knows `system`.
|
|
43
|
+
function keepsDeveloperRole(provider, profile, useModel) {
|
|
44
|
+
if (profile?.developerRole === true) return true;
|
|
45
|
+
return isTogetherBaseURL(provider.baseURL) && /gpt-oss/i.test(String(useModel || ''));
|
|
46
|
+
}
|
|
27
47
|
|
|
28
48
|
export async function sendCompatChat(provider, messages, useModel, tools, opts) {
|
|
29
49
|
const signal = opts.signal || null;
|
|
@@ -49,13 +69,17 @@ export async function sendCompatChat(provider, messages, useModel, tools, opts)
|
|
|
49
69
|
protocol: 'openai-chat',
|
|
50
70
|
model: modelInfo,
|
|
51
71
|
effort: opts.effort ?? provider.config?.reasoningEffort,
|
|
72
|
+
baseURL: provider.baseURL,
|
|
52
73
|
})
|
|
53
74
|
: null;
|
|
75
|
+
// DeepSeek thinking models need the prior reasoning_content back once tools
|
|
76
|
+
// are in play and ignore it otherwise, so it always goes back.
|
|
54
77
|
const replaysReasoningContent = isCustom
|
|
55
78
|
? customReasoning.replay
|
|
56
79
|
: modelInfo?.reasoningContentField === 'reasoning_content' ||
|
|
57
80
|
profile?.replaysReasoningContent === true ||
|
|
58
|
-
|
|
81
|
+
provider.name === 'deepseek';
|
|
82
|
+
const reasoningShape = reasoningShapeFor(provider, modelInfo);
|
|
59
83
|
messages = await preparePdfTextForProvider(messages, provider);
|
|
60
84
|
const params = {
|
|
61
85
|
model: useModel,
|
|
@@ -65,82 +89,113 @@ export async function sendCompatChat(provider, messages, useModel, tools, opts)
|
|
|
65
89
|
messages: ensureChatToolPairs(
|
|
66
90
|
toOpenAIMessages(messages, provider.name, {
|
|
67
91
|
replaysReasoningContent,
|
|
92
|
+
...(reasoningShape ? { reasoningShape } : {}),
|
|
68
93
|
...(isCustom ? { customReplay: customReasoning.replay } : {}),
|
|
94
|
+
...(keepsDeveloperRole(provider, profile, useModel) ? { developerRole: true } : {}),
|
|
69
95
|
nativePdf: provider.nativePdf,
|
|
96
|
+
cacheControl: provider.chatCacheControl === true,
|
|
70
97
|
})
|
|
71
98
|
),
|
|
72
99
|
};
|
|
73
100
|
const maxOutputTokens = resolveCompatMaxOutputTokens(opts);
|
|
74
101
|
if (maxOutputTokens) params.max_tokens = maxOutputTokens;
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
// A Gemini-family model behind this route (google/gemini-* on OpenRouter)
|
|
103
|
+
// fails the whole request on one schema Google rejects; such a tool is left
|
|
104
|
+
// out and reported like on the native Gemini routes.
|
|
105
|
+
// Every other model's `parameters` must be a valid 2020-12 object schema;
|
|
106
|
+
// a draft-07 one is lowered and a broken one left out and reported.
|
|
107
|
+
let sendTools = tools;
|
|
108
|
+
if (tools?.length) {
|
|
109
|
+
sendTools = isGeminiFamilyModel(useModel)
|
|
110
|
+
? geminiAcceptedTools(tools, opts.onToolExcluded)
|
|
111
|
+
: acceptedWireTools(tools, 'openai', opts.onToolExcluded, `[${provider.name}] tool`);
|
|
112
|
+
}
|
|
113
|
+
if (sendTools?.length) params.tools = toOpenAITools(sendTools);
|
|
114
|
+
// A forced tool_choice goes out only on the documented providers; DeepSeek
|
|
115
|
+
// gets it only with thinking explicitly disabled (never silently in thinking
|
|
116
|
+
// mode, and never as an error for a turn whose thinking is enabled).
|
|
117
|
+
applyCompatToolChoice(params, opts, {
|
|
118
|
+
provider: provider.name,
|
|
119
|
+
baseURL: provider.baseURL,
|
|
120
|
+
wire: 'chat',
|
|
121
|
+
thinking:
|
|
122
|
+
provider.name === 'deepseek' && deepseekThinkingMode(opts, provider.config) === 'disabled' ? 'disabled' : null,
|
|
123
|
+
});
|
|
77
124
|
applyCompatProviderChatOptions(params, provider.name, opts, provider.config, modelInfo);
|
|
78
125
|
profile?.applyParams?.(params, { opts, config: provider.config, modelInfo });
|
|
79
126
|
const firstByteTimeoutMs = profile?.firstByteTimeoutMs || PROVIDER_FIRST_BYTE_TIMEOUT_MS;
|
|
80
127
|
const totalSignal = createPassthroughSignal(signal);
|
|
81
128
|
const cacheRouting = provider.name === 'xai' ? xaiCacheRouting(opts, params, tools || [], useModel) : null;
|
|
82
129
|
const cacheRoutingKey = cacheRouting?.key || null;
|
|
130
|
+
// xAI Chat pins a conversation to the server holding its cached prefix with
|
|
131
|
+
// the x-grok-conv-id header (the Responses equivalent is prompt_cache_key).
|
|
132
|
+
const requestHeaders = cacheRoutingKey
|
|
133
|
+
? { 'x-grok-conv-id': cacheRoutingKey, ...(opts.requestHeaders || {}) }
|
|
134
|
+
: opts.requestHeaders;
|
|
83
135
|
params.stream = true;
|
|
84
136
|
params.stream_options = { include_usage: true };
|
|
85
137
|
let assembled;
|
|
86
138
|
try {
|
|
87
139
|
try {
|
|
88
140
|
assembled = await withRetry(
|
|
89
|
-
withCompatRetryProfile(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
({ signal: openSignal }) =>
|
|
97
|
-
provider.client.chat.completions.create(params, {
|
|
98
|
-
signal: openSignal,
|
|
99
|
-
...(opts.requestHeaders ? { headers: opts.requestHeaders } : {}),
|
|
100
|
-
}),
|
|
101
|
-
{
|
|
102
|
-
signal: attemptSignal,
|
|
103
|
-
// Single attempt: this inner wrapper exists only to
|
|
104
|
-
// apply the first-byte per-attempt timeout. Retry is
|
|
105
|
-
// owned by the outer withRetry — nesting retry loops
|
|
106
|
-
// here multiplied tail latency (5x5).
|
|
107
|
-
maxAttempts: 1,
|
|
108
|
-
perAttemptTimeoutMs: firstByteTimeoutMs,
|
|
109
|
-
perAttemptLabel: `${provider.name} first byte`,
|
|
141
|
+
withCompatRetryProfile(
|
|
142
|
+
provider.name,
|
|
143
|
+
refineAttemptErrors(profile, async ({ signal: attemptSignal }) => {
|
|
144
|
+
try {
|
|
145
|
+
opts.onStageChange?.('requesting');
|
|
146
|
+
} catch {
|
|
147
|
+
/* heartbeat best-effort */
|
|
110
148
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
149
|
+
const stream = await withRetry(
|
|
150
|
+
({ signal: openSignal }) =>
|
|
151
|
+
provider.client.chat.completions.create(params, {
|
|
152
|
+
signal: openSignal,
|
|
153
|
+
...(requestHeaders ? { headers: requestHeaders } : {}),
|
|
154
|
+
}),
|
|
155
|
+
{
|
|
156
|
+
signal: attemptSignal,
|
|
157
|
+
// Single attempt: this inner wrapper exists only to
|
|
158
|
+
// apply the first-byte per-attempt timeout. Retry is
|
|
159
|
+
// owned by the outer withRetry — nesting retry loops
|
|
160
|
+
// here multiplied tail latency (5x5).
|
|
161
|
+
maxAttempts: 1,
|
|
162
|
+
perAttemptTimeoutMs: firstByteTimeoutMs,
|
|
163
|
+
perAttemptLabel: `${provider.name} first byte`,
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
try {
|
|
167
|
+
opts.onStageChange?.('streaming');
|
|
168
|
+
} catch {
|
|
169
|
+
/* heartbeat best-effort */
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
return await consumeCompatChatCompletionStream(stream, {
|
|
173
|
+
signal: attemptSignal,
|
|
174
|
+
label: provider.name,
|
|
175
|
+
providerName: provider.name,
|
|
176
|
+
onStreamDelta: opts.onStreamDelta,
|
|
177
|
+
onToolCall: opts.onToolCall,
|
|
178
|
+
onTextDelta: opts.onTextDelta,
|
|
179
|
+
parseToolCalls,
|
|
180
|
+
// Known tool names for the leaked-tool-call guard:
|
|
181
|
+
// recovered leaked calls only synthesize when they name
|
|
182
|
+
// a tool actually offered to this request.
|
|
183
|
+
knownToolNames: knownToolNamesFromOpenAITools(params.tools),
|
|
184
|
+
...(profile?.firstByteTimeoutMs ? { firstByteTimeoutMs: profile.firstByteTimeoutMs } : {}),
|
|
185
|
+
...(profile?.semanticIdleTimeoutMs ? { semanticIdleTimeoutMs: profile.semanticIdleTimeoutMs } : {}),
|
|
139
186
|
});
|
|
187
|
+
} catch (error) {
|
|
188
|
+
// Grok's reference sampler treats content-idle as a
|
|
189
|
+
// terminal sampling decision, not a resample signal.
|
|
190
|
+
if (provider.name === 'xai' && error?.streamStalled === true) {
|
|
191
|
+
throw markProviderRecoveryExhausted(error, {
|
|
192
|
+
owner: 'xai-content-idle-policy',
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
throw error;
|
|
140
196
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
})),
|
|
197
|
+
})
|
|
198
|
+
),
|
|
144
199
|
{
|
|
145
200
|
signal: totalSignal.signal,
|
|
146
201
|
onRetry: compatStreamRetryReporter(provider.name, opts),
|
|
@@ -152,7 +207,7 @@ export async function sendCompatChat(provider, messages, useModel, tools, opts)
|
|
|
152
207
|
const recovered = await provider._recoverCompatNonStreaming({
|
|
153
208
|
streamErr,
|
|
154
209
|
params,
|
|
155
|
-
opts,
|
|
210
|
+
opts: requestHeaders === opts.requestHeaders ? opts : { ...opts, requestHeaders },
|
|
156
211
|
signal: totalSignal.signal,
|
|
157
212
|
useModel,
|
|
158
213
|
});
|
|
@@ -172,6 +227,7 @@ export async function sendCompatChat(provider, messages, useModel, tools, opts)
|
|
|
172
227
|
cacheRoutingKey,
|
|
173
228
|
cacheRouting,
|
|
174
229
|
replaysReasoningContent,
|
|
230
|
+
reasoningShape,
|
|
175
231
|
});
|
|
176
232
|
}
|
|
177
233
|
|
|
@@ -236,13 +292,17 @@ export async function recoverCompatNonStreaming(provider, { streamErr, params, o
|
|
|
236
292
|
/* best-effort */
|
|
237
293
|
}
|
|
238
294
|
traceNonStreamingFallback({ provider: provider.name, model: useModel, opts, streamErr });
|
|
295
|
+
const { content, reasoningContent, reasoningSource } = readChatMessage(message, {
|
|
296
|
+
shape: reasoningShapeFor(provider, provider.getCachedModelInfo?.(useModel) || null),
|
|
297
|
+
});
|
|
239
298
|
return {
|
|
240
299
|
response,
|
|
241
300
|
model: response.model || useModel,
|
|
242
|
-
content
|
|
301
|
+
content,
|
|
243
302
|
toolCalls,
|
|
244
303
|
stopReason: choice.finish_reason || null,
|
|
245
|
-
reasoningContent
|
|
304
|
+
reasoningContent,
|
|
305
|
+
reasoningSource,
|
|
246
306
|
rawUsage: response.usage || null,
|
|
247
307
|
};
|
|
248
308
|
}
|
|
@@ -4,7 +4,18 @@
|
|
|
4
4
|
* reasoning aliases, tool_calls deltas, finish reason and usage.
|
|
5
5
|
*/
|
|
6
6
|
import { mergeToolCallDelta } from './tool-call-acc.mjs';
|
|
7
|
-
import { appendText, relayText, reportProgress, reportTransport } from './stream-state.mjs';
|
|
7
|
+
import { appendText, drainLeakedCalls, relayText, reportProgress, reportTransport } from './stream-state.mjs';
|
|
8
|
+
import { chatContentParts } from '../openai-compat-reasoning-field.mjs';
|
|
9
|
+
|
|
10
|
+
function appendReasoning(state, text, source) {
|
|
11
|
+
state.sawReasoningContent = true;
|
|
12
|
+
state.reasoningSource = source;
|
|
13
|
+
state.reasoningContent += text;
|
|
14
|
+
if (text) {
|
|
15
|
+
state.emittedReasoning = true;
|
|
16
|
+
reportProgress(state, 'reasoning');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
8
19
|
|
|
9
20
|
function applyReasoning(state, delta) {
|
|
10
21
|
if (Array.isArray(delta?.reasoning_details) && delta.reasoning_details.length) {
|
|
@@ -12,14 +23,22 @@ function applyReasoning(state, delta) {
|
|
|
12
23
|
reportProgress(state, 'reasoning');
|
|
13
24
|
}
|
|
14
25
|
// These provider fields are aliases, never independent text segments.
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
const source = ['reasoning_content', 'reasoning', 'thinking'].find((key) => typeof delta?.[key] === 'string');
|
|
27
|
+
if (source === undefined) return;
|
|
28
|
+
appendReasoning(state, delta[source], source);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function applyContent(state, content) {
|
|
32
|
+
if (state.leakGuard.enabled) relayText(state, content);
|
|
33
|
+
else appendText(state, content);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Mistral-style typed chunk lists: thinking → reasoning, text → assistant
|
|
37
|
+
// text, applied in arrival order.
|
|
38
|
+
function applyContentParts(state, parts) {
|
|
39
|
+
for (const part of parts) {
|
|
40
|
+
if (part.kind === 'reasoning') appendReasoning(state, part.text, 'content_chunks');
|
|
41
|
+
else if (part.text) applyContent(state, part.text);
|
|
23
42
|
}
|
|
24
43
|
}
|
|
25
44
|
|
|
@@ -32,15 +51,17 @@ export function applyCompatChunk(state, chunk) {
|
|
|
32
51
|
if (typeof delta?.role === 'string' && delta.role) {
|
|
33
52
|
reportProgress(state, 'semantic');
|
|
34
53
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
54
|
+
const contentParts = chatContentParts(delta?.content);
|
|
55
|
+
if (contentParts) applyContentParts(state, contentParts);
|
|
56
|
+
else if (delta?.content) applyContent(state, delta.content);
|
|
39
57
|
applyReasoning(state, delta);
|
|
40
58
|
if (Array.isArray(delta?.tool_calls) && delta.tool_calls.length) {
|
|
41
59
|
reportProgress(state, 'tool');
|
|
42
60
|
}
|
|
43
61
|
mergeToolCallDelta(state.toolAcc, delta?.tool_calls);
|
|
44
|
-
if (choice?.finish_reason)
|
|
62
|
+
if (choice?.finish_reason) {
|
|
63
|
+
state.stopReason = choice.finish_reason;
|
|
64
|
+
drainLeakedCalls(state);
|
|
65
|
+
}
|
|
45
66
|
if (chunk?.usage) state.rawUsage = chunk.usage;
|
|
46
67
|
}
|
package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
markUnsafeRetryIfToolEmitted,
|
|
14
14
|
} from '../openai-compat-stream-common.mjs';
|
|
15
15
|
import { orderedToolCalls, toolCallsFromStreamAcc } from './tool-call-acc.mjs';
|
|
16
|
-
import { attachPartial, attachReportedUsage, stampCompatOutcome } from './stream-state.mjs';
|
|
16
|
+
import { attachPartial, attachReportedUsage, isIncompleteFinishReason, stampCompatOutcome } from './stream-state.mjs';
|
|
17
17
|
|
|
18
18
|
/** Rejection for a stream that ended without a terminal event. */
|
|
19
19
|
export function incompleteStreamError(state, label) {
|
|
@@ -86,7 +86,9 @@ export function settleCompatStream(state, { label, parseToolCalls }) {
|
|
|
86
86
|
if (failing) throw finishReasonInterruption(state, failing);
|
|
87
87
|
const response = buildResponse(state);
|
|
88
88
|
let toolCalls = parseAccumulatedToolCalls(state, { label, parseToolCalls });
|
|
89
|
-
|
|
89
|
+
// A length-truncated or content-filtered call is a partial result that
|
|
90
|
+
// normalizeCompatChatResponse rejects: it must never reach the executor.
|
|
91
|
+
if (!isIncompleteFinishReason(state.stopReason) && Array.isArray(toolCalls) && toolCalls.length) {
|
|
90
92
|
for (const call of toolCalls) emitCompatToolCallOnce(state.streamEmitState, call, state.onToolCall);
|
|
91
93
|
}
|
|
92
94
|
if (state.leakedCalls.length) {
|
|
@@ -99,6 +101,7 @@ export function settleCompatStream(state, { label, parseToolCalls }) {
|
|
|
99
101
|
toolCalls,
|
|
100
102
|
stopReason: state.stopReason,
|
|
101
103
|
reasoningContent: state.sawReasoningContent ? state.reasoningContent : null,
|
|
104
|
+
reasoningSource: state.sawReasoningContent ? state.reasoningSource : null,
|
|
102
105
|
reasoningDetails: state.reasoningDetails.length ? state.reasoningDetails : null,
|
|
103
106
|
rawUsage: state.rawUsage,
|
|
104
107
|
};
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { stampStreamOutcome, STREAM_TRANSPORTS } from '../lib/stream-outcome.mjs';
|
|
8
8
|
import { createLeakGuard, createToolCallDedupe } from '../lib/leaked-toolcall.mjs';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
emitCompatToolCallOnce,
|
|
11
|
+
failingFinishReasonError,
|
|
12
|
+
synthLeakedOpenAICall,
|
|
13
|
+
} from '../openai-compat-stream-common.mjs';
|
|
10
14
|
import { chatCompletionUsage } from '../openai-compat-response-normalization.mjs';
|
|
11
15
|
import { noteAbandonedUsage } from '../../../../shared/llm/usage-context.mjs';
|
|
12
16
|
import { createToolCallAccumulator } from './tool-call-acc.mjs';
|
|
@@ -31,6 +35,8 @@ export function createCompatStreamState({
|
|
|
31
35
|
content: '',
|
|
32
36
|
reasoningContent: '',
|
|
33
37
|
sawReasoningContent: false,
|
|
38
|
+
// Where the last reasoning text came from: a delta field name or 'content_chunks'.
|
|
39
|
+
reasoningSource: null,
|
|
34
40
|
reasoningDetails: [],
|
|
35
41
|
// Both text and reasoning exposure prohibit resampling the request.
|
|
36
42
|
emittedText: false,
|
|
@@ -43,6 +49,7 @@ export function createCompatStreamState({
|
|
|
43
49
|
streamEmitState: { emittedToolCallKeys: new Set(), emittedToolCall: false, _toolDedupe: toolDedupe },
|
|
44
50
|
leakGuard: createLeakGuard({ knownToolNames, harmony: true }),
|
|
45
51
|
leakedCalls: [],
|
|
52
|
+
pendingLeakedCalls: [],
|
|
46
53
|
};
|
|
47
54
|
}
|
|
48
55
|
|
|
@@ -71,16 +78,39 @@ export function appendText(state, text) {
|
|
|
71
78
|
}
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
|
|
81
|
+
/** A length-truncated or content-filtered turn is a partial result:
|
|
82
|
+
* normalizeCompatChatResponse rejects it, so no tool call of it may execute. */
|
|
83
|
+
export function isIncompleteFinishReason(finishReason) {
|
|
84
|
+
return finishReason === 'length' || finishReason === 'content_filter';
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Whether `finish_reason` confirms a normal end of the turn: present, not an
|
|
88
|
+
* incomplete outcome and not a gateway-reported failure (network_error/error). */
|
|
89
|
+
export function isNormalFinishReason(finishReason) {
|
|
90
|
+
return Boolean(finishReason) && !isIncompleteFinishReason(finishReason) && !failingFinishReasonError(finishReason, '');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Dispatch held leaked calls once a normal finish_reason confirms the turn
|
|
94
|
+
* ended. Otherwise they stay on `leakedCalls` (partial tool calls) and never
|
|
95
|
+
* reach the executor. */
|
|
96
|
+
export function drainLeakedCalls(state) {
|
|
97
|
+
if (!isNormalFinishReason(state.stopReason)) return;
|
|
98
|
+
for (const call of state.pendingLeakedCalls.splice(0)) {
|
|
99
|
+
emitCompatToolCallOnce(state.streamEmitState, call, state.onToolCall);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function recordLeakedCall(state, recovered) {
|
|
75
104
|
const call = synthLeakedOpenAICall(recovered);
|
|
76
|
-
|
|
105
|
+
state.pendingLeakedCalls.push(call);
|
|
77
106
|
reportProgress(state, 'tool');
|
|
78
107
|
return call;
|
|
79
108
|
}
|
|
80
109
|
|
|
81
110
|
function relayGuarded(state, { text, calls }) {
|
|
82
111
|
if (text) appendText(state, text);
|
|
83
|
-
for (const c of calls) state.leakedCalls.push(
|
|
112
|
+
for (const c of calls) state.leakedCalls.push(recordLeakedCall(state, c));
|
|
113
|
+
drainLeakedCalls(state);
|
|
84
114
|
}
|
|
85
115
|
|
|
86
116
|
/** Route a text delta through the leak guard, dispatching rescued calls. */
|
|
@@ -113,9 +143,9 @@ export function noteReportedUsage(state) {
|
|
|
113
143
|
}
|
|
114
144
|
|
|
115
145
|
/** Keep the partial output on the error for upstream salvage: the text, the
|
|
116
|
-
* recovered leaked calls
|
|
117
|
-
* the stream finishes) and whether a
|
|
118
|
-
* streaming. */
|
|
146
|
+
* recovered leaked calls (none dispatched unless a normal finish_reason
|
|
147
|
+
* arrived; native calls only dispatch once the stream finishes) and whether a
|
|
148
|
+
* native call's arguments were still streaming. */
|
|
119
149
|
export function attachPartial(state, err) {
|
|
120
150
|
try {
|
|
121
151
|
err.partialContent = state.content;
|
package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs
CHANGED
|
@@ -35,15 +35,8 @@ export function mergeToolCallDelta(acc, deltaCalls) {
|
|
|
35
35
|
if (tc.id) prev.id = tc.id;
|
|
36
36
|
if (tc.type) prev.type = tc.type;
|
|
37
37
|
if (tc.function?.name && !prev.function.name) prev.function.name = tc.function.name;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
// Preserve support for providers that repeat cumulative arguments.
|
|
41
|
-
if (prev.function.arguments && delta.startsWith(prev.function.arguments)) {
|
|
42
|
-
prev.function.arguments = delta;
|
|
43
|
-
} else {
|
|
44
|
-
prev.function.arguments += delta;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
38
|
+
// Argument fragments are deltas: always append, never infer snapshots.
|
|
39
|
+
if (tc.function?.arguments) prev.function.arguments += tc.function.arguments;
|
|
47
40
|
}
|
|
48
41
|
}
|
|
49
42
|
|
|
@@ -14,7 +14,7 @@ function resetAtFrom(wire, now) {
|
|
|
14
14
|
if (wire?.resets_in_seconds != null && Number.isFinite(inSeconds) && inSeconds >= 0) {
|
|
15
15
|
return now + Math.ceil(inSeconds * 1000);
|
|
16
16
|
}
|
|
17
|
-
const raw = wire?.resets_at ?? wire?.reset_at;
|
|
17
|
+
const raw = wire?.resets_at ?? wire?.reset_at ?? wire?.metadata?.resets_at;
|
|
18
18
|
if (raw == null || raw === '') return null;
|
|
19
19
|
const numeric = Number(raw);
|
|
20
20
|
if (Number.isFinite(numeric) && numeric > 0) return numeric < 1e12 ? Math.round(numeric * 1000) : Math.round(numeric);
|
|
@@ -34,6 +34,25 @@ export async function fetchCompatModelItems(provider, { signal = null, keyless =
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// Provider-native chat-ness: Together `type`, Mistral `capabilities`. Returns a
|
|
38
|
+
// sanitize-compatible mode, or null when the listing says nothing.
|
|
39
|
+
function nativeMode(m) {
|
|
40
|
+
const type = typeof m?.type === 'string' ? m.type.trim().toLowerCase() : '';
|
|
41
|
+
if (type === 'chat') return 'chat';
|
|
42
|
+
if (type === 'language' || type === 'code') return 'completion';
|
|
43
|
+
if (['embedding', 'embeddings', 'image', 'audio', 'rerank', 'moderation', 'video', 'transcribe'].includes(type)) {
|
|
44
|
+
return type;
|
|
45
|
+
}
|
|
46
|
+
// OpenRouter: a model that cannot emit text (image/audio generation) is no chat model.
|
|
47
|
+
const outputs = m?.architecture?.output_modalities;
|
|
48
|
+
if (Array.isArray(outputs) && outputs.length && !outputs.includes('text')) return 'non_chat';
|
|
49
|
+
const caps = m?.capabilities;
|
|
50
|
+
if (caps && typeof caps === 'object' && typeof caps.completion_chat === 'boolean') {
|
|
51
|
+
return caps.completion_chat ? 'chat' : 'non_chat';
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
37
56
|
export async function listCompatModels(provider, { throwOnError = false, signal = null } = {}) {
|
|
38
57
|
try {
|
|
39
58
|
const list = await provider._fetchModelItems({ signal });
|
|
@@ -45,10 +64,23 @@ export async function listCompatModels(provider, { throwOnError = false, signal
|
|
|
45
64
|
m?.max_input_tokens ??
|
|
46
65
|
m?.max_model_len ??
|
|
47
66
|
m?.context_length ??
|
|
67
|
+
m?.max_context_length ??
|
|
68
|
+
m?.top_provider?.context_length ??
|
|
48
69
|
m?.contextWindow ??
|
|
49
70
|
0
|
|
50
71
|
);
|
|
51
|
-
const outputTokens = Number(
|
|
72
|
+
const outputTokens = Number(
|
|
73
|
+
m?.max_output_tokens ??
|
|
74
|
+
m?.output_tokens ??
|
|
75
|
+
m?.maxOutputTokens ??
|
|
76
|
+
m?.top_provider?.max_completion_tokens ??
|
|
77
|
+
0
|
|
78
|
+
);
|
|
79
|
+
const mode = nativeMode(m);
|
|
80
|
+
// A catalog alias (OpenRouter `~anthropic/claude-opus-latest`) keeps its
|
|
81
|
+
// own slug for routing; the slug it currently points at is retained for
|
|
82
|
+
// capability lookup only.
|
|
83
|
+
const aliasTarget = typeof m?.alias_target === 'string' ? m.alias_target : m?.alias_target?.slug;
|
|
52
84
|
models.push({
|
|
53
85
|
id: m?.id,
|
|
54
86
|
name: m?.id,
|
|
@@ -56,10 +88,23 @@ export async function listCompatModels(provider, { throwOnError = false, signal
|
|
|
56
88
|
contextWindow: Number.isFinite(contextWindow) && contextWindow > 0 ? contextWindow : 0,
|
|
57
89
|
outputTokens: Number.isFinite(outputTokens) && outputTokens > 0 ? outputTokens : null,
|
|
58
90
|
created: typeof m?.created === 'number' ? m.created : null,
|
|
91
|
+
...(mode ? { mode } : {}),
|
|
92
|
+
...(typeof aliasTarget === 'string' && aliasTarget ? { aliasTarget } : {}),
|
|
59
93
|
});
|
|
60
94
|
}
|
|
61
95
|
const filtered = models.filter((m) => m.id);
|
|
62
|
-
|
|
96
|
+
// The catalog fills gaps only: native limits and chat-ness are restored
|
|
97
|
+
// over whatever enrichment derived.
|
|
98
|
+
const enrichedRows = (await enrichModels(filtered)).map((row, i) => {
|
|
99
|
+
const native = filtered[i];
|
|
100
|
+
return {
|
|
101
|
+
...row,
|
|
102
|
+
...(native.contextWindow ? { contextWindow: native.contextWindow } : {}),
|
|
103
|
+
...(native.outputTokens ? { outputTokens: native.outputTokens } : {}),
|
|
104
|
+
...(native.mode ? { mode: native.mode } : {}),
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
const enriched = sanitizeModelList(enrichedRows, { provider: provider.name });
|
|
63
108
|
provider._enrichedModels = enriched;
|
|
64
109
|
return enriched;
|
|
65
110
|
} catch (error) {
|
|
@@ -12,6 +12,41 @@ function normalizeReasoningEffort(value, allowed) {
|
|
|
12
12
|
return allowed.includes(effort) ? effort : null;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* OpenRouter's unified `reasoning` field, shared by its Chat and Responses
|
|
17
|
+
* wires: `openRouterReasoningEffort`, else the turn effort, else the configured
|
|
18
|
+
* effort; `none` disables reasoning. Null when no effort applies.
|
|
19
|
+
*/
|
|
20
|
+
export function openRouterReasoning(opts = {}, config = {}) {
|
|
21
|
+
const effort = normalizeReasoningEffort(opts.openRouterReasoningEffort ?? opts.effort ?? config?.reasoningEffort, [
|
|
22
|
+
'none',
|
|
23
|
+
'minimal',
|
|
24
|
+
'low',
|
|
25
|
+
'medium',
|
|
26
|
+
'high',
|
|
27
|
+
'xhigh',
|
|
28
|
+
'max',
|
|
29
|
+
]);
|
|
30
|
+
if (effort === 'none') return { enabled: false };
|
|
31
|
+
return effort ? { enabled: true, effort } : null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function deepseekRawEffort(opts, config) {
|
|
35
|
+
return opts.deepseekReasoningEffort ?? opts.effort ?? config?.reasoningEffort;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** 'enabled' | 'disabled' as the DeepSeek request will carry it, or null when nothing sets it. */
|
|
39
|
+
export function deepseekThinkingMode(opts = {}, config = {}) {
|
|
40
|
+
const rawThinking = opts.deepseekThinking ?? opts.thinking ?? config?.thinking;
|
|
41
|
+
const rawEffort = deepseekRawEffort(opts, config);
|
|
42
|
+
if (rawThinking === undefined && rawEffort === undefined) return null;
|
|
43
|
+
const thinkingMode = String(rawThinking?.type ?? rawThinking ?? rawEffort)
|
|
44
|
+
.trim()
|
|
45
|
+
.toLowerCase();
|
|
46
|
+
const disabled = rawThinking === false || thinkingMode === 'disabled' || thinkingMode === 'none';
|
|
47
|
+
return disabled ? 'disabled' : 'enabled';
|
|
48
|
+
}
|
|
49
|
+
|
|
15
50
|
// Keep provider extensions isolated: fields accepted by one OpenAI-compatible
|
|
16
51
|
// backend are frequently rejected by another even when the core Chat schema
|
|
17
52
|
// is shared.
|
|
@@ -23,22 +58,14 @@ export function applyCompatProviderChatOptions(params, providerName, opts = {},
|
|
|
23
58
|
protocol: 'openai-chat',
|
|
24
59
|
model: modelInfo,
|
|
25
60
|
effort: opts.effort ?? config?.reasoningEffort,
|
|
61
|
+
baseURL: config?.baseURL,
|
|
26
62
|
});
|
|
27
63
|
Object.assign(params, fields);
|
|
28
64
|
return params;
|
|
29
65
|
}
|
|
30
66
|
if (providerName === 'openrouter') {
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
'minimal',
|
|
34
|
-
'low',
|
|
35
|
-
'medium',
|
|
36
|
-
'high',
|
|
37
|
-
'xhigh',
|
|
38
|
-
'max',
|
|
39
|
-
]);
|
|
40
|
-
if (effort === 'none') params.reasoning = { enabled: false };
|
|
41
|
-
else if (effort) params.reasoning = { enabled: true, effort };
|
|
67
|
+
const reasoning = openRouterReasoning(opts, config);
|
|
68
|
+
if (reasoning) params.reasoning = reasoning;
|
|
42
69
|
return params;
|
|
43
70
|
}
|
|
44
71
|
if (providerName === 'xai') {
|
|
@@ -53,22 +80,17 @@ export function applyCompatProviderChatOptions(params, providerName, opts = {},
|
|
|
53
80
|
return params;
|
|
54
81
|
}
|
|
55
82
|
if (providerName === 'deepseek') {
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
.toLowerCase();
|
|
62
|
-
const disabled = rawThinking === false || thinkingMode === 'disabled' || thinkingMode === 'none';
|
|
63
|
-
params.thinking = { type: disabled ? 'disabled' : 'enabled' };
|
|
64
|
-
if (!disabled) {
|
|
65
|
-
const effort = String(rawEffort ?? '')
|
|
83
|
+
const mode = deepseekThinkingMode(opts, config);
|
|
84
|
+
if (mode) {
|
|
85
|
+
params.thinking = { type: mode };
|
|
86
|
+
if (mode === 'enabled') {
|
|
87
|
+
const effort = String(deepseekRawEffort(opts, config) ?? '')
|
|
66
88
|
.trim()
|
|
67
89
|
.toLowerCase();
|
|
68
|
-
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
else if (effort === 'low') params.reasoning_effort = 'low';
|
|
90
|
+
// DeepSeek documents low/high/max; `ultra` is its alias for max,
|
|
91
|
+
// `minimal` for low, `medium`/`xhigh` for high; `low` must not be promoted.
|
|
92
|
+
if (effort === 'max' || effort === 'ultra') params.reasoning_effort = 'max';
|
|
93
|
+
else if (effort === 'low' || effort === 'minimal') params.reasoning_effort = 'low';
|
|
72
94
|
else if (['medium', 'high', 'xhigh'].includes(effort)) params.reasoning_effort = 'high';
|
|
73
95
|
}
|
|
74
96
|
}
|