mixdog 0.8.0 → 0.9.0
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 +47 -23
- package/package.json +33 -27
- package/scripts/_test-folder-dialog.mjs +30 -0
- package/scripts/agent-parallel-smoke.mjs +388 -0
- package/scripts/agent-tag-reuse-smoke.mjs +183 -0
- package/scripts/background-task-meta-smoke.mjs +38 -0
- package/scripts/boot-smoke.mjs +52 -9
- package/scripts/build-runtime-linux.sh +348 -0
- package/scripts/build-runtime-macos.sh +217 -0
- package/scripts/build-runtime-windows.ps1 +242 -0
- package/scripts/compact-active-turn-test.mjs +68 -0
- package/scripts/compact-smoke.mjs +859 -129
- package/scripts/compact-trigger-migration-smoke.mjs +187 -0
- package/scripts/fix-brief-fn.mjs +35 -0
- package/scripts/fix-format-tool-surface.mjs +24 -0
- package/scripts/fix-tool-exec-visible.mjs +42 -0
- package/scripts/generate-runtime-manifest.mjs +166 -0
- package/scripts/hook-bus-test.mjs +330 -0
- package/scripts/lead-workflow-smoke.mjs +33 -39
- package/scripts/live-worker-smoke.mjs +43 -37
- package/scripts/llm-trace-summary.mjs +315 -0
- package/scripts/memory-meta-concurrency-test.mjs +20 -0
- package/scripts/output-style-smoke.mjs +56 -15
- package/scripts/parent-abort-link-test.mjs +44 -0
- package/scripts/patch-agent-brief.mjs +48 -0
- package/scripts/patch-app.mjs +21 -0
- package/scripts/patch-app2.mjs +18 -0
- package/scripts/patch-dist-brief.mjs +96 -0
- package/scripts/patch-tool-exec.mjs +70 -0
- package/scripts/pretool-ask-runtime-test.mjs +54 -0
- package/scripts/provider-toolcall-test.mjs +376 -0
- package/scripts/reactive-compact-persist-smoke.mjs +124 -0
- package/scripts/sanitize-tool-pairs-test.mjs +260 -0
- package/scripts/session-context-bench.mjs +344 -0
- package/scripts/session-ingest-smoke.mjs +177 -0
- package/scripts/set-effort-config-test.mjs +41 -0
- package/scripts/smoke-runtime-negative.ps1 +106 -0
- package/scripts/smoke-runtime-negative.sh +97 -0
- package/scripts/smoke.mjs +25 -0
- package/scripts/tool-result-hook-test.mjs +48 -0
- package/scripts/tool-smoke.mjs +1223 -95
- package/scripts/toolcall-args-test.mjs +150 -0
- package/scripts/tui-background-failure-smoke.mjs +73 -0
- package/scripts/usage-metrics-epoch-smoke.mjs +114 -0
- package/src/agents/debugger/AGENT.md +8 -0
- package/src/agents/explore/AGENT.md +4 -0
- package/src/agents/heavy-worker/AGENT.md +9 -3
- package/src/agents/maintainer/AGENT.md +4 -0
- package/src/agents/reviewer/AGENT.md +8 -0
- package/src/agents/scheduler-task/AGENT.md +12 -0
- package/src/agents/scheduler-task/agent.json +6 -0
- package/src/agents/webhook-handler/AGENT.md +12 -0
- package/src/agents/webhook-handler/agent.json +6 -0
- package/src/agents/worker/AGENT.md +9 -3
- package/src/app.mjs +77 -3
- package/src/defaults/hidden-roles.json +17 -12
- package/src/headless-role.mjs +117 -0
- package/src/help.mjs +30 -0
- package/src/hooks/lib/permission-evaluator.cjs +11 -475
- package/src/lib/keychain-cjs.cjs +9 -1
- package/src/lib/mixdog-debug.cjs +0 -7
- package/src/lib/rules-builder.cjs +240 -96
- package/src/lib/text-utils.cjs +1 -1
- package/src/mixdog-session-runtime.mjs +2325 -450
- package/src/output-styles/default.md +12 -28
- package/src/output-styles/extreme-simple.md +9 -6
- package/src/output-styles/simple.md +22 -9
- package/src/repl.mjs +118 -59
- package/src/rules/agent/00-common.md +15 -0
- package/src/rules/{bridge → agent}/20-skip-protocol.md +1 -2
- package/src/rules/agent/30-explorer.md +22 -0
- package/src/rules/{bridge → agent}/40-cycle1-agent.md +7 -0
- package/src/rules/{bridge → agent}/41-cycle2-agent.md +7 -0
- package/src/rules/{bridge → agent}/42-cycle3-agent.md +7 -0
- package/src/rules/lead/01-general.md +9 -5
- package/src/rules/lead/04-workflow.md +51 -12
- package/src/rules/lead/lead-tool.md +6 -0
- package/src/rules/shared/01-tool.md +12 -1
- package/src/runtime/agent/orchestrator/activity-bus.mjs +7 -18
- package/src/runtime/agent/orchestrator/agent-owner.mjs +11 -0
- package/src/runtime/agent/orchestrator/{smart-bridge/bridge-llm.mjs → agent-runtime/agent-dispatch.mjs} +138 -111
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +94 -0
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/cache-strategy.mjs +32 -23
- package/src/runtime/agent/orchestrator/{smart-bridge → agent-runtime}/session-builder.mjs +33 -27
- package/src/runtime/agent/orchestrator/{bridge-trace.mjs → agent-trace.mjs} +132 -81
- package/src/runtime/agent/orchestrator/cache-mtime.mjs +0 -21
- package/src/runtime/agent/orchestrator/config.mjs +174 -55
- package/src/runtime/agent/orchestrator/context/collect.mjs +195 -487
- package/src/runtime/agent/orchestrator/dispatch-persist.mjs +1 -1
- package/src/runtime/agent/orchestrator/internal-roles.mjs +77 -29
- package/src/runtime/agent/orchestrator/internal-tools.mjs +5 -6
- package/src/runtime/agent/orchestrator/mcp/client.mjs +15 -9
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +377 -243
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +146 -93
- package/src/runtime/agent/orchestrator/providers/api-usage.mjs +236 -4
- package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +49 -0
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +58 -13
- package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +67 -149
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +132 -2
- package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +45 -0
- package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +61 -116
- package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +25 -0
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +79 -255
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +221 -70
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +477 -147
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +343 -496
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +6 -6
- package/src/runtime/agent/orchestrator/providers/registry.mjs +88 -51
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +31 -11
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +41 -8
- package/src/runtime/agent/orchestrator/session/cache/post-edit-marks.mjs +4 -4
- package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compact.mjs +1173 -267
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +199 -36
- package/src/runtime/agent/orchestrator/session/loop.mjs +851 -674
- package/src/runtime/agent/orchestrator/session/manager.mjs +1593 -466
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +107 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +291 -46
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +2 -2
- package/src/runtime/agent/orchestrator/stall-policy.mjs +31 -16
- package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +3 -219
- package/src/runtime/agent/orchestrator/tools/bash-session.mjs +34 -7
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +19 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +9 -9
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +60 -37
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +21 -2
- package/src/runtime/agent/orchestrator/tools/builtin/device-paths.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -7
- package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +1 -3
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +36 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-constants.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +5 -12
- package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +4 -36
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +2 -40
- package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +148 -27
- package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +2 -2
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +43 -75
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +90 -20
- package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +59 -5
- package/src/runtime/agent/orchestrator/tools/code-graph-state.mjs +86 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +11 -11
- package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4106 -4019
- package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +33 -4
- package/src/runtime/agent/orchestrator/tools/patch.mjs +90 -6
- package/src/runtime/agent/orchestrator/tools/progress-message.mjs +6 -4
- package/src/runtime/agent/orchestrator/tools/result-compression.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +8 -1
- package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +4 -4
- package/src/runtime/channels/index.mjs +152 -24
- package/src/runtime/channels/lib/scheduler.mjs +18 -14
- package/src/runtime/channels/lib/session-discovery.mjs +3 -2
- package/src/runtime/channels/lib/tool-format.mjs +0 -2
- package/src/runtime/channels/lib/transcript-discovery.mjs +3 -2
- package/src/runtime/channels/lib/webhook.mjs +1 -1
- package/src/runtime/channels/tool-defs.mjs +29 -29
- package/src/runtime/memory/index.mjs +635 -107
- package/src/runtime/memory/lib/agent-ipc.mjs +29 -12
- package/src/runtime/memory/lib/core-memory-store.mjs +2 -2
- package/src/runtime/memory/lib/embedding-model-config.mjs +55 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +31 -4
- package/src/runtime/memory/lib/embedding-worker.mjs +19 -10
- package/src/runtime/memory/lib/memory-cycle1.mjs +38 -17
- package/src/runtime/memory/lib/memory-cycle2.mjs +6 -7
- package/src/runtime/memory/lib/memory-cycle3.mjs +4 -4
- package/src/runtime/memory/lib/memory-ops-policy.mjs +2 -1
- package/src/runtime/memory/lib/memory-session-merge.mjs +38 -0
- package/src/runtime/memory/lib/memory.mjs +88 -9
- package/src/runtime/memory/lib/model-profile.mjs +1 -1
- package/src/runtime/memory/lib/pg/adapter.mjs +15 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +12 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +37 -3
- package/src/runtime/memory/lib/session-ingest.mjs +194 -0
- package/src/runtime/memory/lib/trace-store.mjs +96 -51
- package/src/runtime/memory/tool-defs.mjs +46 -37
- package/src/runtime/search/index.mjs +102 -466
- package/src/runtime/search/lib/web-tools.mjs +45 -25
- package/src/runtime/search/tool-defs.mjs +16 -23
- package/src/runtime/shared/abort-controller.mjs +1 -1
- package/src/runtime/shared/atomic-file.mjs +4 -3
- package/src/runtime/shared/background-tasks.mjs +122 -11
- package/src/runtime/shared/child-spawn-gate.mjs +145 -0
- package/src/runtime/shared/config.mjs +7 -4
- package/src/runtime/shared/err-text.mjs +131 -4
- package/src/runtime/shared/llm/cost.mjs +2 -2
- package/src/runtime/shared/llm/http-agent.mjs +23 -7
- package/src/runtime/shared/llm/index.mjs +34 -11
- package/src/runtime/shared/llm/usage-log.mjs +4 -4
- package/src/runtime/shared/markdown-frontmatter.mjs +56 -0
- package/src/runtime/shared/singleton-owner.mjs +104 -0
- package/src/runtime/shared/tool-execution-contract.mjs +199 -20
- package/src/runtime/shared/tool-execution-contract.test.mjs +183 -0
- package/src/runtime/shared/tool-surface.mjs +624 -98
- package/src/runtime/shared/user-data-guard.mjs +0 -2
- package/src/standalone/agent-task-status.mjs +203 -0
- package/src/standalone/agent-task-status.test.mjs +76 -0
- package/src/standalone/agent-tool.mjs +1913 -0
- package/src/standalone/channel-worker.mjs +370 -14
- package/src/standalone/explore-tool.mjs +165 -70
- package/src/standalone/folder-dialog.mjs +314 -0
- package/src/standalone/hook-bus.mjs +898 -22
- package/src/standalone/memory-runtime-proxy.mjs +320 -0
- package/src/standalone/projects.mjs +226 -0
- package/src/standalone/provider-admin.mjs +41 -24
- package/src/standalone/seeds.mjs +2 -69
- package/src/standalone/usage-dashboard.mjs +96 -8
- package/src/tui/App.jsx +4798 -2153
- package/src/tui/components/AnsiText.jsx +39 -28
- package/src/tui/components/ContextPanel.jsx +87 -29
- package/src/tui/components/Markdown.jsx +43 -77
- package/src/tui/components/MarkdownTable.jsx +9 -184
- package/src/tui/components/Message.jsx +28 -11
- package/src/tui/components/Picker.jsx +95 -56
- package/src/tui/components/PromptInput.jsx +367 -239
- package/src/tui/components/QueuedCommands.jsx +1 -1
- package/src/tui/components/SlashCommandPalette.jsx +27 -21
- package/src/tui/components/Spinner.jsx +67 -38
- package/src/tui/components/StatusLine.jsx +606 -38
- package/src/tui/components/TextEntryPanel.jsx +128 -9
- package/src/tui/components/ToolExecution.jsx +617 -368
- package/src/tui/components/TurnDone.jsx +3 -3
- package/src/tui/components/UsagePanel.jsx +3 -5
- package/src/tui/components/tool-output-format.mjs +365 -0
- package/src/tui/components/tool-output-format.test.mjs +220 -0
- package/src/tui/dist/index.mjs +8915 -2418
- package/src/tui/engine-runtime-notification.test.mjs +115 -0
- package/src/tui/engine-tool-result-text.test.mjs +75 -0
- package/src/tui/engine.mjs +1455 -279
- package/src/tui/figures.mjs +21 -40
- package/src/tui/index.jsx +75 -31
- package/src/tui/input-editing.mjs +25 -0
- package/src/tui/markdown/format-token.mjs +511 -68
- package/src/tui/markdown/format-token.test.mjs +216 -0
- package/src/tui/markdown/render-ansi.mjs +94 -0
- package/src/tui/markdown/render-ansi.test.mjs +108 -0
- package/src/tui/markdown/stream-fence.mjs +34 -0
- package/src/tui/markdown/stream-fence.test.mjs +26 -0
- package/src/tui/markdown/table-layout.mjs +250 -0
- package/src/tui/paste-attachments.mjs +0 -7
- package/src/tui/spinner-verbs.mjs +1 -2
- package/src/tui/statusline-ansi-bridge.mjs +172 -0
- package/src/tui/statusline-ansi-bridge.test.mjs +159 -0
- package/src/tui/theme.mjs +746 -24
- package/src/tui/time-format.mjs +1 -1
- package/src/tui/transcript-tool-failures.mjs +67 -0
- package/src/tui/transcript-tool-failures.test.mjs +111 -0
- package/src/ui/ansi.mjs +1 -2
- package/src/ui/markdown.mjs +85 -26
- package/src/ui/markdown.test.mjs +70 -0
- package/src/ui/model-display.mjs +121 -0
- package/src/ui/session-stats.mjs +44 -0
- package/src/ui/statusline-context-label.test.mjs +15 -0
- package/src/ui/statusline.mjs +386 -178
- package/src/ui/tool-card.mjs +3 -16
- package/src/vendor/statusline/bin/statusline-lib.mjs +8 -4
- package/src/vendor/statusline/bin/statusline-route.mjs +169 -37
- package/src/vendor/statusline/bin/statusline-route.test.mjs +80 -0
- package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +3 -3
- package/src/vendor/statusline/src/gateway/claude-current.mjs +1 -1
- package/src/vendor/statusline/src/gateway/route-meta.mjs +44 -6
- package/src/vendor/statusline/src/gateway/session-routes.mjs +1 -1
- package/src/workflows/default/WORKFLOW.md +12 -5
- package/src/workflows/default/workflow.json +0 -1
- package/src/workflows/solo/WORKFLOW.md +15 -0
- package/src/workflows/solo/workflow.json +7 -0
- package/vendor/ink/build/output.js +6 -1
- package/src/agents/scheduler-task.md +0 -3
- package/src/agents/web-researcher/AGENT.md +0 -3
- package/src/agents/web-researcher/agent.json +0 -6
- package/src/agents/webhook-handler.md +0 -3
- package/src/rules/bridge/00-common.md +0 -5
- package/src/rules/bridge/30-explorer.md +0 -4
- package/src/rules/lead/00-tool-lead.md +0 -5
- package/src/rules/shared/00-language.md +0 -3
- package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
- package/src/runtime/agent/orchestrator/tools/mutation-content-cache.mjs +0 -67
- package/src/runtime/memory/lib/bridge-trace-queries.mjs +0 -120
- package/src/runtime/shared/llm/pid-cleanup.mjs +0 -27
- package/src/standalone/bridge-tool.mjs +0 -1414
- package/src/tui/runtime/shared/process-shutdown.mjs +0 -1
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
parseCompletedToolCallArgumentsJson,
|
|
10
10
|
} from './openai-compat-stream.mjs';
|
|
11
11
|
import { enrichModels, getModelMetadataSync } from './model-catalog.mjs';
|
|
12
|
-
import {
|
|
12
|
+
import { appendAgentTrace, traceAgentUsage } from '../agent-trace.mjs';
|
|
13
13
|
import {
|
|
14
14
|
resolveProviderCacheKey,
|
|
15
15
|
resolveProviderPromptCacheLane,
|
|
16
|
-
} from '../
|
|
16
|
+
} from '../agent-runtime/cache-strategy.mjs';
|
|
17
17
|
import {
|
|
18
18
|
PROVIDER_FIRST_BYTE_TIMEOUT_MS,
|
|
19
19
|
PROVIDER_GENERATE_TOTAL_TIMEOUT_MS,
|
|
@@ -23,42 +23,16 @@ import {
|
|
|
23
23
|
} from '../stall-policy.mjs';
|
|
24
24
|
import { traceHash, stableTraceStringify, summarizeTraceTools, traceTextShape } from './trace-utils.mjs';
|
|
25
25
|
import {
|
|
26
|
-
contentHasImage,
|
|
27
26
|
normalizeContentForOpenAIChat,
|
|
28
27
|
normalizeContentForOpenAIResponses,
|
|
29
28
|
splitToolContentForOpenAIChat,
|
|
30
29
|
splitToolContentForOpenAIResponses,
|
|
31
30
|
} from './media-normalization.mjs';
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
baseURL: 'https://api.deepseek.com',
|
|
38
|
-
defaultModel: 'deepseek-v4-pro',
|
|
39
|
-
},
|
|
40
|
-
xai: {
|
|
41
|
-
baseURL: 'https://api.x.ai/v1',
|
|
42
|
-
defaultModel: 'grok-4.3',
|
|
43
|
-
},
|
|
44
|
-
// OpenCode Go — low-cost coding-model subscription gateway. GLM / Kimi /
|
|
45
|
-
// DeepSeek / MiMo use the OpenAI-compatible chat surface; MiniMax / Qwen
|
|
46
|
-
// use the Anthropic-compatible messages surface. opencode-go.mjs provides
|
|
47
|
-
// the dual transport while this preset remains the shared base URL/key
|
|
48
|
-
// source. Auth is a single OPENCODE_API_KEY (Bearer).
|
|
49
|
-
'opencode-go': {
|
|
50
|
-
baseURL: 'https://opencode.ai/zen/go/v1',
|
|
51
|
-
defaultModel: 'glm-5.2',
|
|
52
|
-
},
|
|
53
|
-
ollama: {
|
|
54
|
-
baseURL: 'http://localhost:11434/v1',
|
|
55
|
-
defaultModel: 'llama3.3:latest',
|
|
56
|
-
},
|
|
57
|
-
lmstudio: {
|
|
58
|
-
baseURL: 'http://localhost:1234/v1',
|
|
59
|
-
defaultModel: 'default',
|
|
60
|
-
},
|
|
61
|
-
};
|
|
31
|
+
import {
|
|
32
|
+
customToolCallFromResponseItem,
|
|
33
|
+
} from './custom-tool-wire.mjs';
|
|
34
|
+
import { OPENAI_COMPAT_PRESETS } from './openai-compat-presets.mjs';
|
|
35
|
+
export { OPENAI_COMPAT_PRESETS } from './openai-compat-presets.mjs';
|
|
62
36
|
const PRESETS = OPENAI_COMPAT_PRESETS;
|
|
63
37
|
const MODEL_LIST_TIMEOUT_MS = resolveTimeoutMs(
|
|
64
38
|
'MIXDOG_COMPAT_MODEL_LIST_TIMEOUT_MS',
|
|
@@ -266,6 +240,41 @@ function useXaiResponsesWebSocket(opts, config) {
|
|
|
266
240
|
return !['0', 'false', 'off', 'http', 'https', 'responses-http', 'sdk'].includes(transport);
|
|
267
241
|
}
|
|
268
242
|
|
|
243
|
+
function _envFlag(name, fallback = true) {
|
|
244
|
+
const raw = process.env[name];
|
|
245
|
+
if (raw == null || raw === '') return fallback;
|
|
246
|
+
return !['0', 'false', 'off', 'no'].includes(String(raw).toLowerCase());
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function _shouldFallbackXaiWsToHttp(err, signal) {
|
|
250
|
+
if (!_envFlag('MIXDOG_XAI_WS_HTTP_FALLBACK', true)) return false;
|
|
251
|
+
if (signal?.aborted) return false;
|
|
252
|
+
if (err?.liveTextEmitted === true) return false;
|
|
253
|
+
if (err?.emittedToolCall === true || err?.unsafeToRetry === true) return false;
|
|
254
|
+
const status = Number(err?.httpStatus || err?.status || 0);
|
|
255
|
+
if (status === 401 || status === 403 || status === 404 || status === 429) return false;
|
|
256
|
+
if (status >= 500 && status < 600) return true;
|
|
257
|
+
const code = String(err?.code || '');
|
|
258
|
+
if (['EWSACQUIRETIMEOUT', 'ETIMEDOUT', 'ESOCKETTIMEDOUT', 'ECONNRESET', 'EAI_AGAIN', 'ENOTFOUND', 'EAI_NODATA', 'ECONNREFUSED', 'ENETUNREACH', 'EHOSTUNREACH', 'EPIPE'].includes(code)) {
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
const classifier = String(err?.retryClassifier || err?.midstreamClassifier || '');
|
|
262
|
+
if ([
|
|
263
|
+
'timeout', 'reset', 'dns', 'refused', 'network', 'acquire_timeout', 'http_5xx',
|
|
264
|
+
'first_byte_timeout', 'first_meaningful_timeout',
|
|
265
|
+
'ws_1006', 'ws_1011', 'ws_1012', 'ws_1000', 'ws_4000', 'agent_stall', 'stream_stalled',
|
|
266
|
+
'response_failed_disconnected', 'response_failed_network', 'response_failed_auth_expired',
|
|
267
|
+
'ws_send_failed',
|
|
268
|
+
].includes(classifier)) {
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
if (/^http_5\d\d$/.test(classifier)) return true;
|
|
272
|
+
if (err?.firstByteTimeout) return true;
|
|
273
|
+
if (err?.firstMeaningfulTimeout) return true;
|
|
274
|
+
const msg = String(err?.message || '');
|
|
275
|
+
return /opening handshake has timed out|socket hang up|acquire timed out|no first server event|no meaningful output/i.test(msg);
|
|
276
|
+
}
|
|
277
|
+
|
|
269
278
|
function useXaiResponsesWebSocketWarmup(opts, config, { previousResponseId, instructions, rawTools }) {
|
|
270
279
|
if (previousResponseId) return false;
|
|
271
280
|
const raw = opts?.xaiResponsesWarmup
|
|
@@ -282,7 +291,7 @@ function useXaiResponsesWebSocketWarmup(opts, config, { previousResponseId, inst
|
|
|
282
291
|
return String(instructions || '').length >= 2048 || (Array.isArray(rawTools) && rawTools.length >= 10);
|
|
283
292
|
}
|
|
284
293
|
|
|
285
|
-
// Match OpenAI/
|
|
294
|
+
// Match OpenAI OAuth/API cache-lane semantics: default to 12 stable shards (via
|
|
286
295
|
// resolveProviderPromptCacheLane) and serialize each final shard. This gives
|
|
287
296
|
// Grok/xAI 10+ worker fanout without concurrent same-key cache contention.
|
|
288
297
|
const XAI_RESPONSES_CACHE_LANE_DEFAULT_MAX_IN_FLIGHT = 1;
|
|
@@ -511,7 +520,7 @@ function acquireXaiResponsesCacheLane({ key, maxInFlight, signal, timeoutMs }) {
|
|
|
511
520
|
function traceXaiCacheLane(opts, payload) {
|
|
512
521
|
if (!compatCacheTraceEnabled('xai')) return;
|
|
513
522
|
try {
|
|
514
|
-
|
|
523
|
+
appendAgentTrace({
|
|
515
524
|
sessionId: opts?.sessionId || opts?.session?.id || null,
|
|
516
525
|
iteration: Number.isFinite(Number(opts?.iteration)) ? Number(opts.iteration) : null,
|
|
517
526
|
kind: 'cache_lane',
|
|
@@ -784,7 +793,7 @@ function traceXaiResponsesCacheContext(args) {
|
|
|
784
793
|
const payload = xaiResponsesFingerprintPayload(args);
|
|
785
794
|
const sessionId = args?.opts?.sessionId || args?.opts?.session?.id || null;
|
|
786
795
|
const iteration = Number.isFinite(Number(args?.opts?.iteration)) ? Number(args.opts.iteration) : null;
|
|
787
|
-
|
|
796
|
+
appendAgentTrace({
|
|
788
797
|
sessionId,
|
|
789
798
|
iteration,
|
|
790
799
|
kind: 'cache_context',
|
|
@@ -797,7 +806,7 @@ function traceXaiResponsesCacheContext(args) {
|
|
|
797
806
|
anomaly: 'xai_mid_turn_cold_cache',
|
|
798
807
|
reason: 'previous_response_id_present_but_cached_tokens_low',
|
|
799
808
|
};
|
|
800
|
-
|
|
809
|
+
appendAgentTrace({
|
|
801
810
|
sessionId,
|
|
802
811
|
iteration,
|
|
803
812
|
kind: 'cache_anomaly',
|
|
@@ -942,10 +951,6 @@ function toOpenAIMessages(messages, providerName, options = {}) {
|
|
|
942
951
|
return out;
|
|
943
952
|
}
|
|
944
953
|
|
|
945
|
-
function messagesHaveImageContent(messages) {
|
|
946
|
-
return (messages || []).some((m) => contentHasImage(m?.content));
|
|
947
|
-
}
|
|
948
|
-
|
|
949
954
|
function toOpenAITools(tools) {
|
|
950
955
|
return tools.map((t) => ({
|
|
951
956
|
type: 'function',
|
|
@@ -957,14 +962,34 @@ function toOpenAITools(tools) {
|
|
|
957
962
|
}));
|
|
958
963
|
}
|
|
959
964
|
function toResponsesTools(tools) {
|
|
960
|
-
return tools.map((t) =>
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
965
|
+
return tools.map((t) => {
|
|
966
|
+
if (t?.name === 'tool_search') {
|
|
967
|
+
return {
|
|
968
|
+
type: 'tool_search',
|
|
969
|
+
execution: 'client',
|
|
970
|
+
description: t.description,
|
|
971
|
+
parameters: t.inputSchema,
|
|
972
|
+
};
|
|
973
|
+
}
|
|
974
|
+
// xAI/Grok Responses rejects the OpenAI-only `type:'custom'` freeform
|
|
975
|
+
// variant ("unknown variant 'custom'"). Serialize freeform/grammar
|
|
976
|
+
// tools (e.g. apply_patch) as ordinary function tools instead. Grammar
|
|
977
|
+
// tools may carry no usable inputSchema, so fall back to a permissive
|
|
978
|
+
// object schema so grok still registers a valid function tool.
|
|
979
|
+
return {
|
|
980
|
+
type: 'function',
|
|
981
|
+
name: t.name,
|
|
982
|
+
description: t.description,
|
|
983
|
+
parameters: t.inputSchema || { type: 'object', additionalProperties: true },
|
|
984
|
+
};
|
|
985
|
+
});
|
|
966
986
|
}
|
|
967
|
-
function
|
|
987
|
+
function nativeResponsesTools(opts) {
|
|
988
|
+
return Array.isArray(opts?.nativeTools)
|
|
989
|
+
? opts.nativeTools.filter(t => t && typeof t === 'object')
|
|
990
|
+
: [];
|
|
991
|
+
}
|
|
992
|
+
export function parseToolCalls(choice, label) {
|
|
968
993
|
const calls = choice.message?.tool_calls;
|
|
969
994
|
if (!calls?.length)
|
|
970
995
|
return undefined;
|
|
@@ -979,18 +1004,31 @@ function parseToolCalls(choice, label) {
|
|
|
979
1004
|
arguments: parseCompletedToolCallArgumentsJson(tc.function.arguments, label, { id: tc.id, name: tc.function.name, finishReason }),
|
|
980
1005
|
}));
|
|
981
1006
|
}
|
|
982
|
-
function parseResponsesToolCalls(response, label) {
|
|
1007
|
+
export function parseResponsesToolCalls(response, label) {
|
|
983
1008
|
const out = [];
|
|
984
1009
|
// A Responses tool call is only parsed off a completed/done item, so any
|
|
985
1010
|
// malformed-JSON failure here is deterministic, not mid-stream truncation.
|
|
986
1011
|
const finishReason = response?.status || 'completed';
|
|
987
1012
|
for (const item of response?.output || []) {
|
|
988
|
-
if (item?.type
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
1013
|
+
if (item?.type === 'function_call') {
|
|
1014
|
+
out.push({
|
|
1015
|
+
id: item.call_id || item.id,
|
|
1016
|
+
name: item.name,
|
|
1017
|
+
arguments: parseCompletedToolCallArgumentsJson(item.arguments, label, { id: item.call_id || item.id, name: item.name, finishReason }),
|
|
1018
|
+
});
|
|
1019
|
+
} else if (item?.type === 'custom_tool_call') {
|
|
1020
|
+
const call = customToolCallFromResponseItem(item);
|
|
1021
|
+
if (call) out.push(call);
|
|
1022
|
+
} else if (item?.type === 'tool_search_call') {
|
|
1023
|
+
out.push({
|
|
1024
|
+
id: item.call_id || item.id,
|
|
1025
|
+
name: 'tool_search',
|
|
1026
|
+
arguments: item.arguments && typeof item.arguments === 'object'
|
|
1027
|
+
? item.arguments
|
|
1028
|
+
: parseCompletedToolCallArgumentsJson(item.arguments || '{}', label, { id: item.call_id || item.id, name: 'tool_search', finishReason }),
|
|
1029
|
+
nativeType: 'tool_search_call',
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
994
1032
|
}
|
|
995
1033
|
return out.length ? out : undefined;
|
|
996
1034
|
}
|
|
@@ -1005,9 +1043,71 @@ function responseOutputText(response) {
|
|
|
1005
1043
|
}
|
|
1006
1044
|
return chunks.join('');
|
|
1007
1045
|
}
|
|
1008
|
-
function
|
|
1046
|
+
function collectCompatResponseSearchSources(response) {
|
|
1047
|
+
const citations = [];
|
|
1048
|
+
const webSearchCalls = [];
|
|
1049
|
+
const seen = new Set();
|
|
1050
|
+
const addCitation = (source, fallback = {}) => {
|
|
1051
|
+
if (!source) return;
|
|
1052
|
+
if (typeof source === 'string') {
|
|
1053
|
+
const url = source.trim();
|
|
1054
|
+
if (!url || seen.has(url)) return;
|
|
1055
|
+
seen.add(url);
|
|
1056
|
+
citations.push({ title: url, url, snippet: '', source: fallback.source || 'citation', provider: 'xai' });
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
if (typeof source !== 'object') return;
|
|
1060
|
+
const url = String(
|
|
1061
|
+
source.url
|
|
1062
|
+
|| source.uri
|
|
1063
|
+
|| source.href
|
|
1064
|
+
|| source.source_url
|
|
1065
|
+
|| source.url_citation?.url
|
|
1066
|
+
|| '',
|
|
1067
|
+
).trim();
|
|
1068
|
+
if (!url || seen.has(url)) return;
|
|
1069
|
+
seen.add(url);
|
|
1070
|
+
citations.push({
|
|
1071
|
+
title: String(source.title || source.name || source.query || source.url_citation?.title || fallback.title || url).trim(),
|
|
1072
|
+
url,
|
|
1073
|
+
snippet: String(source.snippet || source.text || source.description || '').trim(),
|
|
1074
|
+
source: source.source || fallback.source || 'citation',
|
|
1075
|
+
provider: source.provider || 'xai',
|
|
1076
|
+
});
|
|
1077
|
+
};
|
|
1078
|
+
for (const citation of Array.isArray(response?.citations) ? response.citations : []) addCitation(citation);
|
|
1079
|
+
for (const item of Array.isArray(response?.output) ? response.output : []) {
|
|
1080
|
+
if (item?.type === 'web_search_call') {
|
|
1081
|
+
webSearchCalls.push({ id: item.id || '', status: item.status || '', action: item.action || null });
|
|
1082
|
+
const action = item.action || {};
|
|
1083
|
+
for (const source of Array.isArray(action.sources) ? action.sources : []) addCitation(source, { title: action.query || '', source: 'web_search_call' });
|
|
1084
|
+
if (action.url) addCitation({ url: action.url, title: action.query || '' }, { source: 'web_search_call' });
|
|
1085
|
+
for (const url of Array.isArray(action.urls) ? action.urls : []) addCitation({ url, title: action.query || '' }, { source: 'web_search_call' });
|
|
1086
|
+
}
|
|
1087
|
+
for (const citation of Array.isArray(item?.citations) ? item.citations : []) addCitation(citation);
|
|
1088
|
+
for (const part of Array.isArray(item?.content) ? item.content : []) {
|
|
1089
|
+
for (const annotation of Array.isArray(part?.annotations) ? part.annotations : []) {
|
|
1090
|
+
addCitation(annotation, { source: 'annotation' });
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
return { citations, webSearchCalls };
|
|
1095
|
+
}
|
|
1096
|
+
function toResponsesInputMessage(m, pendingToolMedia = null, customToolCallNameById = null) {
|
|
1009
1097
|
if (m.role === 'tool') {
|
|
1098
|
+
if (Array.isArray(m.nativeToolSearch?.openaiTools)) {
|
|
1099
|
+
return {
|
|
1100
|
+
type: 'tool_search_output',
|
|
1101
|
+
call_id: m.toolCallId || '',
|
|
1102
|
+
status: 'completed',
|
|
1103
|
+
execution: 'client',
|
|
1104
|
+
tools: m.nativeToolSearch.openaiTools,
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1010
1107
|
const { output, mediaContent } = splitToolContentForOpenAIResponses(m.content);
|
|
1108
|
+
// xai path: never emit `custom_tool_call_output` (the `custom` variant
|
|
1109
|
+
// is rejected by grok). Replay prior tool outputs as the standard
|
|
1110
|
+
// `function_call_output` item regardless of original native type.
|
|
1011
1111
|
const item = {
|
|
1012
1112
|
type: 'function_call_output',
|
|
1013
1113
|
call_id: m.toolCallId || '',
|
|
@@ -1020,12 +1120,25 @@ function toResponsesInputMessage(m, pendingToolMedia = null) {
|
|
|
1020
1120
|
const items = [];
|
|
1021
1121
|
if (m.content) items.push({ role: 'assistant', content: normalizeContentForOpenAIResponses(m.content, { role: 'assistant' }) });
|
|
1022
1122
|
for (const tc of m.toolCalls) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1123
|
+
if (tc.nativeType === 'tool_search_call' || tc.name === 'tool_search') {
|
|
1124
|
+
items.push({
|
|
1125
|
+
type: 'tool_search_call',
|
|
1126
|
+
call_id: tc.id,
|
|
1127
|
+
execution: 'client',
|
|
1128
|
+
arguments: tc.arguments || {},
|
|
1129
|
+
});
|
|
1130
|
+
} else {
|
|
1131
|
+
// xai path: prior native `custom_tool_call` history is replayed
|
|
1132
|
+
// as a standard `function_call` (grok rejects the `custom`
|
|
1133
|
+
// variant). tc.arguments already holds the recovered object
|
|
1134
|
+
// form, so the same stringify path as regular calls applies.
|
|
1135
|
+
items.push({
|
|
1136
|
+
type: 'function_call',
|
|
1137
|
+
call_id: tc.id,
|
|
1138
|
+
name: tc.name,
|
|
1139
|
+
arguments: JSON.stringify(tc.arguments || {}),
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1029
1142
|
}
|
|
1030
1143
|
return items;
|
|
1031
1144
|
}
|
|
@@ -1062,6 +1175,7 @@ function toXaiResponsesInput(messages, providerState, options = {}) {
|
|
|
1062
1175
|
}
|
|
1063
1176
|
const input = [];
|
|
1064
1177
|
const pendingToolMedia = [];
|
|
1178
|
+
const customToolCallNameById = new Map();
|
|
1065
1179
|
const flushToolMedia = () => {
|
|
1066
1180
|
if (!pendingToolMedia.length) return;
|
|
1067
1181
|
input.push({ role: 'user', content: pendingToolMedia.splice(0) });
|
|
@@ -1069,7 +1183,7 @@ function toXaiResponsesInput(messages, providerState, options = {}) {
|
|
|
1069
1183
|
for (const m of messages.slice(startIndex)) {
|
|
1070
1184
|
if (!includeSystem && m.role === 'system') continue;
|
|
1071
1185
|
if (m.role !== 'tool') flushToolMedia();
|
|
1072
|
-
const converted = toResponsesInputMessage(m, pendingToolMedia);
|
|
1186
|
+
const converted = toResponsesInputMessage(m, pendingToolMedia, customToolCallNameById);
|
|
1073
1187
|
if (Array.isArray(converted)) input.push(...converted);
|
|
1074
1188
|
else input.push(converted);
|
|
1075
1189
|
}
|
|
@@ -1145,8 +1259,35 @@ export class OpenAICompatProvider {
|
|
|
1145
1259
|
const useModel = model || this.defaultModel;
|
|
1146
1260
|
const opts = sendOpts || {};
|
|
1147
1261
|
if (this.name === 'xai' && useXaiResponsesApi(opts, this.config)) {
|
|
1148
|
-
if (useXaiResponsesWebSocket(opts, this.config)
|
|
1149
|
-
|
|
1262
|
+
if (useXaiResponsesWebSocket(opts, this.config)) {
|
|
1263
|
+
try {
|
|
1264
|
+
return await this._doSendXaiResponsesWebSocket(messages, useModel, tools, opts);
|
|
1265
|
+
} catch (err) {
|
|
1266
|
+
if (_shouldFallbackXaiWsToHttp(err, opts.signal)) {
|
|
1267
|
+
const reason = err?.midstreamClassifier || err?.retryClassifier || err?.code || err?.message || 'ws_failed';
|
|
1268
|
+
process.stderr.write(`[xai:responses] WebSocket unhealthy (${reason}); falling back to HTTP/SSE\n`);
|
|
1269
|
+
try {
|
|
1270
|
+
appendAgentTrace({
|
|
1271
|
+
sessionId: opts?.sessionId || opts?.session?.id || null,
|
|
1272
|
+
iteration: Number.isFinite(Number(opts?.iteration)) ? Number(opts.iteration) : null,
|
|
1273
|
+
kind: 'transport_fallback',
|
|
1274
|
+
provider: 'xai',
|
|
1275
|
+
model: useModel,
|
|
1276
|
+
transport: 'http',
|
|
1277
|
+
payload: {
|
|
1278
|
+
from: 'websocket',
|
|
1279
|
+
to: 'http',
|
|
1280
|
+
reason,
|
|
1281
|
+
error_code: err?.code || null,
|
|
1282
|
+
error_http_status: Number(err?.httpStatus || 0) || null,
|
|
1283
|
+
error_classifier: err?.retryClassifier || err?.midstreamClassifier || null,
|
|
1284
|
+
},
|
|
1285
|
+
});
|
|
1286
|
+
} catch {}
|
|
1287
|
+
return await this._doSendXaiResponses(messages, useModel, tools, opts);
|
|
1288
|
+
}
|
|
1289
|
+
throw err;
|
|
1290
|
+
}
|
|
1150
1291
|
}
|
|
1151
1292
|
return await this._doSendXaiResponses(messages, useModel, tools, opts);
|
|
1152
1293
|
}
|
|
@@ -1283,7 +1424,7 @@ export class OpenAICompatProvider {
|
|
|
1283
1424
|
if (response.usage) {
|
|
1284
1425
|
const inputTokens = Number(response.usage.prompt_tokens ?? response.usage.input_tokens ?? 0);
|
|
1285
1426
|
const cachedTokens = extractCompatCachedTokens(response.usage);
|
|
1286
|
-
|
|
1427
|
+
traceAgentUsage({
|
|
1287
1428
|
sessionId: opts.sessionId || opts.session?.id || null,
|
|
1288
1429
|
iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
|
|
1289
1430
|
inputTokens,
|
|
@@ -1357,9 +1498,10 @@ export class OpenAICompatProvider {
|
|
|
1357
1498
|
prompt_cache_key: cacheRouting.key,
|
|
1358
1499
|
};
|
|
1359
1500
|
if (previousResponseId) params.previous_response_id = previousResponseId;
|
|
1360
|
-
|
|
1501
|
+
const nativeTools = nativeResponsesTools(opts);
|
|
1502
|
+
if (tools?.length || nativeTools.length) params.tools = [...nativeTools, ...toResponsesTools(tools || [])];
|
|
1361
1503
|
// SSE transport: report 'requesting' until the stream opens, then
|
|
1362
|
-
// per-chunk onStreamDelta feeds the
|
|
1504
|
+
// per-chunk onStreamDelta feeds the agent stall watchdog.
|
|
1363
1505
|
try { opts.onStageChange?.('requesting'); } catch { /* heartbeat best-effort */ }
|
|
1364
1506
|
const reasoningEffort = normalizeXaiReasoningEffort(opts.xaiReasoningEffort
|
|
1365
1507
|
?? opts.effort
|
|
@@ -1453,7 +1595,7 @@ export class OpenAICompatProvider {
|
|
|
1453
1595
|
if (response.usage) {
|
|
1454
1596
|
const inputTokens = Number(response.usage.input_tokens ?? response.usage.prompt_tokens ?? 0);
|
|
1455
1597
|
const cachedTokens = extractCompatCachedTokens(response.usage);
|
|
1456
|
-
|
|
1598
|
+
traceAgentUsage({
|
|
1457
1599
|
sessionId: opts.sessionId || opts.session?.id || null,
|
|
1458
1600
|
iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
|
|
1459
1601
|
inputTokens,
|
|
@@ -1469,11 +1611,14 @@ export class OpenAICompatProvider {
|
|
|
1469
1611
|
});
|
|
1470
1612
|
}
|
|
1471
1613
|
const nextPreviousResponseId = streamed.stopReason === 'length' ? null : response.id;
|
|
1614
|
+
const searchSources = collectCompatResponseSearchSources(response);
|
|
1472
1615
|
return {
|
|
1473
1616
|
content: streamed.content,
|
|
1474
1617
|
model: response.model || useModel,
|
|
1475
1618
|
toolCalls,
|
|
1476
1619
|
stopReason: streamed.stopReason || null,
|
|
1620
|
+
citations: searchSources.citations.length ? searchSources.citations : undefined,
|
|
1621
|
+
webSearchCalls: searchSources.webSearchCalls.length ? searchSources.webSearchCalls : undefined,
|
|
1477
1622
|
providerState: {
|
|
1478
1623
|
...(opts.providerState || {}),
|
|
1479
1624
|
xaiResponses: {
|
|
@@ -1529,7 +1674,8 @@ export class OpenAICompatProvider {
|
|
|
1529
1674
|
// xAI rejects instructions together with previous_response_id; the
|
|
1530
1675
|
// first response already anchors instructions for the continuation.
|
|
1531
1676
|
else if (instructions) params.instructions = instructions;
|
|
1532
|
-
|
|
1677
|
+
const nativeTools = nativeResponsesTools(opts);
|
|
1678
|
+
if (tools?.length || nativeTools.length) params.tools = [...nativeTools, ...toResponsesTools(tools || [])];
|
|
1533
1679
|
const reasoningEffort = normalizeXaiReasoningEffort(opts.xaiReasoningEffort
|
|
1534
1680
|
?? opts.effort
|
|
1535
1681
|
?? this.config?.reasoningEffort
|
|
@@ -1640,6 +1786,8 @@ export class OpenAICompatProvider {
|
|
|
1640
1786
|
...result.usage,
|
|
1641
1787
|
...(costUsd != null ? { costUsd } : {}),
|
|
1642
1788
|
} : undefined,
|
|
1789
|
+
citations: Array.isArray(result.citations) && result.citations.length ? result.citations : undefined,
|
|
1790
|
+
webSearchCalls: Array.isArray(result.webSearchCalls) && result.webSearchCalls.length ? result.webSearchCalls : undefined,
|
|
1643
1791
|
};
|
|
1644
1792
|
}
|
|
1645
1793
|
async _fetchModelItems() {
|
|
@@ -1717,3 +1865,6 @@ export class OpenAICompatProvider {
|
|
|
1717
1865
|
return null;
|
|
1718
1866
|
}
|
|
1719
1867
|
}
|
|
1868
|
+
|
|
1869
|
+
export const _toResponsesToolsForTest = toResponsesTools;
|
|
1870
|
+
export const _toXaiResponsesInputForTest = toXaiResponsesInput;
|