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
|
@@ -11,12 +11,16 @@ export const OPENAI_COMPAT_PRESETS = {
|
|
|
11
11
|
},
|
|
12
12
|
// OpenCode Go - low-cost coding-model subscription gateway.
|
|
13
13
|
'opencode-go': {
|
|
14
|
-
baseURL: 'https://opencode.ai/
|
|
14
|
+
baseURL: 'https://opencode.ai/inference/go/v1',
|
|
15
15
|
defaultModel: 'glm-5.2',
|
|
16
|
+
// The gateway expects an application User-Agent (not the SDK default).
|
|
17
|
+
extraHeaders: { 'User-Agent': 'mixdog' },
|
|
16
18
|
},
|
|
17
19
|
openrouter: {
|
|
18
20
|
baseURL: 'https://openrouter.ai/api/v1',
|
|
19
21
|
defaultModel: 'openrouter/auto',
|
|
22
|
+
// OpenRouter documents cache_control on Chat content blocks.
|
|
23
|
+
chatCacheControl: true,
|
|
20
24
|
extraHeaders: {
|
|
21
25
|
'HTTP-Referer': 'https://github.com/tribgames/mixdog',
|
|
22
26
|
'X-OpenRouter-Title': 'mixdog',
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* openai-compat-reasoning-field.mjs — provider-specific reasoning shapes on the
|
|
3
|
+
* Chat Completions wire that the plain `reasoning_content` string path misses.
|
|
4
|
+
*
|
|
5
|
+
* Together AI (docs.together.ai/docs/inference/chat/reasoning): the chain of
|
|
6
|
+
* thought arrives on `reasoning` OR `reasoning_content` (model dependent), on
|
|
7
|
+
* the message and on each streaming delta, and must be passed back "under the
|
|
8
|
+
* same key" on prior assistant turns. vLLM reports it on `reasoning` (formerly
|
|
9
|
+
* `reasoning_content`), Groq on `message.reasoning` (reasoning_format parsed).
|
|
10
|
+
* OpenRouter reports plain text on `reasoning` next to `reasoning_details`.
|
|
11
|
+
*
|
|
12
|
+
* Mistral (docs.mistral.ai/studio/conversations/reasoning): with reasoning on,
|
|
13
|
+
* `message.content` / `delta.content` is a list of typed chunks —
|
|
14
|
+
* `{type:'thinking', thinking:[{type:'text', text}]}` and `{type:'text', text}`
|
|
15
|
+
* — and the full assistant message, thinking chunk included, goes back in the
|
|
16
|
+
* history. Receiving is by the response shape (an array), never by model name.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/** `message.providerMetadata[key].reasoningField`: the key a reply's reasoning arrived on. */
|
|
20
|
+
export const COMPAT_REASONING_METADATA_KEY = 'openaiCompat';
|
|
21
|
+
|
|
22
|
+
const TOGETHER_HOSTS = ['together.xyz', 'together.ai'];
|
|
23
|
+
const GROQ_HOSTS = ['groq.com'];
|
|
24
|
+
const MISTRAL_HOSTS = ['mistral.ai'];
|
|
25
|
+
|
|
26
|
+
function hostMatches(baseURL, domains) {
|
|
27
|
+
let host;
|
|
28
|
+
try {
|
|
29
|
+
host = new URL(String(baseURL || '')).hostname.toLowerCase();
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return domains.some((domain) => host === domain || host.endsWith(`.${domain}`));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function isTogetherBaseURL(baseURL) {
|
|
37
|
+
return hostMatches(baseURL, TOGETHER_HOSTS);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Where an endpoint family reports reasoning and how a prior turn's reasoning
|
|
42
|
+
* goes back. `readsReasoningAlias`: the `reasoning` key is a reasoning field
|
|
43
|
+
* (otherwise only `reasoning_content` is). `resend`:
|
|
44
|
+
* same_key — back under the key it arrived on (Together, vLLM)
|
|
45
|
+
* reasoning — plain text as `reasoning`; reasoning_details win (OpenRouter)
|
|
46
|
+
* content_chunks — as a `thinking` chunk in the assistant content (Mistral)
|
|
47
|
+
* none — never echoed; the docs do not ask for it (Groq)
|
|
48
|
+
*/
|
|
49
|
+
const SHAPES = Object.freeze({
|
|
50
|
+
together: Object.freeze({ id: 'together', readsReasoningAlias: true, resend: 'same_key' }),
|
|
51
|
+
vllm: Object.freeze({ id: 'vllm', readsReasoningAlias: true, resend: 'same_key' }),
|
|
52
|
+
groq: Object.freeze({ id: 'groq', readsReasoningAlias: true, resend: 'none' }),
|
|
53
|
+
mistral: Object.freeze({ id: 'mistral', readsReasoningAlias: false, resend: 'content_chunks' }),
|
|
54
|
+
openrouter: Object.freeze({ id: 'openrouter', readsReasoningAlias: true, resend: 'reasoning' }),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The reasoning shape of a provider, or null for the plain `reasoning_content`
|
|
59
|
+
* path. OpenRouter is by provider name, Together/Groq/Mistral by the provider's
|
|
60
|
+
* own base URL, vLLM (no fixed host) by the model row's `vllm` wire format.
|
|
61
|
+
*/
|
|
62
|
+
export function compatReasoningShape({ providerName, baseURL, wireFormat } = {}) {
|
|
63
|
+
if (providerName === 'openrouter') return SHAPES.openrouter;
|
|
64
|
+
if (wireFormat === 'together' || isTogetherBaseURL(baseURL)) return SHAPES.together;
|
|
65
|
+
if (wireFormat === 'vllm') return SHAPES.vllm;
|
|
66
|
+
if (hostMatches(baseURL, GROQ_HOSTS)) return SHAPES.groq;
|
|
67
|
+
if (hostMatches(baseURL, MISTRAL_HOSTS)) return SHAPES.mistral;
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The receive field worth recording for replay: `reasoning` (non-default key)
|
|
73
|
+
* or `content_chunks` (Mistral), per shape; `reasoning_content` is the default
|
|
74
|
+
* and needs no record. Null when nothing needs remembering.
|
|
75
|
+
*/
|
|
76
|
+
export function replayReasoningField(shape, source) {
|
|
77
|
+
if (!shape) return null;
|
|
78
|
+
if (shape.resend === 'same_key' && source === 'reasoning') return 'reasoning';
|
|
79
|
+
if (shape.resend === 'content_chunks' && source === 'content_chunks') return 'content_chunks';
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** Whether a reply's reasoning source is captured under this shape. */
|
|
84
|
+
export function capturesShapeReasoning(shape, source) {
|
|
85
|
+
if (!shape) return source === 'content_chunks';
|
|
86
|
+
if (source === 'content_chunks') return true;
|
|
87
|
+
return source === 'reasoning_content' || (shape.readsReasoningAlias && source === 'reasoning');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Assistant content with the prior reasoning replayed as a leading `thinking` chunk. */
|
|
91
|
+
export function contentWithThinkingChunk(content, reasoning) {
|
|
92
|
+
const thinking = { type: 'thinking', thinking: [{ type: 'text', text: reasoning }] };
|
|
93
|
+
if (Array.isArray(content)) return [thinking, ...content];
|
|
94
|
+
return typeof content === 'string' && content ? [thinking, { type: 'text', text: content }] : [thinking];
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function thinkingText(thinking) {
|
|
98
|
+
if (typeof thinking === 'string') return thinking;
|
|
99
|
+
if (!Array.isArray(thinking)) return '';
|
|
100
|
+
return thinking
|
|
101
|
+
.map((inner) => (typeof inner === 'string' ? inner : typeof inner?.text === 'string' ? inner.text : ''))
|
|
102
|
+
.join('');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Ordered `{kind:'reasoning'|'text', text}` parts of an array-shaped `content`,
|
|
107
|
+
* or null when `content` is not an array (the plain string/absent shape).
|
|
108
|
+
*/
|
|
109
|
+
export function chatContentParts(content) {
|
|
110
|
+
if (!Array.isArray(content)) return null;
|
|
111
|
+
const parts = [];
|
|
112
|
+
for (const chunk of content) {
|
|
113
|
+
if (typeof chunk === 'string') {
|
|
114
|
+
parts.push({ kind: 'text', text: chunk });
|
|
115
|
+
} else if (chunk?.type === 'thinking') {
|
|
116
|
+
parts.push({ kind: 'reasoning', text: thinkingText(chunk.thinking) });
|
|
117
|
+
} else if (chunk?.type === 'text' && typeof chunk.text === 'string') {
|
|
118
|
+
parts.push({ kind: 'text', text: chunk.text });
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return parts;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Content text, reasoning and reasoning source of one non-streaming message.
|
|
126
|
+
* `reasoning_content` keeps priority; the `reasoning` alias is read only under
|
|
127
|
+
* a shape that reports reasoning there; thinking chunks fill in when no field
|
|
128
|
+
* carried reasoning.
|
|
129
|
+
*/
|
|
130
|
+
export function readChatMessage(message, { shape = null } = {}) {
|
|
131
|
+
const parts = chatContentParts(message?.content);
|
|
132
|
+
const content = parts
|
|
133
|
+
? parts
|
|
134
|
+
.filter((part) => part.kind === 'text')
|
|
135
|
+
.map((part) => part.text)
|
|
136
|
+
.join('')
|
|
137
|
+
: typeof message?.content === 'string'
|
|
138
|
+
? message.content
|
|
139
|
+
: '';
|
|
140
|
+
if (typeof message?.reasoning_content === 'string') {
|
|
141
|
+
return { content, reasoningContent: message.reasoning_content, reasoningSource: 'reasoning_content' };
|
|
142
|
+
}
|
|
143
|
+
if (shape?.readsReasoningAlias && typeof message?.reasoning === 'string') {
|
|
144
|
+
return { content, reasoningContent: message.reasoning, reasoningSource: 'reasoning' };
|
|
145
|
+
}
|
|
146
|
+
const thinking = parts?.filter((part) => part.kind === 'reasoning');
|
|
147
|
+
if (thinking?.length) {
|
|
148
|
+
return { content, reasoningContent: thinking.map((part) => part.text).join(''), reasoningSource: 'content_chunks' };
|
|
149
|
+
}
|
|
150
|
+
return { content, reasoningContent: null, reasoningSource: null };
|
|
151
|
+
}
|
|
@@ -7,20 +7,20 @@ import {
|
|
|
7
7
|
writeXaiResponsesCacheTrace,
|
|
8
8
|
} from './openai-compat-xai.mjs';
|
|
9
9
|
import { createProviderReplay } from './lib/provider-replay.mjs';
|
|
10
|
+
import { reportedCostUsd } from './lib/usage-primitives.mjs';
|
|
10
11
|
import { stampStreamOutcome, STREAM_TRANSPORTS } from './lib/stream-outcome.mjs';
|
|
11
12
|
import { failingFinishReasonError } from './openai-compat-stream-common.mjs';
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
import {
|
|
14
|
+
COMPAT_REASONING_METADATA_KEY,
|
|
15
|
+
capturesShapeReasoning,
|
|
16
|
+
replayReasoningField,
|
|
17
|
+
} from './openai-compat-reasoning-field.mjs';
|
|
15
18
|
|
|
16
19
|
export function compatReportedCostUsd(providerName, usage) {
|
|
17
|
-
if (providerName === 'openrouter')
|
|
18
|
-
const cost = reportedNumber(usage?.cost);
|
|
19
|
-
return Number.isFinite(cost) && cost >= 0 ? cost : undefined;
|
|
20
|
-
}
|
|
20
|
+
if (providerName === 'openrouter') return reportedCostUsd(usage?.cost);
|
|
21
21
|
if (providerName === 'xai') {
|
|
22
|
-
const ticks =
|
|
23
|
-
return
|
|
22
|
+
const ticks = reportedCostUsd(usage?.cost_in_usd_ticks);
|
|
23
|
+
return ticks === undefined ? undefined : Number((ticks * 1e-10).toFixed(8));
|
|
24
24
|
}
|
|
25
25
|
return undefined;
|
|
26
26
|
}
|
|
@@ -79,12 +79,11 @@ export function traceCompatResponseUsage({
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
// Responses-wire reported cost:
|
|
83
|
-
//
|
|
82
|
+
// Responses-wire reported cost: xAI `cost_in_usd_ticks` when present, else a
|
|
83
|
+
// gateway `cost` (decimal USD). null/empty/negative is "not reported", never a
|
|
84
|
+
// reported $0.
|
|
84
85
|
export function responsesReportedCostUsd(usage) {
|
|
85
|
-
|
|
86
|
-
if (Number.isFinite(cost) && cost >= 0) return cost;
|
|
87
|
-
return costUsdFromTicks(usage?.cost_in_usd_ticks);
|
|
86
|
+
return costUsdFromTicks(usage?.cost_in_usd_ticks) ?? reportedCostUsd(usage?.cost);
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
export function chatCompletionUsage(providerName, usage) {
|
|
@@ -138,6 +137,7 @@ export function normalizeCompatChatResponse({
|
|
|
138
137
|
cacheRoutingKey,
|
|
139
138
|
cacheRouting,
|
|
140
139
|
replaysReasoningContent,
|
|
140
|
+
reasoningShape = null,
|
|
141
141
|
}) {
|
|
142
142
|
const response = assembled.response;
|
|
143
143
|
const choice = response.choices[0];
|
|
@@ -146,7 +146,7 @@ export function normalizeCompatChatResponse({
|
|
|
146
146
|
const failingFinish = failingFinishReasonError(stopReason, providerName);
|
|
147
147
|
if (failingFinish) {
|
|
148
148
|
const err = failingFinish;
|
|
149
|
-
const partialContent =
|
|
149
|
+
const partialContent = assembled.content || '';
|
|
150
150
|
Object.assign(err, {
|
|
151
151
|
partialContent,
|
|
152
152
|
partialToolCalls: Array.isArray(toolCalls) && toolCalls.length ? toolCalls : undefined,
|
|
@@ -173,7 +173,7 @@ export function normalizeCompatChatResponse({
|
|
|
173
173
|
code: 'PROVIDER_INCOMPLETE',
|
|
174
174
|
providerIncomplete: true,
|
|
175
175
|
finishReason: stopReason,
|
|
176
|
-
partialContent:
|
|
176
|
+
partialContent: assembled.content || '',
|
|
177
177
|
partialToolCalls: toolCalls,
|
|
178
178
|
model: response.model || useModel,
|
|
179
179
|
responseId: response.id || null,
|
|
@@ -205,14 +205,30 @@ export function normalizeCompatChatResponse({
|
|
|
205
205
|
cachedTokens: extractCompatCachedTokens(response.usage),
|
|
206
206
|
});
|
|
207
207
|
}
|
|
208
|
+
// Together/vLLM/Groq/OpenRouter report reasoning on `reasoning` or
|
|
209
|
+
// `reasoning_content`; Mistral reports it as thinking chunks inside
|
|
210
|
+
// `content`. Both are captured by the provider's own shape / the response
|
|
211
|
+
// shape, whatever the replay flag says.
|
|
212
|
+
const reasoningField = replayReasoningField(reasoningShape, assembled.reasoningSource);
|
|
208
213
|
const capturesReasoningContent =
|
|
209
|
-
providerName === 'deepseek' ||
|
|
214
|
+
providerName === 'deepseek' ||
|
|
215
|
+
providerName === 'xai' ||
|
|
216
|
+
providerName === 'mixdog-local' ||
|
|
217
|
+
replaysReasoningContent ||
|
|
218
|
+
capturesShapeReasoning(reasoningShape, assembled.reasoningSource);
|
|
210
219
|
const reasoningContent =
|
|
211
220
|
capturesReasoningContent && typeof assembled.reasoningContent === 'string' ? assembled.reasoningContent : null;
|
|
212
221
|
const reasoningDetails =
|
|
213
222
|
providerName === 'openrouter' && Array.isArray(choice?.message?.reasoning_details)
|
|
214
223
|
? choice.message.reasoning_details
|
|
215
224
|
: null;
|
|
225
|
+
// Replay sends reasoning back under the field it arrived on.
|
|
226
|
+
const providerMetadata = {
|
|
227
|
+
...(reasoningDetails?.length ? { openrouter: { reasoning_details: reasoningDetails } } : {}),
|
|
228
|
+
...(reasoningContent !== null && reasoningField
|
|
229
|
+
? { [COMPAT_REASONING_METADATA_KEY]: { reasoningField } }
|
|
230
|
+
: {}),
|
|
231
|
+
};
|
|
216
232
|
return {
|
|
217
233
|
content: assembled.content || '',
|
|
218
234
|
// Streamed chunks can omit `model`; fall back to the requested
|
|
@@ -228,11 +244,7 @@ export function normalizeCompatChatResponse({
|
|
|
228
244
|
// instead of silently treating a truncated answer as complete.
|
|
229
245
|
...(stopReason === 'length' && (assembled.content || '').length > 0 ? { truncated: true } : {}),
|
|
230
246
|
...(reasoningContent !== null ? { reasoningContent } : {}),
|
|
231
|
-
...(
|
|
232
|
-
? {
|
|
233
|
-
providerMetadata: { openrouter: { reasoning_details: reasoningDetails } },
|
|
234
|
-
}
|
|
235
|
-
: {}),
|
|
247
|
+
...(Object.keys(providerMetadata).length ? { providerMetadata } : {}),
|
|
236
248
|
usage: response.usage ? chatCompletionUsage(providerName, response.usage) : undefined,
|
|
237
249
|
};
|
|
238
250
|
}
|
|
@@ -332,8 +344,14 @@ export function normalizeXaiResponsesWebSocket({
|
|
|
332
344
|
cacheLane,
|
|
333
345
|
}) {
|
|
334
346
|
const responseId = result.responseId || previousResponseId || null;
|
|
335
|
-
|
|
336
|
-
|
|
347
|
+
// The WS send result drops the collector's `responseItems`; its own
|
|
348
|
+
// owner-tagged `providerReplay` (traceProvider 'xai') still carries every
|
|
349
|
+
// output item in order: encrypted reasoning and server-executed tool_search
|
|
350
|
+
// call/output pairs. Always taken, so they survive to the next turn as xAI
|
|
351
|
+
// requires.
|
|
352
|
+
const responseItems = result.responseItems ?? result.providerReplay?.items;
|
|
353
|
+
const encryptedReasoningItems = encryptedXaiReasoningItems(responseItems);
|
|
354
|
+
const providerReplay = createProviderReplay('xai-responses', responseItems);
|
|
337
355
|
const encryptedReasoningHistory = xaiEncryptedReasoningHistory(opts, messages, encryptedReasoningItems);
|
|
338
356
|
const rawUsage = result.usage?.raw || result.usage || null;
|
|
339
357
|
const response = {
|
|
@@ -3,11 +3,17 @@
|
|
|
3
3
|
// carries the label, the caller callbacks and the leaked-text relay.
|
|
4
4
|
import { typedStatusFrom } from './retry-classifier.mjs';
|
|
5
5
|
import { applyCompatErrorContract } from './openai-compat-error-contract.mjs';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
customToolCallFromResponseItem,
|
|
8
|
+
nativeToolSearchCallFromArguments,
|
|
9
|
+
withToolCallNamespace,
|
|
10
|
+
} from './custom-tool-wire.mjs';
|
|
11
|
+
import { createRefusals } from './openai-ws-response-state/refusals.mjs';
|
|
7
12
|
import { emitCompatToolCallOnce } from './openai-compat-stream-common.mjs';
|
|
8
13
|
import { truncatedCompatStreamError, parseCompletedToolCallArgumentsJson } from './lib/openai-tool-args.mjs';
|
|
9
14
|
import { incompleteReasonFromEvent, isMaxOutputIncompleteReason } from './lib/responses-terminal-fields.mjs';
|
|
10
15
|
import { responsesUsage } from './openai-compat-response-normalization.mjs';
|
|
16
|
+
import { normalizeGatewayErrorDetail } from './provider-error-kind.mjs';
|
|
11
17
|
|
|
12
18
|
// An incomplete response was still billed: carry its reported usage on the
|
|
13
19
|
// error so the provider-boundary accounting records it.
|
|
@@ -35,7 +41,9 @@ function signal(ctx, kind) {
|
|
|
35
41
|
// through the fatal-code deny-list / default-retry classification.
|
|
36
42
|
function typedResponsesFailure(message, event) {
|
|
37
43
|
const err = new Error(message);
|
|
38
|
-
|
|
44
|
+
// A gateway's canonical error_type (OpenRouter's top-level `error_type`)
|
|
45
|
+
// replaces the lossy native code before anything classifies it.
|
|
46
|
+
const detail = normalizeGatewayErrorDetail(event?.response?.error || event?.error || null, event);
|
|
39
47
|
const typed = typedStatusFrom(detail, event);
|
|
40
48
|
if (typed) err.httpStatus = typed;
|
|
41
49
|
const code = detail?.code ?? detail?.type ?? event?.code ?? null;
|
|
@@ -61,18 +69,22 @@ function reconcileCompatFunctionCallItem(state, item, label, onToolCall) {
|
|
|
61
69
|
if (tc) {
|
|
62
70
|
if (!tc.id && item.call_id) tc.id = item.call_id;
|
|
63
71
|
if (!tc.name && item.name) tc.name = item.name;
|
|
72
|
+
withToolCallNamespace(tc, item);
|
|
64
73
|
if (tc.id && tc.name) delete tc._pendingItemId;
|
|
65
74
|
emitCompatToolCallOnce(state, tc, onToolCall);
|
|
66
75
|
} else if (item.call_id && item.name) {
|
|
67
|
-
const call =
|
|
68
|
-
|
|
69
|
-
name: item.name,
|
|
70
|
-
arguments: parseCompletedToolCallArgumentsJson(item.arguments, label, {
|
|
76
|
+
const call = withToolCallNamespace(
|
|
77
|
+
{
|
|
71
78
|
id: item.call_id,
|
|
72
79
|
name: item.name,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
80
|
+
arguments: parseCompletedToolCallArgumentsJson(item.arguments, label, {
|
|
81
|
+
id: item.call_id,
|
|
82
|
+
name: item.name,
|
|
83
|
+
finishReason: 'done',
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
item
|
|
87
|
+
);
|
|
76
88
|
state.toolCalls.push(call);
|
|
77
89
|
emitCompatToolCallOnce(state, call, onToolCall);
|
|
78
90
|
}
|
|
@@ -81,6 +93,9 @@ function reconcileCompatFunctionCallItem(state, item, label, onToolCall) {
|
|
|
81
93
|
|
|
82
94
|
function pushToolSearchCall(state, item, ctx) {
|
|
83
95
|
if (item?.type !== 'tool_search_call') return;
|
|
96
|
+
// Server-executed search already ran inside the response; it stays in
|
|
97
|
+
// providerReplay only and is never a local load_tool dispatch.
|
|
98
|
+
if (item.execution === 'server') return;
|
|
84
99
|
const callId = item.call_id || item.id || '';
|
|
85
100
|
if (!callId || state.toolCalls.some((call) => call.id === callId)) return;
|
|
86
101
|
const searchArgs =
|
|
@@ -165,10 +180,10 @@ function onReasoningDelta(event, state, ctx) {
|
|
|
165
180
|
function onOutputItemAdded(event, state, ctx) {
|
|
166
181
|
const type = event.item?.type;
|
|
167
182
|
if (type === 'function_call') {
|
|
168
|
-
state.pendingCalls.set(
|
|
169
|
-
|
|
170
|
-
callId: event.item.call_id || '',
|
|
171
|
-
|
|
183
|
+
state.pendingCalls.set(
|
|
184
|
+
event.item.id || '',
|
|
185
|
+
withToolCallNamespace({ name: event.item.name || '', callId: event.item.call_id || '' }, event.item)
|
|
186
|
+
);
|
|
172
187
|
state.toolTracker?.mark(event.item);
|
|
173
188
|
state.toolInFlight = true;
|
|
174
189
|
} else if (type === 'custom_tool_call' || type === 'tool_search_call') {
|
|
@@ -194,26 +209,47 @@ function onToolInputDelta(event, state, ctx) {
|
|
|
194
209
|
function onFunctionCallArgumentsDone(event, state, ctx) {
|
|
195
210
|
const itemId = event.item_id || '';
|
|
196
211
|
const pending = state.pendingCalls.get(itemId);
|
|
197
|
-
const call =
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
212
|
+
const call = withToolCallNamespace(
|
|
213
|
+
{
|
|
214
|
+
id: pending?.callId || event.call_id || '',
|
|
215
|
+
name: pending?.name || event.name || '',
|
|
216
|
+
// `*.done` ⇒ arguments are complete; a parse failure is
|
|
217
|
+
// deterministic bad JSON (permanent), not stream truncation.
|
|
218
|
+
arguments: parseCompletedToolCallArgumentsJson(event.arguments, ctx.label, {
|
|
219
|
+
id: pending?.callId || event.call_id,
|
|
220
|
+
name: pending?.name || event.name,
|
|
221
|
+
finishReason: 'done',
|
|
222
|
+
}),
|
|
223
|
+
_pendingItemId: itemId,
|
|
224
|
+
},
|
|
225
|
+
pending
|
|
226
|
+
);
|
|
209
227
|
state.toolCalls.push(call);
|
|
210
228
|
if (call.id && call.name) delete call._pendingItemId;
|
|
211
229
|
emitCompatToolCallOnce(state, call, ctx.onToolCall);
|
|
212
230
|
signal(ctx, 'tool');
|
|
213
231
|
}
|
|
214
232
|
|
|
233
|
+
// Refusal parts (streamed deltas, done text, final message parts) fold into
|
|
234
|
+
// one typed refusal on state.refusals; the stream collector turns it into a
|
|
235
|
+
// `stopReason:'refusal'` result instead of an empty success.
|
|
236
|
+
const refusalsOf = (state) => (state.refusals ||= createRefusals());
|
|
237
|
+
|
|
238
|
+
function onRefusalDelta(event, state, ctx) {
|
|
239
|
+
state.sawOutput = true;
|
|
240
|
+
refusalsOf(state).delta(event);
|
|
241
|
+
signal(ctx, 'semantic');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function onRefusalDone(event, state, ctx) {
|
|
245
|
+
state.sawOutput = true;
|
|
246
|
+
refusalsOf(state).done(event);
|
|
247
|
+
signal(ctx, 'semantic');
|
|
248
|
+
}
|
|
249
|
+
|
|
215
250
|
function onOutputItemDone(event, state, ctx) {
|
|
216
251
|
const item = event.item || {};
|
|
252
|
+
if (item.type === 'message') refusalsOf(state).absorbMessage(item);
|
|
217
253
|
if (item.type === 'function_call') {
|
|
218
254
|
const itemId = reconcileCompatFunctionCallItem(state, item, ctx.label, ctx.onToolCall);
|
|
219
255
|
// Drop the resolved function item from pendingCalls before
|
|
@@ -342,6 +378,8 @@ const RESPONSES_EVENT_HANDLERS = new Map([
|
|
|
342
378
|
['response.output_text.delta', onOutputTextDelta],
|
|
343
379
|
['response.reasoning_text.delta', onReasoningDelta],
|
|
344
380
|
['response.reasoning_summary_text.delta', onReasoningDelta],
|
|
381
|
+
['response.refusal.delta', onRefusalDelta],
|
|
382
|
+
['response.refusal.done', onRefusalDone],
|
|
345
383
|
['response.output_item.added', onOutputItemAdded],
|
|
346
384
|
['response.function_call_arguments.delta', onToolInputDelta],
|
|
347
385
|
['response.custom_tool_call_input.delta', onToolInputDelta],
|