@copilotkit/aimock 1.29.0 → 1.31.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +34 -0
- package/README.md +1 -1
- package/dist/agui-types.d.ts.map +1 -1
- package/dist/bedrock-converse.cjs +63 -31
- package/dist/bedrock-converse.cjs.map +1 -1
- package/dist/bedrock-converse.d.cts.map +1 -1
- package/dist/bedrock-converse.d.ts.map +1 -1
- package/dist/bedrock-converse.js +65 -33
- package/dist/bedrock-converse.js.map +1 -1
- package/dist/bedrock.cjs +95 -33
- package/dist/bedrock.cjs.map +1 -1
- package/dist/bedrock.d.cts.map +1 -1
- package/dist/bedrock.d.ts.map +1 -1
- package/dist/bedrock.js +97 -35
- package/dist/bedrock.js.map +1 -1
- package/dist/cli.cjs +18 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +18 -1
- package/dist/cli.js.map +1 -1
- package/dist/cohere.cjs +49 -15
- package/dist/cohere.cjs.map +1 -1
- package/dist/cohere.d.cts.map +1 -1
- package/dist/cohere.d.ts.map +1 -1
- package/dist/cohere.js +51 -17
- package/dist/cohere.js.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/elevenlabs-audio.cjs +8 -4
- package/dist/elevenlabs-audio.cjs.map +1 -1
- package/dist/elevenlabs-audio.d.cts.map +1 -1
- package/dist/elevenlabs-audio.d.ts.map +1 -1
- package/dist/elevenlabs-audio.js +10 -6
- package/dist/elevenlabs-audio.js.map +1 -1
- package/dist/embeddings.cjs +4 -3
- package/dist/embeddings.cjs.map +1 -1
- package/dist/embeddings.d.cts.map +1 -1
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/embeddings.js +6 -5
- package/dist/embeddings.js.map +1 -1
- package/dist/fal-audio.cjs +18 -8
- package/dist/fal-audio.cjs.map +1 -1
- package/dist/fal-audio.d.cts.map +1 -1
- package/dist/fal-audio.d.ts.map +1 -1
- package/dist/fal-audio.js +22 -12
- package/dist/fal-audio.js.map +1 -1
- package/dist/fal.cjs +55 -46
- package/dist/fal.cjs.map +1 -1
- package/dist/fal.d.cts +8 -0
- package/dist/fal.d.cts.map +1 -1
- package/dist/fal.d.ts +8 -0
- package/dist/fal.d.ts.map +1 -1
- package/dist/fal.js +58 -49
- package/dist/fal.js.map +1 -1
- package/dist/gemini-embeddings.cjs +4 -3
- package/dist/gemini-embeddings.cjs.map +1 -1
- package/dist/gemini-embeddings.js +6 -5
- package/dist/gemini-embeddings.js.map +1 -1
- package/dist/gemini-interactions.cjs +3 -3
- package/dist/gemini-interactions.cjs.map +1 -1
- package/dist/gemini-interactions.d.cts.map +1 -1
- package/dist/gemini-interactions.d.ts.map +1 -1
- package/dist/gemini-interactions.js +5 -5
- package/dist/gemini-interactions.js.map +1 -1
- package/dist/gemini.cjs +55 -24
- package/dist/gemini.cjs.map +1 -1
- package/dist/gemini.d.cts.map +1 -1
- package/dist/gemini.d.ts.map +1 -1
- package/dist/gemini.js +57 -26
- package/dist/gemini.js.map +1 -1
- package/dist/helpers.cjs +120 -2
- package/dist/helpers.cjs.map +1 -1
- package/dist/helpers.d.cts +43 -3
- package/dist/helpers.d.cts.map +1 -1
- package/dist/helpers.d.ts +43 -3
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +117 -3
- package/dist/helpers.js.map +1 -1
- package/dist/images.cjs +12 -6
- package/dist/images.cjs.map +1 -1
- package/dist/images.d.cts.map +1 -1
- package/dist/images.d.ts.map +1 -1
- package/dist/images.js +14 -8
- package/dist/images.js.map +1 -1
- package/dist/index.cjs +13 -2
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +6 -5
- package/dist/llmock.cjs +2 -1
- package/dist/llmock.cjs.map +1 -1
- package/dist/llmock.d.cts.map +1 -1
- package/dist/llmock.d.ts.map +1 -1
- package/dist/llmock.js +2 -1
- package/dist/llmock.js.map +1 -1
- package/dist/messages.cjs +325 -85
- package/dist/messages.cjs.map +1 -1
- package/dist/messages.d.cts.map +1 -1
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +327 -87
- package/dist/messages.js.map +1 -1
- package/dist/metrics.cjs +9 -0
- package/dist/metrics.cjs.map +1 -1
- package/dist/metrics.d.cts.map +1 -1
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +7 -1
- package/dist/metrics.js.map +1 -1
- package/dist/model-utils.cjs +68 -0
- package/dist/model-utils.cjs.map +1 -1
- package/dist/model-utils.js +68 -1
- package/dist/model-utils.js.map +1 -1
- package/dist/ollama.cjs +58 -21
- package/dist/ollama.cjs.map +1 -1
- package/dist/ollama.d.cts.map +1 -1
- package/dist/ollama.d.ts.map +1 -1
- package/dist/ollama.js +60 -23
- package/dist/ollama.js.map +1 -1
- package/dist/openrouter-video.cjs +1609 -0
- package/dist/openrouter-video.cjs.map +1 -0
- package/dist/openrouter-video.d.cts +154 -0
- package/dist/openrouter-video.d.cts.map +1 -0
- package/dist/openrouter-video.d.ts +154 -0
- package/dist/openrouter-video.d.ts.map +1 -0
- package/dist/openrouter-video.js +1601 -0
- package/dist/openrouter-video.js.map +1 -0
- package/dist/recorder.cjs +97 -15
- package/dist/recorder.cjs.map +1 -1
- package/dist/recorder.d.cts.map +1 -1
- package/dist/recorder.d.ts.map +1 -1
- package/dist/recorder.js +96 -17
- package/dist/recorder.js.map +1 -1
- package/dist/responses.cjs +26 -12
- package/dist/responses.cjs.map +1 -1
- package/dist/responses.d.cts +1 -1
- package/dist/responses.d.cts.map +1 -1
- package/dist/responses.d.ts +1 -1
- package/dist/responses.d.ts.map +1 -1
- package/dist/responses.js +28 -14
- package/dist/responses.js.map +1 -1
- package/dist/router.cjs +37 -8
- package/dist/router.cjs.map +1 -1
- package/dist/router.d.cts +30 -1
- package/dist/router.d.cts.map +1 -1
- package/dist/router.d.ts +30 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +37 -9
- package/dist/router.js.map +1 -1
- package/dist/server.cjs +173 -19
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -0
- package/dist/server.d.cts.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +176 -22
- package/dist/server.js.map +1 -1
- package/dist/speech.cjs +4 -2
- package/dist/speech.cjs.map +1 -1
- package/dist/speech.d.cts.map +1 -1
- package/dist/speech.d.ts.map +1 -1
- package/dist/speech.js +6 -4
- package/dist/speech.js.map +1 -1
- package/dist/stream-collapse.cjs +44 -1
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.d.cts +28 -0
- package/dist/stream-collapse.d.cts.map +1 -1
- package/dist/stream-collapse.d.ts +28 -0
- package/dist/stream-collapse.d.ts.map +1 -1
- package/dist/stream-collapse.js +44 -2
- package/dist/stream-collapse.js.map +1 -1
- package/dist/transcription.cjs +4 -2
- package/dist/transcription.cjs.map +1 -1
- package/dist/transcription.d.cts.map +1 -1
- package/dist/transcription.d.ts.map +1 -1
- package/dist/transcription.js +6 -4
- package/dist/transcription.js.map +1 -1
- package/dist/types.d.cts +123 -8
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +123 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-types.d.cts.map +1 -1
- package/dist/vector-types.d.ts.map +1 -1
- package/dist/video.cjs +4 -2
- package/dist/video.cjs.map +1 -1
- package/dist/video.d.cts.map +1 -1
- package/dist/video.d.ts.map +1 -1
- package/dist/video.js +6 -4
- package/dist/video.js.map +1 -1
- package/dist/ws-gemini-live.cjs +4 -3
- package/dist/ws-gemini-live.cjs.map +1 -1
- package/dist/ws-gemini-live.d.cts +2 -2
- package/dist/ws-gemini-live.d.cts.map +1 -1
- package/dist/ws-gemini-live.d.ts.map +1 -1
- package/dist/ws-gemini-live.js +6 -5
- package/dist/ws-gemini-live.js.map +1 -1
- package/dist/ws-realtime.cjs +4 -3
- package/dist/ws-realtime.cjs.map +1 -1
- package/dist/ws-realtime.d.cts +2 -2
- package/dist/ws-realtime.d.cts.map +1 -1
- package/dist/ws-realtime.d.ts.map +1 -1
- package/dist/ws-realtime.js +6 -5
- package/dist/ws-realtime.js.map +1 -1
- package/dist/ws-responses.cjs +8 -6
- package/dist/ws-responses.cjs.map +1 -1
- package/dist/ws-responses.d.cts.map +1 -1
- package/dist/ws-responses.d.ts.map +1 -1
- package/dist/ws-responses.js +10 -8
- package/dist/ws-responses.js.map +1 -1
- package/package.json +2 -2
package/dist/server.d.cts
CHANGED
|
@@ -4,6 +4,7 @@ import { SearchFixture } from "./search.cjs";
|
|
|
4
4
|
import { RerankFixture } from "./rerank.cjs";
|
|
5
5
|
import { ModerationFixture } from "./moderation.cjs";
|
|
6
6
|
import { VideoStateMap } from "./video.cjs";
|
|
7
|
+
import { OpenRouterVideoJobMap } from "./openrouter-video.cjs";
|
|
7
8
|
import * as http$1 from "node:http";
|
|
8
9
|
|
|
9
10
|
//#region src/server.d.ts
|
|
@@ -13,6 +14,7 @@ interface ServerInstance {
|
|
|
13
14
|
url: string;
|
|
14
15
|
defaults: HandlerDefaults;
|
|
15
16
|
videoStates: VideoStateMap;
|
|
17
|
+
openRouterVideoJobs: OpenRouterVideoJobMap;
|
|
16
18
|
}
|
|
17
19
|
interface ServiceFixtures {
|
|
18
20
|
search: SearchFixture[];
|
package/dist/server.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.cts","names":[],"sources":["../src/server.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.cts","names":[],"sources":["../src/server.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;UA0FiB,cAAA;UACP,MAAA,CAAK;EADE,OAAA,EAEN,OAFM;EAAc,GAAA,EAAA,MAAA;UACrB,EAGE,eAHG;aACJ,EAGI,aAHJ;qBAEC,EAEW,qBAFX;;AAEW,UAw8BN,eAAA,CAx8BM;EAAqB,MAAA,EAy8BlC,aAz8BkC,EAAA;EAw8B3B,MAAA,EAEP,aAFsB,EAAA;EAAA,UAAA,EAGlB,iBAHkB,EAAA;;AAEtB,iBAOY,YAAA,CAPZ,QAAA,EAQE,OARF,EAAA,EAAA,OAAA,CAAA,EASE,iBATF,EAAA,MAOV,CAPU,EAUC,KAVD,CAAA;MACI,EAAA,MAAA;EAAiB,OAAA,EASW,SATX;AAM/B,CAAA,CAAA,EAAsB,eAAY,CAAA,EAId,eAJc,CAAA,EAK/B,OAL+B,CAKvB,cALuB,CAAA"}
|
package/dist/server.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { SearchFixture } from "./search.js";
|
|
|
4
4
|
import { RerankFixture } from "./rerank.js";
|
|
5
5
|
import { ModerationFixture } from "./moderation.js";
|
|
6
6
|
import { VideoStateMap } from "./video.js";
|
|
7
|
+
import { OpenRouterVideoJobMap } from "./openrouter-video.js";
|
|
7
8
|
import * as http$1 from "node:http";
|
|
8
9
|
|
|
9
10
|
//#region src/server.d.ts
|
|
@@ -13,6 +14,7 @@ interface ServerInstance {
|
|
|
13
14
|
url: string;
|
|
14
15
|
defaults: HandlerDefaults;
|
|
15
16
|
videoStates: VideoStateMap;
|
|
17
|
+
openRouterVideoJobs: OpenRouterVideoJobMap;
|
|
16
18
|
}
|
|
17
19
|
interface ServiceFixtures {
|
|
18
20
|
search: SearchFixture[];
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","names":[],"sources":["../src/server.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","names":[],"sources":["../src/server.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;UA0FiB,cAAA;UACP,MAAA,CAAK;EADE,OAAA,EAEN,OAFM;EAAc,GAAA,EAAA,MAAA;UACrB,EAGE,eAHG;aACJ,EAGI,aAHJ;qBAEC,EAEW,qBAFX;;AAEW,UAw8BN,eAAA,CAx8BM;EAAqB,MAAA,EAy8BlC,aAz8BkC,EAAA;EAw8B3B,MAAA,EAEP,aAFsB,EAAA;EAAA,UAAA,EAGlB,iBAHkB,EAAA;;AAEtB,iBAOY,YAAA,CAPZ,QAAA,EAQE,OARF,EAAA,EAAA,OAAA,CAAA,EASE,iBATF,EAAA,MAOV,CAPU,EAUC,KAVD,CAAA;MACI,EAAA,MAAA;EAAiB,OAAA,EASW,SATX;AAM/B,CAAA,CAAA,EAAsB,eAAY,CAAA,EAId,eAJc,CAAA,EAK/B,OAL+B,CAKvB,cALuB,CAAA"}
|
package/dist/server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildTextChunks, buildTextCompletion, buildToolCallChunks, buildToolCallCompletion, buildUsageChunk, estimatePromptTokens, estimateTokens, extractOverrides, flattenHeaders, getContext, getTestId, isAudioResponse, isContentWithToolCallsResponse, isErrorResponse, isTextResponse, isToolCallResponse, readBody, resolveResponse, resolveStrictMode, serializeErrorResponse, strictOverrideField } from "./helpers.js";
|
|
1
|
+
import { buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildTextChunks, buildTextCompletion, buildToolCallChunks, buildToolCallCompletion, buildUsageChunk, estimatePromptTokens, estimateTokens, extractOverrides, flattenHeaders, getContext, getTestId, isAudioResponse, isContentWithToolCallsResponse, isErrorResponse, isTextResponse, isToolCallResponse, readBody, resolveReasoningForModel, resolveResponse, resolveStrictMode, serializeErrorResponse, strictNoMatchLogLine, strictNoMatchMessage, strictOverrideField } from "./helpers.js";
|
|
2
2
|
import { Logger } from "./logger.js";
|
|
3
3
|
import { Journal } from "./journal.js";
|
|
4
|
-
import {
|
|
4
|
+
import { matchFixtureDiagnostic } from "./router.js";
|
|
5
5
|
import { entryToFixture, validateFixtures } from "./fixture-loader.js";
|
|
6
6
|
import { writeErrorResponse, writeSSEStream } from "./sse-writer.js";
|
|
7
7
|
import { createInterruptionSignal } from "./interruption.js";
|
|
@@ -19,9 +19,10 @@ import { handleTranscription } from "./transcription.js";
|
|
|
19
19
|
import { handleImageEdit, handleImageVariations, handleImages } from "./images.js";
|
|
20
20
|
import { handleSpeech } from "./speech.js";
|
|
21
21
|
import { VideoStateMap, handleVideoCreate, handleVideoStatus } from "./video.js";
|
|
22
|
-
import { handleElevenLabsAudio, handleElevenLabsTTS } from "./elevenlabs-audio.js";
|
|
23
|
-
import { falQueueStates, handleFal } from "./fal.js";
|
|
24
22
|
import { falJobs, handleFalQueue } from "./fal-audio.js";
|
|
23
|
+
import { falQueueStates, handleFal } from "./fal.js";
|
|
24
|
+
import { OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OpenRouterVideoJobMap, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus } from "./openrouter-video.js";
|
|
25
|
+
import { handleElevenLabsAudio, handleElevenLabsTTS } from "./elevenlabs-audio.js";
|
|
25
26
|
import { handleOllama, handleOllamaEmbeddings, handleOllamaGenerate } from "./ollama.js";
|
|
26
27
|
import { handleCohere, handleCohereEmbed } from "./cohere.js";
|
|
27
28
|
import { handleSearch } from "./search.js";
|
|
@@ -31,7 +32,7 @@ import { upgradeToWebSocket } from "./ws-framing.js";
|
|
|
31
32
|
import { handleWebSocketResponses } from "./ws-responses.js";
|
|
32
33
|
import { handleWebSocketRealtime } from "./ws-realtime.js";
|
|
33
34
|
import { handleWebSocketGeminiLive } from "./ws-gemini-live.js";
|
|
34
|
-
import { createMetricsRegistry, normalizePathLabel } from "./metrics.js";
|
|
35
|
+
import { OPENAI_VIDEO_STATUS_RE, OPENROUTER_VIDEO_CONTENT_RE, OPENROUTER_VIDEO_STATUS_RE, createMetricsRegistry, normalizePathLabel } from "./metrics.js";
|
|
35
36
|
import * as http$1 from "node:http";
|
|
36
37
|
|
|
37
38
|
//#region src/server.ts
|
|
@@ -53,7 +54,6 @@ const SPEECH_PATH = "/v1/audio/speech";
|
|
|
53
54
|
const TRANSCRIPTIONS_PATH = "/v1/audio/transcriptions";
|
|
54
55
|
const TRANSLATIONS_PATH = "/v1/audio/translations";
|
|
55
56
|
const VIDEOS_PATH = "/v1/videos";
|
|
56
|
-
const VIDEOS_STATUS_RE = /^\/v1\/videos\/([^/]+)$/;
|
|
57
57
|
const GEMINI_PREDICT_RE = /^\/v1beta\/models\/([^:]+):predict$/;
|
|
58
58
|
const ELEVENLABS_SOUND_GENERATION_PATH = "/v1/sound-generation";
|
|
59
59
|
const ELEVENLABS_TTS_RE = /^\/v1\/text-to-speech\/([^/]+)$/;
|
|
@@ -104,6 +104,8 @@ const OLLAMA_GENERATE_PATH = "/api/generate";
|
|
|
104
104
|
const OLLAMA_EMBEDDINGS_PATH = "/api/embeddings";
|
|
105
105
|
const OLLAMA_EMBED_PATH = "/api/embed";
|
|
106
106
|
const OLLAMA_TAGS_PATH = "/api/tags";
|
|
107
|
+
const OPENROUTER_VIDEOS_PATH = "/api/v1/videos";
|
|
108
|
+
const OPENROUTER_VIDEO_MODELS_PATH = "/api/v1/videos/models";
|
|
107
109
|
const HEALTH_PATH = "/health";
|
|
108
110
|
const READY_PATH = "/ready";
|
|
109
111
|
const MODELS_PATH = "/v1/models";
|
|
@@ -142,10 +144,11 @@ const CONTROL_PREFIX = "/__aimock";
|
|
|
142
144
|
* `aimock_fixtures_loaded` gauge. Shared by `/reset/fixtures` and the
|
|
143
145
|
* deprecated `/reset` alias.
|
|
144
146
|
*/
|
|
145
|
-
function performFixturesReset(fixtures, journal, videoStates, defaults) {
|
|
147
|
+
function performFixturesReset(fixtures, journal, videoStates, openRouterVideoJobs, defaults) {
|
|
146
148
|
fixtures.length = 0;
|
|
147
149
|
journal.clear();
|
|
148
150
|
videoStates.clear();
|
|
151
|
+
openRouterVideoJobs.clear();
|
|
149
152
|
falJobs.clear();
|
|
150
153
|
falQueueStates.clear();
|
|
151
154
|
resetInteractionCounter();
|
|
@@ -156,7 +159,7 @@ function performFixturesReset(fixtures, journal, videoStates, defaults) {
|
|
|
156
159
|
* Handle requests under `/__aimock/`. Returns `true` if the request was
|
|
157
160
|
* handled, `false` if the path doesn't match the control prefix.
|
|
158
161
|
*/
|
|
159
|
-
async function handleControlAPI(req, res, pathname, fixtures, journal, videoStates, defaults) {
|
|
162
|
+
async function handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, defaults) {
|
|
160
163
|
if (!pathname.startsWith(CONTROL_PREFIX)) return false;
|
|
161
164
|
const subPath = pathname.slice(9);
|
|
162
165
|
setCorsHeaders(res);
|
|
@@ -220,7 +223,7 @@ async function handleControlAPI(req, res, pathname, fixtures, journal, videoStat
|
|
|
220
223
|
return true;
|
|
221
224
|
}
|
|
222
225
|
if (subPath === "/reset/fixtures" && req.method === "POST") {
|
|
223
|
-
performFixturesReset(fixtures, journal, videoStates, defaults);
|
|
226
|
+
performFixturesReset(fixtures, journal, videoStates, openRouterVideoJobs, defaults);
|
|
224
227
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
225
228
|
res.end(JSON.stringify({ reset: true }));
|
|
226
229
|
return true;
|
|
@@ -232,7 +235,7 @@ async function handleControlAPI(req, res, pathname, fixtures, journal, videoStat
|
|
|
232
235
|
return true;
|
|
233
236
|
}
|
|
234
237
|
if (subPath === "/reset" && req.method === "POST") {
|
|
235
|
-
performFixturesReset(fixtures, journal, videoStates, defaults);
|
|
238
|
+
performFixturesReset(fixtures, journal, videoStates, openRouterVideoJobs, defaults);
|
|
236
239
|
const deprecation = "POST /__aimock/reset is deprecated; use POST /__aimock/reset/fixtures (full reset) or POST /__aimock/reset/journal (journal only)";
|
|
237
240
|
defaults.logger.warn("POST /__aimock/reset is deprecated; use /__aimock/reset/fixtures or /__aimock/reset/journal");
|
|
238
241
|
res.writeHead(200, {
|
|
@@ -374,7 +377,7 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
374
377
|
body._endpointType = "chat";
|
|
375
378
|
body._context = getContext(req);
|
|
376
379
|
const testId = getTestId(req);
|
|
377
|
-
const fixture =
|
|
380
|
+
const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(fixtures, body, journal.getFixtureMatchCountsForTest(testId), defaults.requestTransform);
|
|
378
381
|
if (fixture) {
|
|
379
382
|
journal.incrementFixtureMatchCount(fixture, fixtures, testId);
|
|
380
383
|
defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);
|
|
@@ -401,8 +404,8 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
401
404
|
if (!fixture) {
|
|
402
405
|
if (resolveStrictMode(defaults.strict, req.headers)) {
|
|
403
406
|
const strictStatus = 503;
|
|
404
|
-
const strictMessage =
|
|
405
|
-
defaults.logger.error(
|
|
407
|
+
const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);
|
|
408
|
+
defaults.logger.error(strictNoMatchLogLine(req.method ?? "POST", req.url ?? COMPLETIONS_PATH, skippedBySequenceOrTurn));
|
|
406
409
|
journal.add({
|
|
407
410
|
method: req.method ?? "POST",
|
|
408
411
|
path: req.url ?? COMPLETIONS_PATH,
|
|
@@ -512,6 +515,8 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
512
515
|
if (isContentWithToolCallsResponse(response)) {
|
|
513
516
|
if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
|
|
514
517
|
const overrides = extractOverrides(response);
|
|
518
|
+
const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
|
|
519
|
+
const effReasoning = resolveReasoningForModel(response.reasoning, body.model, effectiveStrict, defaults.logger);
|
|
515
520
|
const journalEntry = journal.add({
|
|
516
521
|
method: req.method ?? "POST",
|
|
517
522
|
path: req.url ?? COMPLETIONS_PATH,
|
|
@@ -523,11 +528,11 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
523
528
|
}
|
|
524
529
|
});
|
|
525
530
|
if (body.stream !== true) {
|
|
526
|
-
const completion = buildContentWithToolCallsCompletion(response.content, response.toolCalls, body.model,
|
|
531
|
+
const completion = buildContentWithToolCallsCompletion(response.content, response.toolCalls, body.model, effReasoning, overrides, body.messages);
|
|
527
532
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
528
533
|
res.end(JSON.stringify(completion));
|
|
529
534
|
} else {
|
|
530
|
-
const chunks = buildContentWithToolCallsChunks(response.content, response.toolCalls, body.model, chunkSize,
|
|
535
|
+
const chunks = buildContentWithToolCallsChunks(response.content, response.toolCalls, body.model, chunkSize, effReasoning, overrides);
|
|
531
536
|
const completionText = response.content + response.toolCalls.map((tc) => tc.name + tc.arguments).join("");
|
|
532
537
|
const usageChunk = includeUsage ? buildUsageChunk(chunks[0]?.id ?? "chatcmpl-unknown", overrides?.model ?? body.model, chunks[0]?.created ?? Math.floor(Date.now() / 1e3), overrides?.usage ? {
|
|
533
538
|
prompt_tokens: overrides.usage.prompt_tokens ?? 0,
|
|
@@ -559,6 +564,8 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
559
564
|
if (isTextResponse(response)) {
|
|
560
565
|
if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
|
|
561
566
|
const overrides = extractOverrides(response);
|
|
567
|
+
const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
|
|
568
|
+
const effReasoning = resolveReasoningForModel(response.reasoning, body.model, effectiveStrict, defaults.logger);
|
|
562
569
|
const journalEntry = journal.add({
|
|
563
570
|
method: req.method ?? "POST",
|
|
564
571
|
path: req.url ?? COMPLETIONS_PATH,
|
|
@@ -570,11 +577,11 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
570
577
|
}
|
|
571
578
|
});
|
|
572
579
|
if (body.stream !== true) {
|
|
573
|
-
const completion = buildTextCompletion(response.content, body.model,
|
|
580
|
+
const completion = buildTextCompletion(response.content, body.model, effReasoning, overrides, body.messages);
|
|
574
581
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
575
582
|
res.end(JSON.stringify(completion));
|
|
576
583
|
} else {
|
|
577
|
-
const chunks = buildTextChunks(response.content, body.model, chunkSize,
|
|
584
|
+
const chunks = buildTextChunks(response.content, body.model, chunkSize, effReasoning, overrides);
|
|
578
585
|
const usageChunk = includeUsage ? buildUsageChunk(chunks[0]?.id ?? "chatcmpl-unknown", overrides?.model ?? body.model, chunks[0]?.created ?? Math.floor(Date.now() / 1e3), overrides?.usage ? {
|
|
579
586
|
prompt_tokens: overrides.usage.prompt_tokens ?? 0,
|
|
580
587
|
completion_tokens: overrides.usage.completion_tokens ?? 0,
|
|
@@ -605,6 +612,8 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
605
612
|
if (isToolCallResponse(response)) {
|
|
606
613
|
if (response.webSearches?.length) defaults.logger.warn("webSearches in fixture response are not supported for Chat Completions API — ignoring");
|
|
607
614
|
const overrides = extractOverrides(response);
|
|
615
|
+
const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);
|
|
616
|
+
const effReasoning = resolveReasoningForModel(response.reasoning, body.model, effectiveStrict, defaults.logger);
|
|
608
617
|
const journalEntry = journal.add({
|
|
609
618
|
method: req.method ?? "POST",
|
|
610
619
|
path: req.url ?? COMPLETIONS_PATH,
|
|
@@ -616,11 +625,11 @@ async function handleCompletions(req, res, fixtures, journal, defaults, modelFal
|
|
|
616
625
|
}
|
|
617
626
|
});
|
|
618
627
|
if (body.stream !== true) {
|
|
619
|
-
const completion = buildToolCallCompletion(response.toolCalls, body.model, overrides, body.messages);
|
|
628
|
+
const completion = buildToolCallCompletion(response.toolCalls, body.model, effReasoning, overrides, body.messages);
|
|
620
629
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
621
630
|
res.end(JSON.stringify(completion));
|
|
622
631
|
} else {
|
|
623
|
-
const chunks = buildToolCallChunks(response.toolCalls, body.model, chunkSize, overrides);
|
|
632
|
+
const chunks = buildToolCallChunks(response.toolCalls, body.model, chunkSize, effReasoning, overrides);
|
|
624
633
|
const completionText = response.toolCalls.map((tc) => tc.name + tc.arguments).join("");
|
|
625
634
|
const usageChunk = includeUsage ? buildUsageChunk(chunks[0]?.id ?? "chatcmpl-unknown", overrides?.model ?? body.model, chunks[0]?.created ?? Math.floor(Date.now() / 1e3), overrides?.usage ? {
|
|
626
635
|
prompt_tokens: overrides.usage.prompt_tokens ?? 0,
|
|
@@ -690,6 +699,9 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
690
699
|
},
|
|
691
700
|
get falQueue() {
|
|
692
701
|
return serverOptions.falQueue;
|
|
702
|
+
},
|
|
703
|
+
get openRouterVideo() {
|
|
704
|
+
return serverOptions.openRouterVideo;
|
|
693
705
|
}
|
|
694
706
|
};
|
|
695
707
|
if (options?.chaos) {
|
|
@@ -709,11 +721,31 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
709
721
|
];
|
|
710
722
|
for (const { name, value } of chaosRates) if (value !== void 0 && (value < 0 || value > 1)) logger.warn(`Chaos ${name} (${value}) is outside 0-1 range — will be clamped at runtime`);
|
|
711
723
|
}
|
|
724
|
+
for (const { name, config } of [{
|
|
725
|
+
name: "falQueue",
|
|
726
|
+
config: options?.falQueue
|
|
727
|
+
}, {
|
|
728
|
+
name: "openRouterVideo",
|
|
729
|
+
config: options?.openRouterVideo
|
|
730
|
+
}]) {
|
|
731
|
+
if (!config) continue;
|
|
732
|
+
for (const field of ["pollsBeforeInProgress", "pollsBeforeCompleted"]) {
|
|
733
|
+
const value = config[field];
|
|
734
|
+
if (value === void 0) continue;
|
|
735
|
+
if (!Number.isFinite(value)) logger.warn(`${name}.${field} (${value}) is not a finite number — treating as unset`);
|
|
736
|
+
else if (!Number.isInteger(value) || value < 0) logger.warn(`${name}.${field} (${value}) is not a non-negative integer — flooring/clamping to a non-negative integer`);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
{
|
|
740
|
+
const cap = options?.record?.openRouterVideo?.maxContentBytes;
|
|
741
|
+
if (cap !== void 0 && (!Number.isInteger(cap) || cap < 0)) logger.warn(`record.openRouterVideo.maxContentBytes (${cap}) is not a non-negative integer — using the default cap (${OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES})`);
|
|
742
|
+
}
|
|
712
743
|
const journal = new Journal({
|
|
713
744
|
maxEntries: options?.journalMaxEntries ?? 1e3,
|
|
714
745
|
fixtureCountsMaxTestIds: options?.fixtureCountsMaxTestIds ?? 500
|
|
715
746
|
});
|
|
716
747
|
const videoStates = new VideoStateMap();
|
|
748
|
+
const openRouterVideoJobs = new OpenRouterVideoJobMap();
|
|
717
749
|
if (mounts) for (const { handler } of mounts) {
|
|
718
750
|
if (handler.setJournal) handler.setJournal(journal);
|
|
719
751
|
if (registry && handler.setRegistry) handler.setRegistry(registry);
|
|
@@ -760,7 +792,7 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
760
792
|
}
|
|
761
793
|
});
|
|
762
794
|
if (pathname.startsWith(CONTROL_PREFIX)) {
|
|
763
|
-
await handleControlAPI(req, res, pathname, fixtures, journal, videoStates, defaults);
|
|
795
|
+
await handleControlAPI(req, res, pathname, fixtures, journal, videoStates, openRouterVideoJobs, defaults);
|
|
764
796
|
return;
|
|
765
797
|
}
|
|
766
798
|
if (mounts) {
|
|
@@ -824,6 +856,125 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
824
856
|
res.end(JSON.stringify({ models }));
|
|
825
857
|
return;
|
|
826
858
|
}
|
|
859
|
+
const openRouterVideoContentMatch = pathname.match(OPENROUTER_VIDEO_CONTENT_RE);
|
|
860
|
+
if (openRouterVideoContentMatch && req.method === "GET") {
|
|
861
|
+
try {
|
|
862
|
+
await handleOpenRouterVideoContent(req, res, openRouterVideoContentMatch[1], journal, defaults, setCorsHeaders, openRouterVideoJobs);
|
|
863
|
+
} catch (err) {
|
|
864
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
865
|
+
defaults.logger.error(`openrouter-video content: ${msg}`);
|
|
866
|
+
if (!res.headersSent) {
|
|
867
|
+
try {
|
|
868
|
+
journal.add({
|
|
869
|
+
method: req.method ?? "GET",
|
|
870
|
+
path: req.url ?? pathname,
|
|
871
|
+
headers: flattenHeaders(req.headers),
|
|
872
|
+
body: null,
|
|
873
|
+
response: {
|
|
874
|
+
status: 500,
|
|
875
|
+
fixture: null
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
} catch (jErr) {
|
|
879
|
+
defaults.logger.warn(`openrouter-video content: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
|
|
880
|
+
}
|
|
881
|
+
writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
882
|
+
message: msg,
|
|
883
|
+
type: "server_error"
|
|
884
|
+
} }));
|
|
885
|
+
} else if (!res.writableEnded) res.destroy();
|
|
886
|
+
}
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
if (pathname === OPENROUTER_VIDEO_MODELS_PATH && req.method === "GET") {
|
|
890
|
+
try {
|
|
891
|
+
await handleOpenRouterVideoModels(req, res, fixtures, journal, defaults, setCorsHeaders);
|
|
892
|
+
} catch (err) {
|
|
893
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
894
|
+
defaults.logger.error(`openrouter-video models: ${msg}`);
|
|
895
|
+
if (!res.headersSent) {
|
|
896
|
+
try {
|
|
897
|
+
journal.add({
|
|
898
|
+
method: req.method ?? "GET",
|
|
899
|
+
path: req.url ?? pathname,
|
|
900
|
+
headers: flattenHeaders(req.headers),
|
|
901
|
+
body: null,
|
|
902
|
+
response: {
|
|
903
|
+
status: 500,
|
|
904
|
+
fixture: null
|
|
905
|
+
}
|
|
906
|
+
});
|
|
907
|
+
} catch (jErr) {
|
|
908
|
+
defaults.logger.warn(`openrouter-video models: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
|
|
909
|
+
}
|
|
910
|
+
writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
911
|
+
message: msg,
|
|
912
|
+
type: "server_error"
|
|
913
|
+
} }));
|
|
914
|
+
} else if (!res.writableEnded) res.destroy();
|
|
915
|
+
}
|
|
916
|
+
return;
|
|
917
|
+
}
|
|
918
|
+
const openRouterVideoStatusMatch = pathname.match(OPENROUTER_VIDEO_STATUS_RE);
|
|
919
|
+
if (openRouterVideoStatusMatch && req.method === "GET") {
|
|
920
|
+
try {
|
|
921
|
+
await handleOpenRouterVideoStatus(req, res, openRouterVideoStatusMatch[1], fixtures, journal, defaults, setCorsHeaders, openRouterVideoJobs);
|
|
922
|
+
} catch (err) {
|
|
923
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
924
|
+
defaults.logger.error(`openrouter-video status: ${msg}`);
|
|
925
|
+
if (!res.headersSent) {
|
|
926
|
+
try {
|
|
927
|
+
journal.add({
|
|
928
|
+
method: req.method ?? "GET",
|
|
929
|
+
path: req.url ?? pathname,
|
|
930
|
+
headers: flattenHeaders(req.headers),
|
|
931
|
+
body: null,
|
|
932
|
+
response: {
|
|
933
|
+
status: 500,
|
|
934
|
+
fixture: null
|
|
935
|
+
}
|
|
936
|
+
});
|
|
937
|
+
} catch (jErr) {
|
|
938
|
+
defaults.logger.warn(`openrouter-video status: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
|
|
939
|
+
}
|
|
940
|
+
writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
941
|
+
message: msg,
|
|
942
|
+
type: "server_error"
|
|
943
|
+
} }));
|
|
944
|
+
} else if (!res.writableEnded) res.destroy();
|
|
945
|
+
}
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
if (pathname === OPENROUTER_VIDEOS_PATH && req.method === "POST") {
|
|
949
|
+
setCorsHeaders(res);
|
|
950
|
+
try {
|
|
951
|
+
await handleOpenRouterVideoCreate(req, res, await readBody(req), fixtures, journal, defaults, setCorsHeaders, openRouterVideoJobs);
|
|
952
|
+
} catch (err) {
|
|
953
|
+
const msg = err instanceof Error ? err.message : "Internal error";
|
|
954
|
+
defaults.logger.error(`openrouter-video submit: ${msg}`);
|
|
955
|
+
if (!res.headersSent) {
|
|
956
|
+
try {
|
|
957
|
+
journal.add({
|
|
958
|
+
method: req.method ?? "POST",
|
|
959
|
+
path: req.url ?? pathname,
|
|
960
|
+
headers: flattenHeaders(req.headers),
|
|
961
|
+
body: null,
|
|
962
|
+
response: {
|
|
963
|
+
status: 500,
|
|
964
|
+
fixture: null
|
|
965
|
+
}
|
|
966
|
+
});
|
|
967
|
+
} catch (jErr) {
|
|
968
|
+
defaults.logger.warn(`openrouter-video submit: journal write failed after handler error: ${jErr instanceof Error ? jErr.message : String(jErr)}`);
|
|
969
|
+
}
|
|
970
|
+
writeErrorResponse(res, 500, JSON.stringify({ error: {
|
|
971
|
+
message: msg,
|
|
972
|
+
type: "server_error"
|
|
973
|
+
} }));
|
|
974
|
+
} else if (!res.writableEnded) res.destroy();
|
|
975
|
+
}
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
827
978
|
let azureDeploymentId;
|
|
828
979
|
const azureMatch = pathname.match(AZURE_DEPLOYMENT_RE);
|
|
829
980
|
if (azureMatch && req.method === "POST") {
|
|
@@ -1099,7 +1250,7 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1099
1250
|
}
|
|
1100
1251
|
return;
|
|
1101
1252
|
}
|
|
1102
|
-
const videoStatusMatch = pathname.match(
|
|
1253
|
+
const videoStatusMatch = pathname.match(OPENAI_VIDEO_STATUS_RE);
|
|
1103
1254
|
if (videoStatusMatch && req.method === "GET") {
|
|
1104
1255
|
const videoId = videoStatusMatch[1];
|
|
1105
1256
|
handleVideoStatus(req, res, videoId, journal, defaults, setCorsHeaders, videoStates);
|
|
@@ -1521,6 +1672,8 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1521
1672
|
server.close = function(callback) {
|
|
1522
1673
|
for (const ws of activeConnections) ws.close(1001, "Server shutting down");
|
|
1523
1674
|
activeConnections.clear();
|
|
1675
|
+
videoStates.clear();
|
|
1676
|
+
openRouterVideoJobs.clear();
|
|
1524
1677
|
originalClose(callback);
|
|
1525
1678
|
return this;
|
|
1526
1679
|
};
|
|
@@ -1541,7 +1694,8 @@ async function createServer(fixtures, options, mounts, serviceFixtures) {
|
|
|
1541
1694
|
journal,
|
|
1542
1695
|
url,
|
|
1543
1696
|
defaults,
|
|
1544
|
-
videoStates
|
|
1697
|
+
videoStates,
|
|
1698
|
+
openRouterVideoJobs
|
|
1545
1699
|
});
|
|
1546
1700
|
});
|
|
1547
1701
|
});
|