mixdog 0.8.1 → 0.9.1
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 +34 -28
- 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 +205 -33
- 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 +1222 -90
- 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 -29
- package/src/lib/plugin-paths.cjs +1 -7
- package/src/lib/rules-builder.cjs +242 -98
- package/src/lib/text-utils.cjs +1 -1
- package/src/mixdog-session-runtime.mjs +2211 -446
- 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 +108 -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 +380 -268
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +131 -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 +203 -71
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +512 -312
- package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +343 -518
- 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 +289 -11
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +41 -8
- 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 +840 -612
- package/src/runtime/agent/orchestrator/session/manager.mjs +1574 -459
- package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +107 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +67 -29
- 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 +35 -8
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +19 -8
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +10 -53
- 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.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 +149 -51
- package/src/runtime/channels/lib/cli-worker-host.mjs +1 -8
- package/src/runtime/channels/lib/config.mjs +0 -1
- package/src/runtime/channels/lib/drop-trace.mjs +1 -1
- package/src/runtime/channels/lib/executor.mjs +0 -3
- package/src/runtime/channels/lib/memory-client.mjs +0 -38
- package/src/runtime/channels/lib/output-forwarder.mjs +1 -8
- package/src/runtime/channels/lib/runtime-paths.mjs +0 -6
- package/src/runtime/channels/lib/scheduler.mjs +18 -14
- package/src/runtime/channels/lib/session-discovery.mjs +3 -6
- package/src/runtime/channels/lib/tool-format.mjs +0 -1
- package/src/runtime/channels/lib/transcript-discovery.mjs +4 -12
- package/src/runtime/channels/lib/webhook.mjs +1 -1
- package/src/runtime/channels/tool-defs.mjs +29 -29
- package/src/runtime/lib/keychain-cjs.cjs +0 -1
- package/src/runtime/memory/data/runtime-manifest.json +6 -7
- package/src/runtime/memory/index.mjs +519 -118
- 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/llm-worker-host.mjs +0 -4
- package/src/runtime/memory/lib/memory-cycle1.mjs +28 -7
- package/src/runtime/memory/lib/memory-cycle2.mjs +4 -5
- package/src/runtime/memory/lib/memory-cycle3.mjs +2 -2
- package/src/runtime/memory/lib/memory-ops-policy.mjs +2 -2
- 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 +1 -1
- package/src/runtime/memory/lib/pg/supervisor.mjs +12 -0
- package/src/runtime/memory/lib/runtime-fetcher.mjs +80 -21
- package/src/runtime/memory/lib/session-ingest.mjs +196 -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 +104 -473
- package/src/runtime/search/lib/config.mjs +0 -4
- package/src/runtime/search/lib/state.mjs +1 -15
- package/src/runtime/search/lib/web-tools.mjs +44 -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 +139 -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 -95
- 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 +1 -78
- package/src/standalone/usage-dashboard.mjs +96 -8
- package/src/tui/App.jsx +4800 -2140
- package/src/tui/components/AnsiText.jsx +39 -28
- package/src/tui/components/ContextPanel.jsx +14 -4
- 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 +428 -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 +597 -362
- package/src/tui/components/TurnDone.jsx +3 -3
- package/src/tui/components/UsagePanel.jsx +3 -5
- package/src/tui/components/tool-output-format.mjs +499 -0
- package/src/tui/components/tool-output-format.test.mjs +312 -0
- package/src/tui/dist/index.mjs +9192 -2399
- 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 +671 -69
- package/src/tui/markdown/format-token.test.mjs +312 -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 +756 -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 +2 -13
- package/src/vendor/statusline/bin/statusline-lib.mjs +1 -620
- 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/ink.js +54 -8
- 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/hooks/lib/permission-rules.cjs +0 -170
- package/src/hooks/lib/settings-loader.cjs +0 -112
- package/src/lib/hook-pipe-path.cjs +0 -10
- 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/channels/lib/hook-pipe-server.mjs +0 -671
- 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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
2
|
import { createHash } from 'crypto';
|
|
3
3
|
import { loadConfig } from '../config.mjs';
|
|
4
|
-
import { withRetry } from './retry-classifier.mjs';
|
|
4
|
+
import { shouldFallbackTransport, withRetry } from './retry-classifier.mjs';
|
|
5
5
|
import { sendViaWebSocket } from './openai-oauth-ws.mjs';
|
|
6
6
|
import {
|
|
7
7
|
consumeCompatChatCompletionStream,
|
|
@@ -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,22 @@ 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
|
+
// xAI WS→HTTP transport fallback → shared shouldFallbackTransport
|
|
250
|
+
// (retry-classifier.mjs). Identical deny-order + allow-list; the per-provider
|
|
251
|
+
// env flag is computed here and passed via `enabled`.
|
|
252
|
+
function _shouldFallbackXaiWsToHttp(err, signal) {
|
|
253
|
+
return shouldFallbackTransport(err, {
|
|
254
|
+
signal,
|
|
255
|
+
enabled: _envFlag('MIXDOG_XAI_WS_HTTP_FALLBACK', true),
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
|
|
269
259
|
function useXaiResponsesWebSocketWarmup(opts, config, { previousResponseId, instructions, rawTools }) {
|
|
270
260
|
if (previousResponseId) return false;
|
|
271
261
|
const raw = opts?.xaiResponsesWarmup
|
|
@@ -282,7 +272,7 @@ function useXaiResponsesWebSocketWarmup(opts, config, { previousResponseId, inst
|
|
|
282
272
|
return String(instructions || '').length >= 2048 || (Array.isArray(rawTools) && rawTools.length >= 10);
|
|
283
273
|
}
|
|
284
274
|
|
|
285
|
-
// Match OpenAI/
|
|
275
|
+
// Match OpenAI OAuth/API cache-lane semantics: default to 12 stable shards (via
|
|
286
276
|
// resolveProviderPromptCacheLane) and serialize each final shard. This gives
|
|
287
277
|
// Grok/xAI 10+ worker fanout without concurrent same-key cache contention.
|
|
288
278
|
const XAI_RESPONSES_CACHE_LANE_DEFAULT_MAX_IN_FLIGHT = 1;
|
|
@@ -511,7 +501,7 @@ function acquireXaiResponsesCacheLane({ key, maxInFlight, signal, timeoutMs }) {
|
|
|
511
501
|
function traceXaiCacheLane(opts, payload) {
|
|
512
502
|
if (!compatCacheTraceEnabled('xai')) return;
|
|
513
503
|
try {
|
|
514
|
-
|
|
504
|
+
appendAgentTrace({
|
|
515
505
|
sessionId: opts?.sessionId || opts?.session?.id || null,
|
|
516
506
|
iteration: Number.isFinite(Number(opts?.iteration)) ? Number(opts.iteration) : null,
|
|
517
507
|
kind: 'cache_lane',
|
|
@@ -784,7 +774,7 @@ function traceXaiResponsesCacheContext(args) {
|
|
|
784
774
|
const payload = xaiResponsesFingerprintPayload(args);
|
|
785
775
|
const sessionId = args?.opts?.sessionId || args?.opts?.session?.id || null;
|
|
786
776
|
const iteration = Number.isFinite(Number(args?.opts?.iteration)) ? Number(args.opts.iteration) : null;
|
|
787
|
-
|
|
777
|
+
appendAgentTrace({
|
|
788
778
|
sessionId,
|
|
789
779
|
iteration,
|
|
790
780
|
kind: 'cache_context',
|
|
@@ -797,7 +787,7 @@ function traceXaiResponsesCacheContext(args) {
|
|
|
797
787
|
anomaly: 'xai_mid_turn_cold_cache',
|
|
798
788
|
reason: 'previous_response_id_present_but_cached_tokens_low',
|
|
799
789
|
};
|
|
800
|
-
|
|
790
|
+
appendAgentTrace({
|
|
801
791
|
sessionId,
|
|
802
792
|
iteration,
|
|
803
793
|
kind: 'cache_anomaly',
|
|
@@ -942,10 +932,6 @@ function toOpenAIMessages(messages, providerName, options = {}) {
|
|
|
942
932
|
return out;
|
|
943
933
|
}
|
|
944
934
|
|
|
945
|
-
function messagesHaveImageContent(messages) {
|
|
946
|
-
return (messages || []).some((m) => contentHasImage(m?.content));
|
|
947
|
-
}
|
|
948
|
-
|
|
949
935
|
function toOpenAITools(tools) {
|
|
950
936
|
return tools.map((t) => ({
|
|
951
937
|
type: 'function',
|
|
@@ -957,14 +943,34 @@ function toOpenAITools(tools) {
|
|
|
957
943
|
}));
|
|
958
944
|
}
|
|
959
945
|
function toResponsesTools(tools) {
|
|
960
|
-
return tools.map((t) =>
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
946
|
+
return tools.map((t) => {
|
|
947
|
+
if (t?.name === 'tool_search') {
|
|
948
|
+
return {
|
|
949
|
+
type: 'tool_search',
|
|
950
|
+
execution: 'client',
|
|
951
|
+
description: t.description,
|
|
952
|
+
parameters: t.inputSchema,
|
|
953
|
+
};
|
|
954
|
+
}
|
|
955
|
+
// xAI/Grok Responses rejects the OpenAI-only `type:'custom'` freeform
|
|
956
|
+
// variant ("unknown variant 'custom'"). Serialize freeform/grammar
|
|
957
|
+
// tools (e.g. apply_patch) as ordinary function tools instead. Grammar
|
|
958
|
+
// tools may carry no usable inputSchema, so fall back to a permissive
|
|
959
|
+
// object schema so grok still registers a valid function tool.
|
|
960
|
+
return {
|
|
961
|
+
type: 'function',
|
|
962
|
+
name: t.name,
|
|
963
|
+
description: t.description,
|
|
964
|
+
parameters: t.inputSchema || { type: 'object', additionalProperties: true },
|
|
965
|
+
};
|
|
966
|
+
});
|
|
966
967
|
}
|
|
967
|
-
function
|
|
968
|
+
function nativeResponsesTools(opts) {
|
|
969
|
+
return Array.isArray(opts?.nativeTools)
|
|
970
|
+
? opts.nativeTools.filter(t => t && typeof t === 'object')
|
|
971
|
+
: [];
|
|
972
|
+
}
|
|
973
|
+
export function parseToolCalls(choice, label) {
|
|
968
974
|
const calls = choice.message?.tool_calls;
|
|
969
975
|
if (!calls?.length)
|
|
970
976
|
return undefined;
|
|
@@ -979,18 +985,31 @@ function parseToolCalls(choice, label) {
|
|
|
979
985
|
arguments: parseCompletedToolCallArgumentsJson(tc.function.arguments, label, { id: tc.id, name: tc.function.name, finishReason }),
|
|
980
986
|
}));
|
|
981
987
|
}
|
|
982
|
-
function parseResponsesToolCalls(response, label) {
|
|
988
|
+
export function parseResponsesToolCalls(response, label) {
|
|
983
989
|
const out = [];
|
|
984
990
|
// A Responses tool call is only parsed off a completed/done item, so any
|
|
985
991
|
// malformed-JSON failure here is deterministic, not mid-stream truncation.
|
|
986
992
|
const finishReason = response?.status || 'completed';
|
|
987
993
|
for (const item of response?.output || []) {
|
|
988
|
-
if (item?.type
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
+
if (item?.type === 'function_call') {
|
|
995
|
+
out.push({
|
|
996
|
+
id: item.call_id || item.id,
|
|
997
|
+
name: item.name,
|
|
998
|
+
arguments: parseCompletedToolCallArgumentsJson(item.arguments, label, { id: item.call_id || item.id, name: item.name, finishReason }),
|
|
999
|
+
});
|
|
1000
|
+
} else if (item?.type === 'custom_tool_call') {
|
|
1001
|
+
const call = customToolCallFromResponseItem(item);
|
|
1002
|
+
if (call) out.push(call);
|
|
1003
|
+
} else if (item?.type === 'tool_search_call') {
|
|
1004
|
+
out.push({
|
|
1005
|
+
id: item.call_id || item.id,
|
|
1006
|
+
name: 'tool_search',
|
|
1007
|
+
arguments: item.arguments && typeof item.arguments === 'object'
|
|
1008
|
+
? item.arguments
|
|
1009
|
+
: parseCompletedToolCallArgumentsJson(item.arguments || '{}', label, { id: item.call_id || item.id, name: 'tool_search', finishReason }),
|
|
1010
|
+
nativeType: 'tool_search_call',
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
994
1013
|
}
|
|
995
1014
|
return out.length ? out : undefined;
|
|
996
1015
|
}
|
|
@@ -1005,9 +1024,71 @@ function responseOutputText(response) {
|
|
|
1005
1024
|
}
|
|
1006
1025
|
return chunks.join('');
|
|
1007
1026
|
}
|
|
1008
|
-
function
|
|
1027
|
+
function collectCompatResponseSearchSources(response) {
|
|
1028
|
+
const citations = [];
|
|
1029
|
+
const webSearchCalls = [];
|
|
1030
|
+
const seen = new Set();
|
|
1031
|
+
const addCitation = (source, fallback = {}) => {
|
|
1032
|
+
if (!source) return;
|
|
1033
|
+
if (typeof source === 'string') {
|
|
1034
|
+
const url = source.trim();
|
|
1035
|
+
if (!url || seen.has(url)) return;
|
|
1036
|
+
seen.add(url);
|
|
1037
|
+
citations.push({ title: url, url, snippet: '', source: fallback.source || 'citation', provider: 'xai' });
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
if (typeof source !== 'object') return;
|
|
1041
|
+
const url = String(
|
|
1042
|
+
source.url
|
|
1043
|
+
|| source.uri
|
|
1044
|
+
|| source.href
|
|
1045
|
+
|| source.source_url
|
|
1046
|
+
|| source.url_citation?.url
|
|
1047
|
+
|| '',
|
|
1048
|
+
).trim();
|
|
1049
|
+
if (!url || seen.has(url)) return;
|
|
1050
|
+
seen.add(url);
|
|
1051
|
+
citations.push({
|
|
1052
|
+
title: String(source.title || source.name || source.query || source.url_citation?.title || fallback.title || url).trim(),
|
|
1053
|
+
url,
|
|
1054
|
+
snippet: String(source.snippet || source.text || source.description || '').trim(),
|
|
1055
|
+
source: source.source || fallback.source || 'citation',
|
|
1056
|
+
provider: source.provider || 'xai',
|
|
1057
|
+
});
|
|
1058
|
+
};
|
|
1059
|
+
for (const citation of Array.isArray(response?.citations) ? response.citations : []) addCitation(citation);
|
|
1060
|
+
for (const item of Array.isArray(response?.output) ? response.output : []) {
|
|
1061
|
+
if (item?.type === 'web_search_call') {
|
|
1062
|
+
webSearchCalls.push({ id: item.id || '', status: item.status || '', action: item.action || null });
|
|
1063
|
+
const action = item.action || {};
|
|
1064
|
+
for (const source of Array.isArray(action.sources) ? action.sources : []) addCitation(source, { title: action.query || '', source: 'web_search_call' });
|
|
1065
|
+
if (action.url) addCitation({ url: action.url, title: action.query || '' }, { source: 'web_search_call' });
|
|
1066
|
+
for (const url of Array.isArray(action.urls) ? action.urls : []) addCitation({ url, title: action.query || '' }, { source: 'web_search_call' });
|
|
1067
|
+
}
|
|
1068
|
+
for (const citation of Array.isArray(item?.citations) ? item.citations : []) addCitation(citation);
|
|
1069
|
+
for (const part of Array.isArray(item?.content) ? item.content : []) {
|
|
1070
|
+
for (const annotation of Array.isArray(part?.annotations) ? part.annotations : []) {
|
|
1071
|
+
addCitation(annotation, { source: 'annotation' });
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
return { citations, webSearchCalls };
|
|
1076
|
+
}
|
|
1077
|
+
function toResponsesInputMessage(m, pendingToolMedia = null, customToolCallNameById = null) {
|
|
1009
1078
|
if (m.role === 'tool') {
|
|
1079
|
+
if (Array.isArray(m.nativeToolSearch?.openaiTools)) {
|
|
1080
|
+
return {
|
|
1081
|
+
type: 'tool_search_output',
|
|
1082
|
+
call_id: m.toolCallId || '',
|
|
1083
|
+
status: 'completed',
|
|
1084
|
+
execution: 'client',
|
|
1085
|
+
tools: m.nativeToolSearch.openaiTools,
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1010
1088
|
const { output, mediaContent } = splitToolContentForOpenAIResponses(m.content);
|
|
1089
|
+
// xai path: never emit `custom_tool_call_output` (the `custom` variant
|
|
1090
|
+
// is rejected by grok). Replay prior tool outputs as the standard
|
|
1091
|
+
// `function_call_output` item regardless of original native type.
|
|
1011
1092
|
const item = {
|
|
1012
1093
|
type: 'function_call_output',
|
|
1013
1094
|
call_id: m.toolCallId || '',
|
|
@@ -1020,12 +1101,25 @@ function toResponsesInputMessage(m, pendingToolMedia = null) {
|
|
|
1020
1101
|
const items = [];
|
|
1021
1102
|
if (m.content) items.push({ role: 'assistant', content: normalizeContentForOpenAIResponses(m.content, { role: 'assistant' }) });
|
|
1022
1103
|
for (const tc of m.toolCalls) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1104
|
+
if (tc.nativeType === 'tool_search_call' || tc.name === 'tool_search') {
|
|
1105
|
+
items.push({
|
|
1106
|
+
type: 'tool_search_call',
|
|
1107
|
+
call_id: tc.id,
|
|
1108
|
+
execution: 'client',
|
|
1109
|
+
arguments: tc.arguments || {},
|
|
1110
|
+
});
|
|
1111
|
+
} else {
|
|
1112
|
+
// xai path: prior native `custom_tool_call` history is replayed
|
|
1113
|
+
// as a standard `function_call` (grok rejects the `custom`
|
|
1114
|
+
// variant). tc.arguments already holds the recovered object
|
|
1115
|
+
// form, so the same stringify path as regular calls applies.
|
|
1116
|
+
items.push({
|
|
1117
|
+
type: 'function_call',
|
|
1118
|
+
call_id: tc.id,
|
|
1119
|
+
name: tc.name,
|
|
1120
|
+
arguments: JSON.stringify(tc.arguments || {}),
|
|
1121
|
+
});
|
|
1122
|
+
}
|
|
1029
1123
|
}
|
|
1030
1124
|
return items;
|
|
1031
1125
|
}
|
|
@@ -1062,6 +1156,7 @@ function toXaiResponsesInput(messages, providerState, options = {}) {
|
|
|
1062
1156
|
}
|
|
1063
1157
|
const input = [];
|
|
1064
1158
|
const pendingToolMedia = [];
|
|
1159
|
+
const customToolCallNameById = new Map();
|
|
1065
1160
|
const flushToolMedia = () => {
|
|
1066
1161
|
if (!pendingToolMedia.length) return;
|
|
1067
1162
|
input.push({ role: 'user', content: pendingToolMedia.splice(0) });
|
|
@@ -1069,7 +1164,7 @@ function toXaiResponsesInput(messages, providerState, options = {}) {
|
|
|
1069
1164
|
for (const m of messages.slice(startIndex)) {
|
|
1070
1165
|
if (!includeSystem && m.role === 'system') continue;
|
|
1071
1166
|
if (m.role !== 'tool') flushToolMedia();
|
|
1072
|
-
const converted = toResponsesInputMessage(m, pendingToolMedia);
|
|
1167
|
+
const converted = toResponsesInputMessage(m, pendingToolMedia, customToolCallNameById);
|
|
1073
1168
|
if (Array.isArray(converted)) input.push(...converted);
|
|
1074
1169
|
else input.push(converted);
|
|
1075
1170
|
}
|
|
@@ -1145,8 +1240,35 @@ export class OpenAICompatProvider {
|
|
|
1145
1240
|
const useModel = model || this.defaultModel;
|
|
1146
1241
|
const opts = sendOpts || {};
|
|
1147
1242
|
if (this.name === 'xai' && useXaiResponsesApi(opts, this.config)) {
|
|
1148
|
-
if (useXaiResponsesWebSocket(opts, this.config)
|
|
1149
|
-
|
|
1243
|
+
if (useXaiResponsesWebSocket(opts, this.config)) {
|
|
1244
|
+
try {
|
|
1245
|
+
return await this._doSendXaiResponsesWebSocket(messages, useModel, tools, opts);
|
|
1246
|
+
} catch (err) {
|
|
1247
|
+
if (_shouldFallbackXaiWsToHttp(err, opts.signal)) {
|
|
1248
|
+
const reason = err?.midstreamClassifier || err?.retryClassifier || err?.code || err?.message || 'ws_failed';
|
|
1249
|
+
process.stderr.write(`[xai:responses] WebSocket unhealthy (${reason}); falling back to HTTP/SSE\n`);
|
|
1250
|
+
try {
|
|
1251
|
+
appendAgentTrace({
|
|
1252
|
+
sessionId: opts?.sessionId || opts?.session?.id || null,
|
|
1253
|
+
iteration: Number.isFinite(Number(opts?.iteration)) ? Number(opts.iteration) : null,
|
|
1254
|
+
kind: 'transport_fallback',
|
|
1255
|
+
provider: 'xai',
|
|
1256
|
+
model: useModel,
|
|
1257
|
+
transport: 'http',
|
|
1258
|
+
payload: {
|
|
1259
|
+
from: 'websocket',
|
|
1260
|
+
to: 'http',
|
|
1261
|
+
reason,
|
|
1262
|
+
error_code: err?.code || null,
|
|
1263
|
+
error_http_status: Number(err?.httpStatus || 0) || null,
|
|
1264
|
+
error_classifier: err?.retryClassifier || err?.midstreamClassifier || null,
|
|
1265
|
+
},
|
|
1266
|
+
});
|
|
1267
|
+
} catch {}
|
|
1268
|
+
return await this._doSendXaiResponses(messages, useModel, tools, opts);
|
|
1269
|
+
}
|
|
1270
|
+
throw err;
|
|
1271
|
+
}
|
|
1150
1272
|
}
|
|
1151
1273
|
return await this._doSendXaiResponses(messages, useModel, tools, opts);
|
|
1152
1274
|
}
|
|
@@ -1283,7 +1405,7 @@ export class OpenAICompatProvider {
|
|
|
1283
1405
|
if (response.usage) {
|
|
1284
1406
|
const inputTokens = Number(response.usage.prompt_tokens ?? response.usage.input_tokens ?? 0);
|
|
1285
1407
|
const cachedTokens = extractCompatCachedTokens(response.usage);
|
|
1286
|
-
|
|
1408
|
+
traceAgentUsage({
|
|
1287
1409
|
sessionId: opts.sessionId || opts.session?.id || null,
|
|
1288
1410
|
iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
|
|
1289
1411
|
inputTokens,
|
|
@@ -1357,9 +1479,10 @@ export class OpenAICompatProvider {
|
|
|
1357
1479
|
prompt_cache_key: cacheRouting.key,
|
|
1358
1480
|
};
|
|
1359
1481
|
if (previousResponseId) params.previous_response_id = previousResponseId;
|
|
1360
|
-
|
|
1482
|
+
const nativeTools = nativeResponsesTools(opts);
|
|
1483
|
+
if (tools?.length || nativeTools.length) params.tools = [...nativeTools, ...toResponsesTools(tools || [])];
|
|
1361
1484
|
// SSE transport: report 'requesting' until the stream opens, then
|
|
1362
|
-
// per-chunk onStreamDelta feeds the
|
|
1485
|
+
// per-chunk onStreamDelta feeds the agent stall watchdog.
|
|
1363
1486
|
try { opts.onStageChange?.('requesting'); } catch { /* heartbeat best-effort */ }
|
|
1364
1487
|
const reasoningEffort = normalizeXaiReasoningEffort(opts.xaiReasoningEffort
|
|
1365
1488
|
?? opts.effort
|
|
@@ -1453,7 +1576,7 @@ export class OpenAICompatProvider {
|
|
|
1453
1576
|
if (response.usage) {
|
|
1454
1577
|
const inputTokens = Number(response.usage.input_tokens ?? response.usage.prompt_tokens ?? 0);
|
|
1455
1578
|
const cachedTokens = extractCompatCachedTokens(response.usage);
|
|
1456
|
-
|
|
1579
|
+
traceAgentUsage({
|
|
1457
1580
|
sessionId: opts.sessionId || opts.session?.id || null,
|
|
1458
1581
|
iteration: Number.isFinite(Number(opts.iteration)) ? Number(opts.iteration) : null,
|
|
1459
1582
|
inputTokens,
|
|
@@ -1469,11 +1592,14 @@ export class OpenAICompatProvider {
|
|
|
1469
1592
|
});
|
|
1470
1593
|
}
|
|
1471
1594
|
const nextPreviousResponseId = streamed.stopReason === 'length' ? null : response.id;
|
|
1595
|
+
const searchSources = collectCompatResponseSearchSources(response);
|
|
1472
1596
|
return {
|
|
1473
1597
|
content: streamed.content,
|
|
1474
1598
|
model: response.model || useModel,
|
|
1475
1599
|
toolCalls,
|
|
1476
1600
|
stopReason: streamed.stopReason || null,
|
|
1601
|
+
citations: searchSources.citations.length ? searchSources.citations : undefined,
|
|
1602
|
+
webSearchCalls: searchSources.webSearchCalls.length ? searchSources.webSearchCalls : undefined,
|
|
1477
1603
|
providerState: {
|
|
1478
1604
|
...(opts.providerState || {}),
|
|
1479
1605
|
xaiResponses: {
|
|
@@ -1529,7 +1655,8 @@ export class OpenAICompatProvider {
|
|
|
1529
1655
|
// xAI rejects instructions together with previous_response_id; the
|
|
1530
1656
|
// first response already anchors instructions for the continuation.
|
|
1531
1657
|
else if (instructions) params.instructions = instructions;
|
|
1532
|
-
|
|
1658
|
+
const nativeTools = nativeResponsesTools(opts);
|
|
1659
|
+
if (tools?.length || nativeTools.length) params.tools = [...nativeTools, ...toResponsesTools(tools || [])];
|
|
1533
1660
|
const reasoningEffort = normalizeXaiReasoningEffort(opts.xaiReasoningEffort
|
|
1534
1661
|
?? opts.effort
|
|
1535
1662
|
?? this.config?.reasoningEffort
|
|
@@ -1640,6 +1767,8 @@ export class OpenAICompatProvider {
|
|
|
1640
1767
|
...result.usage,
|
|
1641
1768
|
...(costUsd != null ? { costUsd } : {}),
|
|
1642
1769
|
} : undefined,
|
|
1770
|
+
citations: Array.isArray(result.citations) && result.citations.length ? result.citations : undefined,
|
|
1771
|
+
webSearchCalls: Array.isArray(result.webSearchCalls) && result.webSearchCalls.length ? result.webSearchCalls : undefined,
|
|
1643
1772
|
};
|
|
1644
1773
|
}
|
|
1645
1774
|
async _fetchModelItems() {
|
|
@@ -1717,3 +1846,6 @@ export class OpenAICompatProvider {
|
|
|
1717
1846
|
return null;
|
|
1718
1847
|
}
|
|
1719
1848
|
}
|
|
1849
|
+
|
|
1850
|
+
export const _toResponsesToolsForTest = toResponsesTools;
|
|
1851
|
+
export const _toXaiResponsesInputForTest = toXaiResponsesInput;
|