mixdog 0.9.147 → 0.9.148
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/package.json +23 -3
- package/scripts/build-voice-runtime-unix.sh +101 -0
- package/scripts/embedding-quality-probe.mjs +96 -0
- package/scripts/generate-voice-runtime-manifest.mjs +300 -0
- package/scripts/generate-voice-runtime-manifest.test.mjs +135 -0
- package/scripts/native-binary-arch.mjs +30 -13
- package/scripts/native-binary-arch.test.mjs +40 -4
- package/scripts/plan-voice-runtime-release.mjs +73 -0
- package/scripts/prepare-native-assets.mjs +50 -9
- package/scripts/prune-embedding-runtime.mjs +3 -3
- package/scripts/sync-voice-runtime-manifest.mjs +46 -0
- package/scripts/verify-release-assets.mjs +106 -6
- package/scripts/verify-voice-runtime-release.mjs +89 -0
- package/scripts/voice-runtime-config.json +52 -0
- package/src/app.mjs +42 -5
- package/src/headless-exec.mjs +58 -32
- package/src/headless-exec.test.mjs +74 -13
- package/src/rules/lead/01-general.md +2 -0
- package/src/rules/shared/10-tool-workflow.md +7 -4
- package/src/rules/shared/30-exploration.md +2 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +28 -9
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +6 -1
- package/src/runtime/agent/orchestrator/config.mjs +53 -18
- package/src/runtime/agent/orchestrator/mcp/cancellation.test.mjs +139 -0
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +34 -5
- package/src/runtime/agent/orchestrator/mcp/client.mjs +94 -10
- package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +98 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.test.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-leaked-toolcall.mjs +67 -16
- package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +4 -82
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +0 -5
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +62 -121
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +48 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.test.mjs +215 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +44 -48
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +54 -31
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +56 -2
- package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +34 -2
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +61 -1
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +6 -1
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +61 -15
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +120 -1
- package/src/runtime/agent/orchestrator/providers/lib/env-utils.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/lib/stream-outcome.mjs +0 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +187 -84
- package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +36 -36
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +16 -6
- package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +50 -213
- package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +135 -126
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +17 -11
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +20 -7
- package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +11 -0
- package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +132 -42
- package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -2
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +28 -10
- package/src/runtime/agent/orchestrator/providers/registry.mjs +122 -95
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +58 -3
- package/src/runtime/agent/orchestrator/providers/tool-stream-state.mjs +4 -22
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +7 -14
- package/src/runtime/agent/orchestrator/session/compact-policy.test.mjs +128 -0
- package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +5 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +27 -48
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +19 -14
- package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +9 -43
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +15 -2
- package/src/runtime/agent/orchestrator/session/manager/pending-messages-persistence.test.mjs +325 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +599 -195
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +22 -0
- package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +9 -2
- package/src/runtime/agent/orchestrator/session/manager.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +26 -16
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +23 -11
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +118 -3
- package/src/runtime/agent/orchestrator/session/store-summary-reader.test.mjs +332 -0
- package/src/runtime/agent/orchestrator/session/store.mjs +38 -1
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +27 -6
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -20
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +291 -128
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +45 -8
- package/src/runtime/agent/orchestrator/tools/builtin/edit-encoding-eol.test.mjs +224 -0
- package/src/runtime/agent/orchestrator/tools/builtin/edit-sequential-occupation.test.mjs +53 -3
- package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +255 -25
- package/src/runtime/agent/orchestrator/tools/builtin/find-search-budget.test.mjs +87 -0
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +132 -9
- package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.test.mjs +10 -0
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-pattern-fanout.mjs +29 -3
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +178 -29
- package/src/runtime/agent/orchestrator/tools/builtin/local-search-telemetry.mjs +4 -1
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +32 -5
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-health.test.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-runner.mjs +10 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +38 -10
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +31 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +11 -1
- package/src/runtime/agent/orchestrator/tools/builtin/read-windows.mjs +22 -4
- package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +6 -8
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +25 -24
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +152 -133
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +114 -42
- package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +129 -15
- package/src/runtime/agent/orchestrator/tools/code-graph/loose-file-target.test.mjs +72 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +7 -8
- package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +4 -4
- package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +201 -19
- package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +26 -3
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +10 -1
- package/src/runtime/agent/orchestrator/tools/code-graph/symbol-search-scope.test.mjs +55 -0
- package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +115 -25
- package/src/runtime/agent/orchestrator/tools/code-graph/text-span-mask.test.mjs +268 -0
- package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +3 -3
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +296 -46
- package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.test.mjs +104 -0
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +136 -0
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +127 -38
- package/src/runtime/agent/orchestrator/tools/patch/engine-contract-gate.test.mjs +661 -0
- package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +350 -9
- package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +418 -44
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +27 -3
- package/src/runtime/agent/orchestrator/tools/patch/patch-codec-eol.test.mjs +552 -0
- package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +65 -15
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +11 -11
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +284 -109
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +51 -21
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +44 -27
- package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +11 -11
- package/src/runtime/attachments/store.mjs +11 -3
- package/src/runtime/channels/data/voice-runtime-manifest.json +46 -70
- package/src/runtime/channels/lib/event-queue.mjs +51 -41
- package/src/runtime/channels/lib/scheduler.mjs +23 -28
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -17
- package/src/runtime/channels/lib/voice-runtime-fetcher.test.mjs +17 -0
- package/src/runtime/channels/lib/webhook.mjs +39 -20
- package/src/runtime/channels/lib/whisper-server.mjs +46 -1
- package/src/runtime/channels/lib/worker-main.mjs +3 -1
- package/src/runtime/media/adapters/gemini-video.mjs +20 -4
- package/src/runtime/media/jobs.mjs +13 -0
- package/src/runtime/media/renditions.mjs +7 -1
- package/src/runtime/media/store.mjs +42 -22
- package/src/runtime/memory/index.mjs +4 -9
- package/src/runtime/memory/lib/agent-ipc.mjs +1 -6
- package/src/runtime/memory/lib/archive-security.test.mjs +21 -1
- package/src/runtime/memory/lib/core-memory-store.mjs +28 -50
- package/src/runtime/memory/lib/embedding-model-config.mjs +37 -1
- package/src/runtime/memory/lib/embedding-model-config.test.mjs +33 -0
- package/src/runtime/memory/lib/embedding-provider.mjs +34 -12
- package/src/runtime/memory/lib/embedding-worker.mjs +37 -5
- package/src/runtime/memory/lib/ko-morph.mjs +46 -15
- package/src/runtime/memory/lib/memory-action-handlers.mjs +18 -1
- package/src/runtime/memory/lib/memory-cycle1.mjs +1 -18
- package/src/runtime/memory/lib/memory-cycle2-gate.mjs +1 -18
- package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +98 -45
- package/src/runtime/memory/lib/memory-cycle2-shared.mjs +71 -0
- package/src/runtime/memory/lib/memory-cycle2-shared.test.mjs +78 -0
- package/src/runtime/memory/lib/memory-cycle2.mjs +37 -3
- package/src/runtime/memory/lib/memory-cycle3.mjs +1 -1
- package/src/runtime/memory/lib/memory-embedding-migration.test.mjs +50 -0
- package/src/runtime/memory/lib/memory-recall-store.mjs +9 -24
- package/src/runtime/memory/lib/memory.mjs +50 -12
- package/src/runtime/memory/lib/pg/process.mjs +1 -10
- package/src/runtime/memory/lib/pg/supervisor.mjs +1 -9
- package/src/runtime/memory/lib/query-handlers.mjs +2 -4
- package/src/runtime/memory/lib/session-ingest-runtime.mjs +2 -2
- package/src/runtime/shared/background-tasks.mjs +15 -0
- package/src/runtime/shared/background-tasks.test.mjs +78 -0
- package/src/runtime/shared/child-guardian.mjs +2 -10
- package/src/runtime/shared/pid-liveness.mjs +27 -0
- package/src/runtime/shared/runtime-root.mjs +1 -11
- package/src/runtime/shared/service-discovery.mjs +1 -17
- package/src/runtime/shared/singleton-owner.mjs +1 -11
- package/src/runtime/shared/staged-update.mjs +2 -12
- package/src/runtime/shared/tool-status.mjs +5 -1
- package/src/runtime/shared/tool-surface.mjs +15 -7
- package/src/runtime/shared/turn-snapshot-store.mjs +168 -0
- package/src/runtime/shared/turn-snapshot.mjs +137 -13
- package/src/runtime/shared/turn-worktree-snapshot.mjs +110 -18
- package/src/runtime/shared/webhook-session-run.mjs +16 -2
- package/src/runtime/web-search/lib/http-fetch.mjs +34 -4
- package/src/runtime/web-search/lib/state.mjs +15 -15
- package/src/runtime/web-search/lib/web-tools.mjs +46 -5
- package/src/session-runtime/context-status.mjs +4 -12
- package/src/session-runtime/runtime-core.mjs +20 -1
- package/src/standalone/agent-dispatch-broker.mjs +33 -2
- package/src/standalone/agent-tool/job-task-reconcile.mjs +78 -0
- package/src/standalone/agent-tool/notify.mjs +3 -1
- package/src/standalone/agent-tool/spawn-flow.mjs +48 -66
- package/src/standalone/agent-tool/tag-registry.mjs +116 -33
- package/src/standalone/agent-tool/tool-def.mjs +2 -2
- package/src/standalone/agent-tool/worker-index.mjs +8 -11
- package/src/standalone/agent-tool/worker-rows.mjs +4 -1
- package/src/standalone/agent-tool.mjs +20 -55
- package/src/standalone/agent-watchdog-registry.mjs +28 -4
- package/src/standalone/channel-client.mjs +47 -15
- package/src/standalone/channel-transport.mjs +44 -25
- package/src/standalone/daemon.mjs +31 -2
- package/src/standalone/hook-bus/config.mjs +25 -9
- package/src/standalone/hook-bus/handlers.mjs +16 -52
- package/src/standalone/hook-bus.mjs +29 -23
- package/src/standalone/memory-runtime-proxy.mjs +1 -16
- package/src/standalone/session-client.mjs +86 -23
- package/src/standalone/session-protocol.mjs +0 -2
- package/src/standalone/session-runtime-host-health.test.mjs +5 -4
- package/src/standalone/session-runtime-host.mjs +101 -6
- package/src/standalone/session-runtime-record.mjs +1 -5
- package/src/standalone/session-runtime-worker.mjs +52 -57
- package/src/standalone/session-service.mjs +4 -1
- package/src/standalone/session-transport.mjs +56 -25
- package/src/tui/App.jsx +40 -49
- package/src/tui/app/app-view.jsx +14 -21
- package/src/tui/app/core-memory-picker.mjs +29 -16
- package/src/tui/app/create-app-pickers.mjs +15 -36
- package/src/tui/app/extension-pickers.mjs +60 -49
- package/src/tui/app/maintenance-pickers.mjs +100 -57
- package/src/tui/app/message-selector.mjs +6 -5
- package/src/tui/app/model-picker.mjs +30 -13
- package/src/tui/app/onboarding-steps.mjs +21 -12
- package/src/tui/app/panel-epoch.mjs +56 -0
- package/src/tui/app/panel-epoch.test.mjs +1009 -0
- package/src/tui/app/panel-surface.mjs +98 -0
- package/src/tui/app/project-picker.mjs +30 -29
- package/src/tui/app/prompt-submit.mjs +192 -97
- package/src/tui/app/prompt-submit.test.mjs +206 -0
- package/src/tui/app/provider-setup-picker.mjs +74 -43
- package/src/tui/app/resume-picker.mjs +11 -8
- package/src/tui/app/route-pickers.mjs +45 -28
- package/src/tui/app/settings-picker.mjs +69 -18
- package/src/tui/app/shell-layout.mjs +1 -3
- package/src/tui/app/slash-commands.mjs +0 -2
- package/src/tui/app/slash-dispatch.mjs +4 -2
- package/src/tui/app/text-entry-policy.mjs +25 -0
- package/src/tui/app/theme-effort-pickers.mjs +11 -16
- package/src/tui/app/usage-context-panels.mjs +21 -25
- package/src/tui/app/use-global-key-input.mjs +3 -2
- package/src/tui/app/use-prompt-draft-flow.mjs +6 -18
- package/src/tui/app/use-prompt-handlers.mjs +3 -2
- package/src/tui/app/use-welcome-prompt-hint.mjs +17 -3
- package/src/tui/components/Picker.jsx +1 -1
- package/src/tui/components/TextEntryPanel.jsx +7 -2
- package/src/tui/dist/index.mjs +652 -561
- package/src/tui/lib/voice-setup.mjs +1 -2
- package/src/tui/session/agent-job-feed.mjs +73 -11
- package/src/tui/session/session-api-ext.mjs +5 -6
- package/src/tui/session/session-api.mjs +1 -0
- package/src/tui/session/tool-approval.mjs +15 -5
- package/src/tui/session/tui-steering-persist.mjs +33 -19
- package/src/tui/session/tui-steering-persist.test.mjs +104 -0
- package/src/tui/session-local.mjs +0 -22
- package/scripts/.tmp-coverage-report.mjs +0 -96
- package/src/runtime/agent/orchestrator/tools/builtin/shell-monitor.mjs +0 -57
- package/src/runtime/agent/orchestrator/tools/builtin/shell-monitor.test.mjs +0 -57
|
@@ -152,11 +152,16 @@ function mergeToolCallDelta(accByIndex, deltaCalls, bucketState) {
|
|
|
152
152
|
} else if (tc.function?.name) {
|
|
153
153
|
const anonId = ++bucketState._nextAnonId;
|
|
154
154
|
key = `anon:${anonId}`;
|
|
155
|
-
bucketState._lastAnonKey = key;
|
|
156
155
|
} else {
|
|
157
156
|
key = bucketState._lastAnonKey;
|
|
158
157
|
if (!key) continue;
|
|
159
158
|
}
|
|
159
|
+
// Whatever bucket this chunk resolved to becomes the continuation
|
|
160
|
+
// target for later argument-only chunks (no index, no id, no name).
|
|
161
|
+
// Only the anonymous branch used to record it, so a provider that
|
|
162
|
+
// identifies a tool call by id alone and then streams bare argument
|
|
163
|
+
// deltas had every one of those deltas silently discarded.
|
|
164
|
+
bucketState._lastAnonKey = key;
|
|
160
165
|
let prev = accByIndex.get(key);
|
|
161
166
|
if (!prev) {
|
|
162
167
|
prev = {
|
|
@@ -210,7 +215,7 @@ function emitCompatToolCallOnce(state, call, onToolCall) {
|
|
|
210
215
|
// Fix 2: cross-path name+args dedupe. A synthesized text-leaked call and an
|
|
211
216
|
// identical native tool_call must fire onToolCall exactly once. state._toolDedupe
|
|
212
217
|
// is created per stream; when absent (older callers) behavior is unchanged.
|
|
213
|
-
if (state._toolDedupe && !state._toolDedupe.shouldDispatch(call.name, call.arguments)) {
|
|
218
|
+
if (state._toolDedupe && !state._toolDedupe.shouldDispatch(call.name, call.arguments, call.id)) {
|
|
214
219
|
// Still mark the id as emitted so later id-frames for the same native
|
|
215
220
|
// call don't retry, but do NOT invoke onToolCall (already dispatched).
|
|
216
221
|
state.emittedToolCallKeys.add(key);
|
|
@@ -556,6 +561,33 @@ export async function consumeCompatChatCompletionStream(stream, {
|
|
|
556
561
|
};
|
|
557
562
|
}
|
|
558
563
|
|
|
564
|
+
// Reconcile a COMPLETED function_call item into state.toolCalls: fill in the
|
|
565
|
+
// id/name a streamed call may still be missing, or adopt the item as a new
|
|
566
|
+
// call. `response.output_item.done` and the `response.completed` sweep see the
|
|
567
|
+
// same item shape and must land on the same single emit, so both route here.
|
|
568
|
+
// Returns the item id the done-branch still needs for its pendingCalls /
|
|
569
|
+
// tool-tracker bookkeeping.
|
|
570
|
+
function reconcileCompatFunctionCallItem(state, item, label, onToolCall) {
|
|
571
|
+
const itemId = item.id || '';
|
|
572
|
+
const tc = state.toolCalls.find(t => t._pendingItemId === itemId)
|
|
573
|
+
|| (item.call_id ? state.toolCalls.find(t => t.id === item.call_id) : null);
|
|
574
|
+
if (tc) {
|
|
575
|
+
if (!tc.id && item.call_id) tc.id = item.call_id;
|
|
576
|
+
if (!tc.name && item.name) tc.name = item.name;
|
|
577
|
+
if (tc.id && tc.name) delete tc._pendingItemId;
|
|
578
|
+
emitCompatToolCallOnce(state, tc, onToolCall);
|
|
579
|
+
} else if (item.call_id && item.name) {
|
|
580
|
+
const call = {
|
|
581
|
+
id: item.call_id,
|
|
582
|
+
name: item.name,
|
|
583
|
+
arguments: parseCompletedToolCallArgumentsJson(item.arguments, label, { id: item.call_id, name: item.name, finishReason: 'done' }),
|
|
584
|
+
};
|
|
585
|
+
state.toolCalls.push(call);
|
|
586
|
+
emitCompatToolCallOnce(state, call, onToolCall);
|
|
587
|
+
}
|
|
588
|
+
return itemId;
|
|
589
|
+
}
|
|
590
|
+
|
|
559
591
|
function handleCompatResponsesStreamEvent(event, state, { label, parseResponsesToolCalls, responseOutputText, onStreamDelta, onToolCall, onTextDelta, relayLeakText }) {
|
|
560
592
|
if (!event || typeof event.type !== 'string') return;
|
|
561
593
|
const pushToolSearchCall = (item) => {
|
|
@@ -671,23 +703,7 @@ function handleCompatResponsesStreamEvent(event, state, { label, parseResponsesT
|
|
|
671
703
|
case 'response.output_item.done': {
|
|
672
704
|
const item = event.item || {};
|
|
673
705
|
if (item.type === 'function_call') {
|
|
674
|
-
const itemId = item
|
|
675
|
-
const tc = state.toolCalls.find(t => t._pendingItemId === itemId)
|
|
676
|
-
|| (item.call_id ? state.toolCalls.find(t => t.id === item.call_id) : null);
|
|
677
|
-
if (tc) {
|
|
678
|
-
if (!tc.id && item.call_id) tc.id = item.call_id;
|
|
679
|
-
if (!tc.name && item.name) tc.name = item.name;
|
|
680
|
-
if (tc.id && tc.name) delete tc._pendingItemId;
|
|
681
|
-
emitCompatToolCallOnce(state, tc, onToolCall);
|
|
682
|
-
} else if (item.call_id && item.name) {
|
|
683
|
-
const call = {
|
|
684
|
-
id: item.call_id,
|
|
685
|
-
name: item.name,
|
|
686
|
-
arguments: parseCompletedToolCallArgumentsJson(item.arguments, label, { id: item.call_id, name: item.name, finishReason: 'done' }),
|
|
687
|
-
};
|
|
688
|
-
state.toolCalls.push(call);
|
|
689
|
-
emitCompatToolCallOnce(state, call, onToolCall);
|
|
690
|
-
}
|
|
706
|
+
const itemId = reconcileCompatFunctionCallItem(state, item, label, onToolCall);
|
|
691
707
|
// Drop the resolved function item from pendingCalls before
|
|
692
708
|
// recomputing toolInFlight — otherwise a completed call keeps
|
|
693
709
|
// pendingCalls.size > 0 and the latch never clears, so a later
|
|
@@ -732,23 +748,7 @@ function handleCompatResponsesStreamEvent(event, state, { label, parseResponsesT
|
|
|
732
748
|
}
|
|
733
749
|
for (const item of resp.output || []) {
|
|
734
750
|
if (item?.type === 'function_call') {
|
|
735
|
-
|
|
736
|
-
const tc = state.toolCalls.find(t => t._pendingItemId === itemId)
|
|
737
|
-
|| (item.call_id ? state.toolCalls.find(t => t.id === item.call_id) : null);
|
|
738
|
-
if (tc) {
|
|
739
|
-
if (!tc.id && item.call_id) tc.id = item.call_id;
|
|
740
|
-
if (!tc.name && item.name) tc.name = item.name;
|
|
741
|
-
if (tc.id && tc.name) delete tc._pendingItemId;
|
|
742
|
-
emitCompatToolCallOnce(state, tc, onToolCall);
|
|
743
|
-
} else if (item.call_id && item.name) {
|
|
744
|
-
const call = {
|
|
745
|
-
id: item.call_id,
|
|
746
|
-
name: item.name,
|
|
747
|
-
arguments: parseCompletedToolCallArgumentsJson(item.arguments, label, { id: item.call_id, name: item.name, finishReason: 'done' }),
|
|
748
|
-
};
|
|
749
|
-
state.toolCalls.push(call);
|
|
750
|
-
emitCompatToolCallOnce(state, call, onToolCall);
|
|
751
|
-
}
|
|
751
|
+
reconcileCompatFunctionCallItem(state, item, label, onToolCall);
|
|
752
752
|
try { onStreamDelta?.('tool'); } catch {}
|
|
753
753
|
reportedBundleProgress = true;
|
|
754
754
|
} else if (item?.type === 'tool_search_call') {
|
|
@@ -44,13 +44,15 @@ export function toOpenAIMessages(messages, providerName, options = {}) {
|
|
|
44
44
|
// strict providers (xai) reject unknown roles/types and would 400 the
|
|
45
45
|
// request. Documented in v0.1.160 (GPT reasoning replay).
|
|
46
46
|
//
|
|
47
|
-
// DeepSeek thinking models
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
51
|
-
//
|
|
47
|
+
// DeepSeek splits by model: thinking-mode models with tools REQUIRE the
|
|
48
|
+
// prior turn's `reasoning_content` echoed back (400 without it), while
|
|
49
|
+
// `deepseek-reasoner` REJECTS it with a 400. The caller decides per model
|
|
50
|
+
// through options.replaysReasoningContent — see
|
|
51
|
+
// deepseekReplaysReasoningContent below. xAI reasoning models preserve
|
|
52
|
+
// their official multi-turn shape and cache prefix stability when prior
|
|
53
|
+
// assistant reasoning_content is replayed; reasoning_effort itself remains
|
|
54
|
+
// caller/user-selected.
|
|
52
55
|
const replaysReasoningContent = options.replaysReasoningContent === true
|
|
53
|
-
|| providerName === 'deepseek'
|
|
54
56
|
|| providerName === 'xai';
|
|
55
57
|
const out = [];
|
|
56
58
|
const pendingToolMedia = [];
|
|
@@ -94,6 +96,14 @@ export function toOpenAIMessages(messages, providerName, options = {}) {
|
|
|
94
96
|
return out;
|
|
95
97
|
}
|
|
96
98
|
|
|
99
|
+
// deepseek-reasoner returns 400 when `reasoning_content` appears in the input
|
|
100
|
+
// messages; every other DeepSeek thinking model needs it back once tools are in
|
|
101
|
+
// play. Unknown DeepSeek ids default to replaying: a missing echo breaks the
|
|
102
|
+
// tool loop, while a stray field on a non-thinking model is ignored.
|
|
103
|
+
export function deepseekReplaysReasoningContent(model) {
|
|
104
|
+
return !/reasoner/.test(String(model || '').trim().toLowerCase());
|
|
105
|
+
}
|
|
106
|
+
|
|
97
107
|
export function toOpenAITools(tools) {
|
|
98
108
|
return tools.map((t) => ({
|
|
99
109
|
type: 'function',
|
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
* openai-compat-xai.mjs — xAI/Grok Responses-API routing, prompt-cache lanes
|
|
3
3
|
* and cache tracing for the OpenAI-compat provider.
|
|
4
4
|
*
|
|
5
|
-
* Extracted from openai-compat.mjs. Owns the xAI cache
|
|
6
|
-
* (
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Extracted from openai-compat.mjs. Owns the xAI prompt-cache lane RESOLUTION
|
|
6
|
+
* (shard/slot selection) plus cache routing/fingerprint/trace helpers and the
|
|
7
|
+
* compat cache trace writer shared by chat-completions and Responses paths.
|
|
8
|
+
* openai-compat.mjs imports the routing/lane/trace entry points. Admission is
|
|
9
|
+
* owned exclusively by the shared provider scheduler — there is no second
|
|
10
|
+
* cache-lane queue here.
|
|
9
11
|
*/
|
|
10
12
|
import { createHash } from 'crypto';
|
|
11
13
|
import { appendAgentTrace } from '../agent-trace.mjs';
|
|
@@ -14,6 +16,10 @@ import {
|
|
|
14
16
|
resolveProviderPromptCacheLane,
|
|
15
17
|
} from '../agent-runtime/cache-strategy.mjs';
|
|
16
18
|
import { shouldFallbackTransport } from './retry-classifier.mjs';
|
|
19
|
+
import { envFlag as _envFlag } from './lib/env-utils.mjs';
|
|
20
|
+
// Same named export as before the shared helper move: importers of this module
|
|
21
|
+
// keep reading `_envFlag` from here.
|
|
22
|
+
export { _envFlag };
|
|
17
23
|
import { traceHash, stableTraceStringify, summarizeTraceTools, traceTextShape } from './trace-utils.mjs';
|
|
18
24
|
import { summarizeTraceMessages, extractCompatCachedTokens } from './openai-compat-trace.mjs';
|
|
19
25
|
|
|
@@ -92,7 +98,7 @@ export function xaiResponsesCacheRouting(opts, params, rawTools, model) {
|
|
|
92
98
|
// session per process, where round-robin degenerates to slot 0 for
|
|
93
99
|
// everyone). Default stays a single shared key (lane disabled) —
|
|
94
100
|
// identical seed/key to before.
|
|
95
|
-
const lane = xaiResponsesPromptCacheLane(opts,
|
|
101
|
+
const lane = xaiResponsesPromptCacheLane(opts, { prefixHash, ownerSessionHash: sessionId ? traceHash(sessionId) : null });
|
|
96
102
|
const laneEnabled = lane?.enabled === true;
|
|
97
103
|
const laneShards = Number.isFinite(Number(lane?.shards)) && Number(lane.shards) > 0 ? Number(lane.shards) : 0;
|
|
98
104
|
const explicitSlot = Number(opts?.promptCacheLaneSlot ?? opts?.xaiCacheLaneSlot);
|
|
@@ -128,6 +134,19 @@ export function normalizeXaiReasoningEffort(value) {
|
|
|
128
134
|
return ['low', 'medium', 'high', 'xhigh'].includes(effort) ? effort : null;
|
|
129
135
|
}
|
|
130
136
|
|
|
137
|
+
// grok-3, grok-4 and grok-4-fast REJECT reasoning_effort outright (HTTP 400
|
|
138
|
+
// "does not support parameter reasoningEffort"), so the parameter ships only
|
|
139
|
+
// for the families that document it. An unknown/absent model id keeps the
|
|
140
|
+
// parameter — a custom xAI-compatible deployment that never saw the 400 must
|
|
141
|
+
// not silently lose the caller's effort choice.
|
|
142
|
+
export function xaiModelSupportsReasoningEffort(model) {
|
|
143
|
+
const id = String(model || '').trim().toLowerCase();
|
|
144
|
+
if (!id) return true;
|
|
145
|
+
if (!id.startsWith('grok')) return true;
|
|
146
|
+
// grok-4.5 / grok-4.6 and anything newer in that line.
|
|
147
|
+
return /grok[-_]?4\.(?:[5-9]|\d{2,})/.test(id);
|
|
148
|
+
}
|
|
149
|
+
|
|
131
150
|
function opencodeGoReasoningEffortValues(modelInfo) {
|
|
132
151
|
const effort = (modelInfo?.reasoningOptions || []).find((option) => option?.type === 'effort');
|
|
133
152
|
return Array.isArray(effort?.values)
|
|
@@ -170,12 +189,6 @@ export function useXaiResponsesWebSocket(opts, config) {
|
|
|
170
189
|
return !['0', 'false', 'off', 'http', 'https', 'responses-http', 'sdk'].includes(transport);
|
|
171
190
|
}
|
|
172
191
|
|
|
173
|
-
export function _envFlag(name, fallback = true) {
|
|
174
|
-
const raw = process.env[name];
|
|
175
|
-
if (raw == null || raw === '') return fallback;
|
|
176
|
-
return !['0', 'false', 'off', 'no'].includes(String(raw).toLowerCase());
|
|
177
|
-
}
|
|
178
|
-
|
|
179
192
|
// xAI WS→HTTP transport fallback → shared shouldFallbackTransport
|
|
180
193
|
// (retry-classifier.mjs). Identical deny-order + allow-list; the per-provider
|
|
181
194
|
// env flag is computed here and passed via `enabled`.
|
|
@@ -186,7 +199,7 @@ export function _shouldFallbackXaiWsToHttp(err, signal) {
|
|
|
186
199
|
});
|
|
187
200
|
}
|
|
188
201
|
|
|
189
|
-
export function useXaiResponsesWebSocketWarmup(opts, config, { previousResponseId
|
|
202
|
+
export function useXaiResponsesWebSocketWarmup(opts, config, { previousResponseId }) {
|
|
190
203
|
if (previousResponseId) return false;
|
|
191
204
|
const raw = opts?.xaiResponsesWarmup
|
|
192
205
|
?? opts?.xaiWsWarmup
|
|
@@ -204,97 +217,36 @@ export function useXaiResponsesWebSocketWarmup(opts, config, { previousResponseI
|
|
|
204
217
|
return false;
|
|
205
218
|
}
|
|
206
219
|
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return parseXaiPositiveInt(
|
|
223
|
-
opts?.xaiCacheMaxInFlight
|
|
224
|
-
?? opts?.xaiResponsesCacheMaxInFlight
|
|
225
|
-
?? opts?.grokCacheMaxInFlight
|
|
226
|
-
?? opts?.grokResponsesCacheMaxInFlight
|
|
227
|
-
?? config?.xaiCacheMaxInFlight
|
|
228
|
-
?? config?.xaiResponsesCacheMaxInFlight
|
|
229
|
-
?? config?.grokCacheMaxInFlight
|
|
230
|
-
?? config?.grokResponsesCacheMaxInFlight
|
|
231
|
-
?? process.env.MIXDOG_XAI_CACHE_MAX_INFLIGHT
|
|
232
|
-
?? process.env.MIXDOG_XAI_RESPONSES_CACHE_MAX_INFLIGHT
|
|
233
|
-
?? process.env.MIXDOG_GROK_CACHE_MAX_INFLIGHT
|
|
234
|
-
?? process.env.MIXDOG_GROK_RESPONSES_CACHE_MAX_INFLIGHT
|
|
235
|
-
?? process.env.MIXDOG_GROK_OAUTH_CACHE_MAX_INFLIGHT
|
|
236
|
-
?? process.env.MIXDOG_GROK_OAUTH_RESPONSES_CACHE_MAX_INFLIGHT,
|
|
237
|
-
XAI_RESPONSES_CACHE_LANE_DEFAULT_MAX_IN_FLIGHT,
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function xaiResponsesCacheLaneQueueTimeoutMs(opts, config) {
|
|
242
|
-
return parseXaiPositiveInt(
|
|
243
|
-
opts?.xaiCacheQueueTimeoutMs
|
|
244
|
-
?? opts?.xaiResponsesCacheQueueTimeoutMs
|
|
245
|
-
?? opts?.grokCacheQueueTimeoutMs
|
|
246
|
-
?? opts?.grokResponsesCacheQueueTimeoutMs
|
|
247
|
-
?? config?.xaiCacheQueueTimeoutMs
|
|
248
|
-
?? config?.xaiResponsesCacheQueueTimeoutMs
|
|
249
|
-
?? config?.grokCacheQueueTimeoutMs
|
|
250
|
-
?? config?.grokResponsesCacheQueueTimeoutMs
|
|
251
|
-
?? process.env.MIXDOG_XAI_CACHE_QUEUE_TIMEOUT_MS
|
|
252
|
-
?? process.env.MIXDOG_XAI_RESPONSES_CACHE_QUEUE_TIMEOUT_MS
|
|
253
|
-
?? process.env.MIXDOG_GROK_CACHE_QUEUE_TIMEOUT_MS
|
|
254
|
-
?? process.env.MIXDOG_GROK_RESPONSES_CACHE_QUEUE_TIMEOUT_MS
|
|
255
|
-
?? process.env.MIXDOG_GROK_OAUTH_CACHE_QUEUE_TIMEOUT_MS
|
|
256
|
-
?? process.env.MIXDOG_GROK_OAUTH_RESPONSES_CACHE_QUEUE_TIMEOUT_MS,
|
|
257
|
-
0,
|
|
258
|
-
);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
function xaiResponsesPromptCacheLane(opts, config, cacheRouting) {
|
|
220
|
+
// No `config` argument: the single caller (xaiResponsesCacheRouting) never had
|
|
221
|
+
// one to pass, so the provider-config lane aliases this used to read were dead
|
|
222
|
+
// operands. Lane selection on this route is opts + env only.
|
|
223
|
+
function xaiResponsesPromptCacheLane(opts, cacheRouting) {
|
|
224
|
+
// Lane SHARDS only, for xAI/Grok. The `*CacheMaxParallel` /
|
|
225
|
+
// *_CACHE_MAX_PARALLEL knobs that used to bound the lane's in-flight
|
|
226
|
+
// admission were removed with the lane queue itself (admission is the
|
|
227
|
+
// shared provider scheduler's job now). They are deliberately NOT accepted
|
|
228
|
+
// here as shard aliases — on this route they never selected shards, and a
|
|
229
|
+
// setting named "max parallel" silently deciding prompt-cache key fan-out
|
|
230
|
+
// is a different control with different consequences. An xAI operator who
|
|
231
|
+
// set one gets the documented default until they opt into
|
|
232
|
+
// `*CacheLaneShards` / MIXDOG_XAI_CACHE_LANE_SHARDS explicitly.
|
|
233
|
+
// promptCacheLaneIgnoreAliases scopes that refusal to this route only:
|
|
234
|
+
// OpenAI direct/OAuth keep honouring the aliases (cache-strategy.mjs).
|
|
262
235
|
const shardOverride =
|
|
263
236
|
opts?.xaiCacheLaneShards
|
|
264
237
|
?? opts?.xaiResponsesCacheLaneShards
|
|
265
|
-
?? opts?.xaiCacheMaxParallel
|
|
266
|
-
?? opts?.xaiResponsesCacheMaxParallel
|
|
267
238
|
?? opts?.grokCacheLaneShards
|
|
268
239
|
?? opts?.grokResponsesCacheLaneShards
|
|
269
|
-
?? opts?.grokCacheMaxParallel
|
|
270
|
-
?? opts?.grokResponsesCacheMaxParallel
|
|
271
|
-
?? config?.xaiCacheLaneShards
|
|
272
|
-
?? config?.xaiResponsesCacheLaneShards
|
|
273
|
-
?? config?.xaiCacheMaxParallel
|
|
274
|
-
?? config?.xaiResponsesCacheMaxParallel
|
|
275
|
-
?? config?.grokCacheLaneShards
|
|
276
|
-
?? config?.grokResponsesCacheLaneShards
|
|
277
|
-
?? config?.grokCacheMaxParallel
|
|
278
|
-
?? config?.grokResponsesCacheMaxParallel
|
|
279
|
-
?? process.env.MIXDOG_XAI_RESPONSES_CACHE_MAX_PARALLEL
|
|
280
240
|
?? process.env.MIXDOG_XAI_RESPONSES_CACHE_LANE_SHARDS
|
|
281
|
-
?? process.env.MIXDOG_GROK_CACHE_MAX_PARALLEL
|
|
282
241
|
?? process.env.MIXDOG_GROK_CACHE_LANE_SHARDS
|
|
283
|
-
?? process.env.MIXDOG_GROK_RESPONSES_CACHE_MAX_PARALLEL
|
|
284
242
|
?? process.env.MIXDOG_GROK_RESPONSES_CACHE_LANE_SHARDS
|
|
285
|
-
?? process.env.MIXDOG_GROK_OAUTH_CACHE_MAX_PARALLEL
|
|
286
243
|
?? process.env.MIXDOG_GROK_OAUTH_CACHE_LANE_SHARDS
|
|
287
|
-
?? process.env.MIXDOG_GROK_OAUTH_RESPONSES_CACHE_MAX_PARALLEL
|
|
288
244
|
?? process.env.MIXDOG_GROK_OAUTH_RESPONSES_CACHE_LANE_SHARDS;
|
|
289
245
|
const autoOverride =
|
|
290
246
|
opts?.xaiCacheLaneAuto
|
|
291
247
|
?? opts?.xaiResponsesCacheLaneAuto
|
|
292
248
|
?? opts?.grokCacheLaneAuto
|
|
293
249
|
?? opts?.grokResponsesCacheLaneAuto
|
|
294
|
-
?? config?.xaiCacheLaneAuto
|
|
295
|
-
?? config?.xaiResponsesCacheLaneAuto
|
|
296
|
-
?? config?.grokCacheLaneAuto
|
|
297
|
-
?? config?.grokResponsesCacheLaneAuto
|
|
298
250
|
?? process.env.MIXDOG_XAI_RESPONSES_CACHE_LANE_AUTO
|
|
299
251
|
?? process.env.MIXDOG_GROK_CACHE_LANE_AUTO
|
|
300
252
|
?? process.env.MIXDOG_GROK_RESPONSES_CACHE_LANE_AUTO
|
|
@@ -319,137 +271,22 @@ function xaiResponsesPromptCacheLane(opts, config, cacheRouting) {
|
|
|
319
271
|
);
|
|
320
272
|
return resolveProviderPromptCacheLane('xai', {
|
|
321
273
|
...opts,
|
|
274
|
+
promptCacheLaneIgnoreAliases: true,
|
|
322
275
|
...(shardOverride !== undefined ? { promptCacheLaneShards: shardOverride } : {}),
|
|
323
276
|
...(autoOverride !== undefined ? { promptCacheLaneAuto: autoOverride } : {}),
|
|
324
277
|
...(slotOverride !== undefined ? { promptCacheLaneSlot: slotOverride } : {}),
|
|
325
278
|
promptCacheLaneSeed: seed || 'xai-cache-lane',
|
|
326
|
-
},
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
function xaiResponsesCacheLaneKey({ model, cacheRouting, opts, config }) {
|
|
330
|
-
const prefix = cacheRouting?.prefixHash || cacheRouting?.seedHash || cacheRouting?.key || 'unknown-prefix';
|
|
331
|
-
const lane = xaiResponsesPromptCacheLane(opts, config, cacheRouting);
|
|
332
|
-
const shard = Number.isFinite(Number(lane?.slot)) ? Number(lane.slot) : 0;
|
|
333
|
-
return {
|
|
334
|
-
key: `xai-responses:${model || 'default'}:${prefix}:shard-${shard}`,
|
|
335
|
-
shard,
|
|
336
|
-
lane,
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
function getXaiResponsesCacheLaneState(key, maxInFlight) {
|
|
341
|
-
let state = xaiResponsesCacheLanes.get(key);
|
|
342
|
-
if (!state) {
|
|
343
|
-
state = { key, active: 0, queue: [], maxInFlight, nextId: 0 };
|
|
344
|
-
xaiResponsesCacheLanes.set(key, state);
|
|
345
|
-
}
|
|
346
|
-
state.maxInFlight = maxInFlight;
|
|
347
|
-
return state;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
function cleanupXaiResponsesCacheLane(state) {
|
|
351
|
-
if (state.active === 0 && state.queue.length === 0) {
|
|
352
|
-
xaiResponsesCacheLanes.delete(state.key);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
function removeQueuedXaiCacheLaneRequest(state, request) {
|
|
357
|
-
const index = state.queue.indexOf(request);
|
|
358
|
-
if (index >= 0) state.queue.splice(index, 1);
|
|
359
|
-
cleanupXaiResponsesCacheLane(state);
|
|
279
|
+
}, null);
|
|
360
280
|
}
|
|
361
281
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
if (released) return;
|
|
371
|
-
released = true;
|
|
372
|
-
releaseXaiResponsesCacheLane(state);
|
|
373
|
-
},
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function releaseXaiResponsesCacheLane(state) {
|
|
378
|
-
state.active = Math.max(0, state.active - 1);
|
|
379
|
-
while (state.queue.length > 0 && state.active < state.maxInFlight) {
|
|
380
|
-
const next = state.queue.shift();
|
|
381
|
-
next.cleanup?.();
|
|
382
|
-
state.active += 1;
|
|
383
|
-
next.resolve(makeXaiCacheLaneHandle(state, next.requestId, next.enqueuedAt));
|
|
384
|
-
}
|
|
385
|
-
cleanupXaiResponsesCacheLane(state);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function acquireXaiResponsesCacheLane({ key, maxInFlight, signal, timeoutMs }) {
|
|
389
|
-
const state = getXaiResponsesCacheLaneState(key, maxInFlight);
|
|
390
|
-
const requestId = ++state.nextId;
|
|
391
|
-
const enqueuedAt = Date.now();
|
|
392
|
-
if (state.active < state.maxInFlight) {
|
|
393
|
-
state.active += 1;
|
|
394
|
-
return Promise.resolve(makeXaiCacheLaneHandle(state, requestId, enqueuedAt));
|
|
395
|
-
}
|
|
396
|
-
return new Promise((resolve, reject) => {
|
|
397
|
-
const request = {
|
|
398
|
-
requestId,
|
|
399
|
-
enqueuedAt,
|
|
400
|
-
resolve,
|
|
401
|
-
reject,
|
|
402
|
-
cleanup: null,
|
|
403
|
-
};
|
|
404
|
-
const cleanup = () => {
|
|
405
|
-
if (request.timer) clearTimeout(request.timer);
|
|
406
|
-
if (signal && request.abortListener) signal.removeEventListener('abort', request.abortListener);
|
|
407
|
-
};
|
|
408
|
-
request.cleanup = cleanup;
|
|
409
|
-
request.abortListener = () => {
|
|
410
|
-
cleanup();
|
|
411
|
-
removeQueuedXaiCacheLaneRequest(state, request);
|
|
412
|
-
const reason = signal?.reason;
|
|
413
|
-
reject(reason instanceof Error ? reason : new Error('xAI cache lane wait aborted'));
|
|
414
|
-
};
|
|
415
|
-
if (signal?.aborted) {
|
|
416
|
-
request.abortListener();
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
if (signal) signal.addEventListener('abort', request.abortListener, { once: true });
|
|
420
|
-
if (timeoutMs > 0) {
|
|
421
|
-
request.timer = setTimeout(() => {
|
|
422
|
-
cleanup();
|
|
423
|
-
removeQueuedXaiCacheLaneRequest(state, request);
|
|
424
|
-
reject(new Error(`xAI cache lane wait timed out after ${timeoutMs}ms`));
|
|
425
|
-
}, timeoutMs);
|
|
426
|
-
request.timer.unref?.();
|
|
427
|
-
}
|
|
428
|
-
state.queue.push(request);
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
function traceXaiCacheLane(opts, payload) {
|
|
433
|
-
if (!compatCacheTraceEnabled('xai')) return;
|
|
434
|
-
try {
|
|
435
|
-
appendAgentTrace({
|
|
436
|
-
sessionId: opts?.sessionId || opts?.session?.id || null,
|
|
437
|
-
iteration: Number.isFinite(Number(opts?.iteration)) ? Number(opts.iteration) : null,
|
|
438
|
-
kind: 'cache_lane',
|
|
439
|
-
...payload,
|
|
440
|
-
payload,
|
|
441
|
-
});
|
|
442
|
-
} catch {}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
export async function withXaiResponsesCacheLane({ opts, config, cacheRouting, model, transport, previousResponseId, inputCount, signal }, fn) {
|
|
446
|
-
// Historical prompt-cache lanes formed a second admission queue and could
|
|
447
|
-
// time out while waiting. xAI is now governed exclusively by the common
|
|
448
|
-
// fixed-64 provider/account scheduler, regardless of legacy env/option
|
|
449
|
-
// knobs. Keep this wrapper only as a call-shape compatibility boundary.
|
|
450
|
-
const laneMeta = { enabled: false, maxInFlight: 0 };
|
|
451
|
-
return { value: await fn(laneMeta), laneMeta };
|
|
452
|
-
}
|
|
282
|
+
// Historical prompt-cache lanes formed a second admission queue and could time
|
|
283
|
+
// out while waiting. xAI is now governed exclusively by the common fixed-64
|
|
284
|
+
// provider/account scheduler, so no lane is ever taken: the queue/handle
|
|
285
|
+
// machinery and its max-in-flight / queue-timeout knobs were dead code and have
|
|
286
|
+
// been removed rather than left as settings that silently do nothing. The
|
|
287
|
+
// cache-trace payload still reports the lane shape, so this frozen "no lane"
|
|
288
|
+
// record is what the xAI Responses trace writers receive.
|
|
289
|
+
export const XAI_CACHE_LANE_META = Object.freeze({ enabled: false, maxInFlight: 0 });
|
|
453
290
|
|
|
454
291
|
function deterministicUuidFromKey(key) {
|
|
455
292
|
const hex = createHash('sha256').update(String(key ?? '')).digest('hex');
|