@copilotkit/aimock 1.40.0 → 1.41.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 +16 -0
- package/README.md +3 -2
- package/dist/agui-handler.d.cts.map +1 -1
- package/dist/byteplus-video.cjs +954 -0
- package/dist/byteplus-video.cjs.map +1 -0
- package/dist/byteplus-video.d.cts +176 -0
- package/dist/byteplus-video.d.cts.map +1 -0
- package/dist/byteplus-video.d.ts +176 -0
- package/dist/byteplus-video.d.ts.map +1 -0
- package/dist/byteplus-video.js +947 -0
- package/dist/byteplus-video.js.map +1 -0
- package/dist/cli.cjs +5 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/config-loader.d.cts.map +1 -1
- package/dist/config-loader.d.ts.map +1 -1
- package/dist/images.cjs +2 -2
- package/dist/images.cjs.map +1 -1
- package/dist/images.d.cts +11 -3
- package/dist/images.d.cts.map +1 -1
- package/dist/images.d.ts +11 -3
- package/dist/images.d.ts.map +1 -1
- package/dist/images.js +2 -2
- package/dist/images.js.map +1 -1
- package/dist/index.cjs +7 -0
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/metrics.cjs +20 -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 +19 -1
- package/dist/metrics.js.map +1 -1
- package/dist/provider-auth.cjs +2 -0
- package/dist/provider-auth.cjs.map +1 -1
- package/dist/provider-auth.js +2 -0
- package/dist/provider-auth.js.map +1 -1
- package/dist/router.cjs +1 -0
- package/dist/router.cjs.map +1 -1
- package/dist/router.d.cts.map +1 -1
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +1 -0
- package/dist/router.js.map +1 -1
- package/dist/server.cjs +91 -6
- 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 +92 -7
- package/dist/server.js.map +1 -1
- package/dist/stream-collapse.cjs +2 -1
- package/dist/stream-collapse.cjs.map +1 -1
- package/dist/stream-collapse.js +2 -1
- package/dist/stream-collapse.js.map +1 -1
- package/dist/types.d.cts +19 -3
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.ts +19 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-types.d.cts.map +1 -1
- package/package.json +2 -2
package/dist/images.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"images.cjs","names":["flattenHeaders","getContext","getTestId","matchFixtureDiagnostic","applyChaos","resolveStrictMode","strictNoMatchMessage","strictNoMatchLogLine","strictOverrideField","proxyAndRecord","resolveResponse","isErrorResponse","serializeErrorResponse","isImageResponse","extractBoundary","extractFormField"],"sources":["../src/images.ts"],"sourcesContent":["import type * as http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isImageResponse,\n isErrorResponse,\n serializeErrorResponse,\n flattenHeaders,\n getContext,\n getTestId,\n resolveResponse,\n resolveStrictMode,\n strictOverrideField,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\nimport { extractBoundary, extractFormField } from \"./transcription.js\";\n\ninterface OpenAIImageRequest {\n model?: string;\n prompt: string;\n n?: number;\n size?: string;\n response_format?: \"url\" | \"b64_json\";\n [key: string]: unknown;\n}\n\ninterface GeminiPredictRequest {\n instances: Array<{ prompt: string }>;\n parameters?: { sampleCount?: number };\n [key: string]: unknown;\n}\n\nfunction buildSyntheticRequest(\n model: string,\n prompt: string,\n context?: string,\n): ChatCompletionRequest {\n return {\n model,\n messages: [{ role: \"user\", content: prompt }],\n _endpointType: \"image\",\n ...(context !== undefined && { _context: context }),\n };\n}\n\nexport async function handleImages(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n format: \"openai\" | \"gemini\" = \"openai\",\n geminiModel?: string,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/generations\";\n const method = req.method ?? \"POST\";\n\n let model: string;\n let prompt: string;\n\n try {\n const body = JSON.parse(raw);\n if (format === \"gemini\") {\n const geminiReq = body as GeminiPredictRequest;\n prompt = geminiReq.instances?.[0]?.prompt ?? \"\";\n model = geminiModel ?? \"imagen\";\n } else {\n const openaiReq = body as OpenAIImageRequest;\n prompt = openaiReq.prompt ?? \"\";\n model = openaiReq.model ?? \"dall-e-3\";\n }\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n if (!prompt) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Missing required parameter: 'prompt'\", type: \"invalid_request_error\" },\n }),\n );\n return;\n }\n\n const syntheticReq = buildSyntheticRequest(model, prompt, getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n format === \"gemini\" ? \"gemini\" : \"openai\",\n req.url ?? \"/v1/images/generations\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n // Normalize to array of image items\n const items = response.images ?? (response.image ? [response.image] : []);\n\n if (format === \"gemini\") {\n const predictions = items.map((item) => ({\n bytesBase64Encoded: item.b64Json ?? \"\",\n mimeType: \"image/png\" as const,\n }));\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ predictions }));\n } else {\n serializeOpenAIImageResponse(res, items);\n }\n}\n\n/**\n * Write the standard OpenAI image response envelope (`{ created, data }`).\n * Shared by generations, edit, and variations endpoints.\n */\nfunction serializeOpenAIImageResponse(\n res: http.ServerResponse,\n items: Array<{ url?: string; b64Json?: string; revisedPrompt?: string }>,\n): void {\n const data = items.map((item) => {\n const entry: Record<string, string> = {};\n if (item.url) entry.url = item.url;\n if (item.b64Json) entry.b64_json = item.b64Json;\n if (item.revisedPrompt) entry.revised_prompt = item.revisedPrompt;\n return entry;\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ created: Math.floor(Date.now() / 1000), data }));\n}\n\n/**\n * Handle POST /v1/images/edits — OpenAI Image Edit API.\n *\n * Request uses multipart/form-data. We extract text fields (`prompt`, `model`,\n * `n`, `size`, `response_format`) and ignore binary fields (`image`, `mask`)\n * since aimock doesn't process actual image data.\n *\n * The response envelope is identical to /v1/images/generations.\n */\nexport async function handleImageEdit(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/edits\";\n const method = req.method ?? \"POST\";\n\n const contentType = Array.isArray(req.headers[\"content-type\"])\n ? req.headers[\"content-type\"][0]\n : req.headers[\"content-type\"];\n const boundary = extractBoundary(contentType);\n\n const prompt = extractFormField(raw, \"prompt\", boundary) ?? \"\";\n const model = extractFormField(raw, \"model\", boundary) ?? \"dall-e-2\";\n\n if (!prompt) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Missing required parameter: 'prompt'\", type: \"invalid_request_error\" },\n }),\n );\n return;\n }\n\n const syntheticReq = buildSyntheticRequest(model, prompt, getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/images/edits\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const items = response.images ?? (response.image ? [response.image] : []);\n serializeOpenAIImageResponse(res, items);\n}\n\n/**\n * Handle POST /v1/images/variations — OpenAI Image Variations API.\n *\n * Request uses multipart/form-data. We extract text fields (`model`, `n`,\n * `size`, `response_format`) and ignore the binary `image` field.\n * Unlike edit, no `prompt` field is required.\n *\n * The response envelope is identical to /v1/images/generations.\n */\nexport async function handleImageVariations(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/variations\";\n const method = req.method ?? \"POST\";\n\n const contentType = Array.isArray(req.headers[\"content-type\"])\n ? req.headers[\"content-type\"][0]\n : req.headers[\"content-type\"];\n const boundary = extractBoundary(contentType);\n\n const model = extractFormField(raw, \"model\", boundary) ?? \"dall-e-2\";\n\n // Variations don't have a prompt — use a synthetic placeholder for fixture matching\n const syntheticReq = buildSyntheticRequest(model, \"[variation]\", getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/images/variations\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const items = response.images ?? (response.image ? [response.image] : []);\n serializeOpenAIImageResponse(res, items);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"images.cjs","names":["flattenHeaders","getContext","getTestId","matchFixtureDiagnostic","applyChaos","resolveStrictMode","strictNoMatchMessage","strictNoMatchLogLine","strictOverrideField","proxyAndRecord","resolveResponse","isErrorResponse","serializeErrorResponse","isImageResponse","extractBoundary","extractFormField"],"sources":["../src/images.ts"],"sourcesContent":["import type * as http from \"node:http\";\nimport type {\n ChatCompletionRequest,\n Fixture,\n HandlerDefaults,\n RecordProviderKey,\n} from \"./types.js\";\nimport {\n isImageResponse,\n isErrorResponse,\n serializeErrorResponse,\n flattenHeaders,\n getContext,\n getTestId,\n resolveResponse,\n resolveStrictMode,\n strictOverrideField,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\nimport { extractBoundary, extractFormField } from \"./transcription.js\";\n\ninterface OpenAIImageRequest {\n model?: string;\n prompt: string;\n n?: number;\n size?: string;\n response_format?: \"url\" | \"b64_json\";\n [key: string]: unknown;\n}\n\ninterface GeminiPredictRequest {\n instances: Array<{ prompt: string }>;\n parameters?: { sampleCount?: number };\n [key: string]: unknown;\n}\n\nfunction buildSyntheticRequest(\n model: string,\n prompt: string,\n context?: string,\n): ChatCompletionRequest {\n return {\n model,\n messages: [{ role: \"user\", content: prompt }],\n _endpointType: \"image\",\n ...(context !== undefined && { _context: context }),\n };\n}\n\nexport async function handleImages(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n format: \"openai\" | \"gemini\" = \"openai\",\n geminiModel?: string,\n /**\n * Provider key this request records under. Defaults to `\"openai\"` — the\n * value hardcoded here before BytePlus Ark needed images attribution — so the\n * Gemini `:predict` call site keeps today's behavior by omitting it. Only the\n * OpenAI-images call site passes it, and only with a non-default value behind\n * server.ts's configuration gate (a byteplus upstream must be configured AND\n * the request must carry the /api/v3 prefix).\n */\n recordProviderKey?: RecordProviderKey,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/generations\";\n const method = req.method ?? \"POST\";\n\n let model: string;\n let prompt: string;\n\n try {\n const body = JSON.parse(raw);\n if (format === \"gemini\") {\n const geminiReq = body as GeminiPredictRequest;\n prompt = geminiReq.instances?.[0]?.prompt ?? \"\";\n model = geminiModel ?? \"imagen\";\n } else {\n const openaiReq = body as OpenAIImageRequest;\n prompt = openaiReq.prompt ?? \"\";\n model = openaiReq.model ?? \"dall-e-3\";\n }\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n if (!prompt) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Missing required parameter: 'prompt'\", type: \"invalid_request_error\" },\n }),\n );\n return;\n }\n\n const syntheticReq = buildSyntheticRequest(model, prompt, getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n format === \"gemini\" ? \"gemini\" : (recordProviderKey ?? \"openai\"),\n req.url ?? \"/v1/images/generations\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n // Normalize to array of image items\n const items = response.images ?? (response.image ? [response.image] : []);\n\n if (format === \"gemini\") {\n const predictions = items.map((item) => ({\n bytesBase64Encoded: item.b64Json ?? \"\",\n mimeType: \"image/png\" as const,\n }));\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ predictions }));\n } else {\n serializeOpenAIImageResponse(res, items);\n }\n}\n\n/**\n * Write the standard OpenAI image response envelope (`{ created, data }`).\n * Shared by generations, edit, and variations endpoints.\n */\nfunction serializeOpenAIImageResponse(\n res: http.ServerResponse,\n items: Array<{ url?: string; b64Json?: string; revisedPrompt?: string }>,\n): void {\n const data = items.map((item) => {\n const entry: Record<string, string> = {};\n if (item.url) entry.url = item.url;\n if (item.b64Json) entry.b64_json = item.b64Json;\n if (item.revisedPrompt) entry.revised_prompt = item.revisedPrompt;\n return entry;\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ created: Math.floor(Date.now() / 1000), data }));\n}\n\n/**\n * Handle POST /v1/images/edits — OpenAI Image Edit API.\n *\n * Request uses multipart/form-data. We extract text fields (`prompt`, `model`,\n * `n`, `size`, `response_format`) and ignore binary fields (`image`, `mask`)\n * since aimock doesn't process actual image data.\n *\n * The response envelope is identical to /v1/images/generations.\n */\nexport async function handleImageEdit(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/edits\";\n const method = req.method ?? \"POST\";\n\n const contentType = Array.isArray(req.headers[\"content-type\"])\n ? req.headers[\"content-type\"][0]\n : req.headers[\"content-type\"];\n const boundary = extractBoundary(contentType);\n\n const prompt = extractFormField(raw, \"prompt\", boundary) ?? \"\";\n const model = extractFormField(raw, \"model\", boundary) ?? \"dall-e-2\";\n\n if (!prompt) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Missing required parameter: 'prompt'\", type: \"invalid_request_error\" },\n }),\n );\n return;\n }\n\n const syntheticReq = buildSyntheticRequest(model, prompt, getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/images/edits\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const items = response.images ?? (response.image ? [response.image] : []);\n serializeOpenAIImageResponse(res, items);\n}\n\n/**\n * Handle POST /v1/images/variations — OpenAI Image Variations API.\n *\n * Request uses multipart/form-data. We extract text fields (`model`, `n`,\n * `size`, `response_format`) and ignore the binary `image` field.\n * Unlike edit, no `prompt` field is required.\n *\n * The response envelope is identical to /v1/images/generations.\n */\nexport async function handleImageVariations(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/variations\";\n const method = req.method ?? \"POST\";\n\n const contentType = Array.isArray(req.headers[\"content-type\"])\n ? req.headers[\"content-type\"][0]\n : req.headers[\"content-type\"];\n const boundary = extractBoundary(contentType);\n\n const model = extractFormField(raw, \"model\", boundary) ?? \"dall-e-2\";\n\n // Variations don't have a prompt — use a synthetic placeholder for fixture matching\n const syntheticReq = buildSyntheticRequest(model, \"[variation]\", getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/images/variations\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const items = response.images ?? (response.image ? [response.image] : []);\n serializeOpenAIImageResponse(res, items);\n}\n"],"mappings":"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"}
|
package/dist/images.d.cts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { Journal } from "./journal.cjs";
|
|
2
|
-
import { Fixture, HandlerDefaults } from "./types.cjs";
|
|
2
|
+
import { Fixture, HandlerDefaults, RecordProviderKey } from "./types.cjs";
|
|
3
3
|
import * as http$1 from "node:http";
|
|
4
4
|
|
|
5
5
|
//#region src/images.d.ts
|
|
6
|
-
declare function handleImages(req: http$1.IncomingMessage, res: http$1.ServerResponse, raw: string, fixtures: Fixture[], journal: Journal, defaults: HandlerDefaults, setCorsHeaders: (res: http$1.ServerResponse) => void, format?: "openai" | "gemini", geminiModel?: string
|
|
6
|
+
declare function handleImages(req: http$1.IncomingMessage, res: http$1.ServerResponse, raw: string, fixtures: Fixture[], journal: Journal, defaults: HandlerDefaults, setCorsHeaders: (res: http$1.ServerResponse) => void, format?: "openai" | "gemini", geminiModel?: string,
|
|
7
|
+
/**
|
|
8
|
+
* Provider key this request records under. Defaults to `"openai"` — the
|
|
9
|
+
* value hardcoded here before BytePlus Ark needed images attribution — so the
|
|
10
|
+
* Gemini `:predict` call site keeps today's behavior by omitting it. Only the
|
|
11
|
+
* OpenAI-images call site passes it, and only with a non-default value behind
|
|
12
|
+
* server.ts's configuration gate (a byteplus upstream must be configured AND
|
|
13
|
+
* the request must carry the /api/v3 prefix).
|
|
14
|
+
*/
|
|
15
|
+
recordProviderKey?: RecordProviderKey): Promise<void>;
|
|
7
16
|
/**
|
|
8
17
|
* Handle POST /v1/images/edits — OpenAI Image Edit API.
|
|
9
18
|
*
|
|
@@ -13,7 +22,6 @@ declare function handleImages(req: http$1.IncomingMessage, res: http$1.ServerRes
|
|
|
13
22
|
*
|
|
14
23
|
* The response envelope is identical to /v1/images/generations.
|
|
15
24
|
*/
|
|
16
|
-
|
|
17
25
|
//#endregion
|
|
18
26
|
export { handleImages };
|
|
19
27
|
//# sourceMappingURL=images.d.cts.map
|
package/dist/images.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"images.d.cts","names":[],"sources":["../src/images.ts"],"sourcesContent":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"images.d.cts","names":[],"sources":["../src/images.ts"],"sourcesContent":[],"mappings":";;;;;iBAuDsB,YAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,uCAEA,oBACD,mBACC,uCACY,MAAA,CAAK;;AAP7B;;;;;;;iBAO6B,CAAA,EAWP,iBAXO,CAAA,EAY1B,OAZ0B,CAAA,IAAA,CAAA"}
|
package/dist/images.d.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { Journal } from "./journal.js";
|
|
2
|
-
import { Fixture, HandlerDefaults } from "./types.js";
|
|
2
|
+
import { Fixture, HandlerDefaults, RecordProviderKey } from "./types.js";
|
|
3
3
|
import * as http$1 from "node:http";
|
|
4
4
|
|
|
5
5
|
//#region src/images.d.ts
|
|
6
|
-
declare function handleImages(req: http$1.IncomingMessage, res: http$1.ServerResponse, raw: string, fixtures: Fixture[], journal: Journal, defaults: HandlerDefaults, setCorsHeaders: (res: http$1.ServerResponse) => void, format?: "openai" | "gemini", geminiModel?: string
|
|
6
|
+
declare function handleImages(req: http$1.IncomingMessage, res: http$1.ServerResponse, raw: string, fixtures: Fixture[], journal: Journal, defaults: HandlerDefaults, setCorsHeaders: (res: http$1.ServerResponse) => void, format?: "openai" | "gemini", geminiModel?: string,
|
|
7
|
+
/**
|
|
8
|
+
* Provider key this request records under. Defaults to `"openai"` — the
|
|
9
|
+
* value hardcoded here before BytePlus Ark needed images attribution — so the
|
|
10
|
+
* Gemini `:predict` call site keeps today's behavior by omitting it. Only the
|
|
11
|
+
* OpenAI-images call site passes it, and only with a non-default value behind
|
|
12
|
+
* server.ts's configuration gate (a byteplus upstream must be configured AND
|
|
13
|
+
* the request must carry the /api/v3 prefix).
|
|
14
|
+
*/
|
|
15
|
+
recordProviderKey?: RecordProviderKey): Promise<void>;
|
|
7
16
|
/**
|
|
8
17
|
* Handle POST /v1/images/edits — OpenAI Image Edit API.
|
|
9
18
|
*
|
|
@@ -13,7 +22,6 @@ declare function handleImages(req: http$1.IncomingMessage, res: http$1.ServerRes
|
|
|
13
22
|
*
|
|
14
23
|
* The response envelope is identical to /v1/images/generations.
|
|
15
24
|
*/
|
|
16
|
-
|
|
17
25
|
//#endregion
|
|
18
26
|
export { handleImages };
|
|
19
27
|
//# sourceMappingURL=images.d.ts.map
|
package/dist/images.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"images.d.ts","names":[],"sources":["../src/images.ts"],"sourcesContent":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"images.d.ts","names":[],"sources":["../src/images.ts"],"sourcesContent":[],"mappings":";;;;;iBAuDsB,YAAA,MACf,MAAA,CAAK,sBACL,MAAA,CAAK,uCAEA,oBACD,mBACC,uCACY,MAAA,CAAK;;AAP7B;;;;;;;iBAO6B,CAAA,EAWP,iBAXO,CAAA,EAY1B,OAZ0B,CAAA,IAAA,CAAA"}
|
package/dist/images.js
CHANGED
|
@@ -17,7 +17,7 @@ function buildSyntheticRequest(model, prompt, context) {
|
|
|
17
17
|
...context !== void 0 && { _context: context }
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
async function handleImages(req, res, raw, fixtures, journal, defaults, setCorsHeaders, format = "openai", geminiModel) {
|
|
20
|
+
async function handleImages(req, res, raw, fixtures, journal, defaults, setCorsHeaders, format = "openai", geminiModel, recordProviderKey) {
|
|
21
21
|
setCorsHeaders(res);
|
|
22
22
|
const path = req.url ?? "/v1/images/generations";
|
|
23
23
|
const method = req.method ?? "POST";
|
|
@@ -105,7 +105,7 @@ async function handleImages(req, res, raw, fixtures, journal, defaults, setCorsH
|
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
107
|
if (defaults.record) {
|
|
108
|
-
const outcome = await proxyAndRecord(req, res, syntheticReq, format === "gemini" ? "gemini" : "openai", req.url ?? "/v1/images/generations", fixtures, defaults, raw);
|
|
108
|
+
const outcome = await proxyAndRecord(req, res, syntheticReq, format === "gemini" ? "gemini" : recordProviderKey ?? "openai", req.url ?? "/v1/images/generations", fixtures, defaults, raw);
|
|
109
109
|
if (outcome === "handled_by_hook") return;
|
|
110
110
|
if (outcome !== "not_configured") {
|
|
111
111
|
journal.add({
|
package/dist/images.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"images.js","names":[],"sources":["../src/images.ts"],"sourcesContent":["import type * as http from \"node:http\";\nimport type { ChatCompletionRequest, Fixture, HandlerDefaults } from \"./types.js\";\nimport {\n isImageResponse,\n isErrorResponse,\n serializeErrorResponse,\n flattenHeaders,\n getContext,\n getTestId,\n resolveResponse,\n resolveStrictMode,\n strictOverrideField,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\nimport { extractBoundary, extractFormField } from \"./transcription.js\";\n\ninterface OpenAIImageRequest {\n model?: string;\n prompt: string;\n n?: number;\n size?: string;\n response_format?: \"url\" | \"b64_json\";\n [key: string]: unknown;\n}\n\ninterface GeminiPredictRequest {\n instances: Array<{ prompt: string }>;\n parameters?: { sampleCount?: number };\n [key: string]: unknown;\n}\n\nfunction buildSyntheticRequest(\n model: string,\n prompt: string,\n context?: string,\n): ChatCompletionRequest {\n return {\n model,\n messages: [{ role: \"user\", content: prompt }],\n _endpointType: \"image\",\n ...(context !== undefined && { _context: context }),\n };\n}\n\nexport async function handleImages(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n format: \"openai\" | \"gemini\" = \"openai\",\n geminiModel?: string,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/generations\";\n const method = req.method ?? \"POST\";\n\n let model: string;\n let prompt: string;\n\n try {\n const body = JSON.parse(raw);\n if (format === \"gemini\") {\n const geminiReq = body as GeminiPredictRequest;\n prompt = geminiReq.instances?.[0]?.prompt ?? \"\";\n model = geminiModel ?? \"imagen\";\n } else {\n const openaiReq = body as OpenAIImageRequest;\n prompt = openaiReq.prompt ?? \"\";\n model = openaiReq.model ?? \"dall-e-3\";\n }\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n if (!prompt) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Missing required parameter: 'prompt'\", type: \"invalid_request_error\" },\n }),\n );\n return;\n }\n\n const syntheticReq = buildSyntheticRequest(model, prompt, getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n format === \"gemini\" ? \"gemini\" : \"openai\",\n req.url ?? \"/v1/images/generations\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n // Normalize to array of image items\n const items = response.images ?? (response.image ? [response.image] : []);\n\n if (format === \"gemini\") {\n const predictions = items.map((item) => ({\n bytesBase64Encoded: item.b64Json ?? \"\",\n mimeType: \"image/png\" as const,\n }));\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ predictions }));\n } else {\n serializeOpenAIImageResponse(res, items);\n }\n}\n\n/**\n * Write the standard OpenAI image response envelope (`{ created, data }`).\n * Shared by generations, edit, and variations endpoints.\n */\nfunction serializeOpenAIImageResponse(\n res: http.ServerResponse,\n items: Array<{ url?: string; b64Json?: string; revisedPrompt?: string }>,\n): void {\n const data = items.map((item) => {\n const entry: Record<string, string> = {};\n if (item.url) entry.url = item.url;\n if (item.b64Json) entry.b64_json = item.b64Json;\n if (item.revisedPrompt) entry.revised_prompt = item.revisedPrompt;\n return entry;\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ created: Math.floor(Date.now() / 1000), data }));\n}\n\n/**\n * Handle POST /v1/images/edits — OpenAI Image Edit API.\n *\n * Request uses multipart/form-data. We extract text fields (`prompt`, `model`,\n * `n`, `size`, `response_format`) and ignore binary fields (`image`, `mask`)\n * since aimock doesn't process actual image data.\n *\n * The response envelope is identical to /v1/images/generations.\n */\nexport async function handleImageEdit(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/edits\";\n const method = req.method ?? \"POST\";\n\n const contentType = Array.isArray(req.headers[\"content-type\"])\n ? req.headers[\"content-type\"][0]\n : req.headers[\"content-type\"];\n const boundary = extractBoundary(contentType);\n\n const prompt = extractFormField(raw, \"prompt\", boundary) ?? \"\";\n const model = extractFormField(raw, \"model\", boundary) ?? \"dall-e-2\";\n\n if (!prompt) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Missing required parameter: 'prompt'\", type: \"invalid_request_error\" },\n }),\n );\n return;\n }\n\n const syntheticReq = buildSyntheticRequest(model, prompt, getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/images/edits\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const items = response.images ?? (response.image ? [response.image] : []);\n serializeOpenAIImageResponse(res, items);\n}\n\n/**\n * Handle POST /v1/images/variations — OpenAI Image Variations API.\n *\n * Request uses multipart/form-data. We extract text fields (`model`, `n`,\n * `size`, `response_format`) and ignore the binary `image` field.\n * Unlike edit, no `prompt` field is required.\n *\n * The response envelope is identical to /v1/images/generations.\n */\nexport async function handleImageVariations(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/variations\";\n const method = req.method ?? \"POST\";\n\n const contentType = Array.isArray(req.headers[\"content-type\"])\n ? req.headers[\"content-type\"][0]\n : req.headers[\"content-type\"];\n const boundary = extractBoundary(contentType);\n\n const model = extractFormField(raw, \"model\", boundary) ?? \"dall-e-2\";\n\n // Variations don't have a prompt — use a synthetic placeholder for fixture matching\n const syntheticReq = buildSyntheticRequest(model, \"[variation]\", getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/images/variations\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const items = response.images ?? (response.image ? [response.image] : []);\n serializeOpenAIImageResponse(res, items);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"images.js","names":[],"sources":["../src/images.ts"],"sourcesContent":["import type * as http from \"node:http\";\nimport type {\n ChatCompletionRequest,\n Fixture,\n HandlerDefaults,\n RecordProviderKey,\n} from \"./types.js\";\nimport {\n isImageResponse,\n isErrorResponse,\n serializeErrorResponse,\n flattenHeaders,\n getContext,\n getTestId,\n resolveResponse,\n resolveStrictMode,\n strictOverrideField,\n strictNoMatchMessage,\n strictNoMatchLogLine,\n} from \"./helpers.js\";\nimport { matchFixtureDiagnostic } from \"./router.js\";\nimport { writeErrorResponse } from \"./sse-writer.js\";\nimport type { Journal } from \"./journal.js\";\nimport { applyChaos } from \"./chaos.js\";\nimport { proxyAndRecord } from \"./recorder.js\";\nimport { extractBoundary, extractFormField } from \"./transcription.js\";\n\ninterface OpenAIImageRequest {\n model?: string;\n prompt: string;\n n?: number;\n size?: string;\n response_format?: \"url\" | \"b64_json\";\n [key: string]: unknown;\n}\n\ninterface GeminiPredictRequest {\n instances: Array<{ prompt: string }>;\n parameters?: { sampleCount?: number };\n [key: string]: unknown;\n}\n\nfunction buildSyntheticRequest(\n model: string,\n prompt: string,\n context?: string,\n): ChatCompletionRequest {\n return {\n model,\n messages: [{ role: \"user\", content: prompt }],\n _endpointType: \"image\",\n ...(context !== undefined && { _context: context }),\n };\n}\n\nexport async function handleImages(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n format: \"openai\" | \"gemini\" = \"openai\",\n geminiModel?: string,\n /**\n * Provider key this request records under. Defaults to `\"openai\"` — the\n * value hardcoded here before BytePlus Ark needed images attribution — so the\n * Gemini `:predict` call site keeps today's behavior by omitting it. Only the\n * OpenAI-images call site passes it, and only with a non-default value behind\n * server.ts's configuration gate (a byteplus upstream must be configured AND\n * the request must carry the /api/v3 prefix).\n */\n recordProviderKey?: RecordProviderKey,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/generations\";\n const method = req.method ?? \"POST\";\n\n let model: string;\n let prompt: string;\n\n try {\n const body = JSON.parse(raw);\n if (format === \"gemini\") {\n const geminiReq = body as GeminiPredictRequest;\n prompt = geminiReq.instances?.[0]?.prompt ?? \"\";\n model = geminiModel ?? \"imagen\";\n } else {\n const openaiReq = body as OpenAIImageRequest;\n prompt = openaiReq.prompt ?? \"\";\n model = openaiReq.model ?? \"dall-e-3\";\n }\n } catch (parseErr) {\n const detail = parseErr instanceof Error ? parseErr.message : \"unknown\";\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: {\n message: `Malformed JSON: ${detail}`,\n type: \"invalid_request_error\",\n code: \"invalid_json\",\n },\n }),\n );\n return;\n }\n\n if (!prompt) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Missing required parameter: 'prompt'\", type: \"invalid_request_error\" },\n }),\n );\n return;\n }\n\n const syntheticReq = buildSyntheticRequest(model, prompt, getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n format === \"gemini\" ? \"gemini\" : (recordProviderKey ?? \"openai\"),\n req.url ?? \"/v1/images/generations\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n // Normalize to array of image items\n const items = response.images ?? (response.image ? [response.image] : []);\n\n if (format === \"gemini\") {\n const predictions = items.map((item) => ({\n bytesBase64Encoded: item.b64Json ?? \"\",\n mimeType: \"image/png\" as const,\n }));\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ predictions }));\n } else {\n serializeOpenAIImageResponse(res, items);\n }\n}\n\n/**\n * Write the standard OpenAI image response envelope (`{ created, data }`).\n * Shared by generations, edit, and variations endpoints.\n */\nfunction serializeOpenAIImageResponse(\n res: http.ServerResponse,\n items: Array<{ url?: string; b64Json?: string; revisedPrompt?: string }>,\n): void {\n const data = items.map((item) => {\n const entry: Record<string, string> = {};\n if (item.url) entry.url = item.url;\n if (item.b64Json) entry.b64_json = item.b64Json;\n if (item.revisedPrompt) entry.revised_prompt = item.revisedPrompt;\n return entry;\n });\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ created: Math.floor(Date.now() / 1000), data }));\n}\n\n/**\n * Handle POST /v1/images/edits — OpenAI Image Edit API.\n *\n * Request uses multipart/form-data. We extract text fields (`prompt`, `model`,\n * `n`, `size`, `response_format`) and ignore binary fields (`image`, `mask`)\n * since aimock doesn't process actual image data.\n *\n * The response envelope is identical to /v1/images/generations.\n */\nexport async function handleImageEdit(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/edits\";\n const method = req.method ?? \"POST\";\n\n const contentType = Array.isArray(req.headers[\"content-type\"])\n ? req.headers[\"content-type\"][0]\n : req.headers[\"content-type\"];\n const boundary = extractBoundary(contentType);\n\n const prompt = extractFormField(raw, \"prompt\", boundary) ?? \"\";\n const model = extractFormField(raw, \"model\", boundary) ?? \"dall-e-2\";\n\n if (!prompt) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: null,\n response: { status: 400, fixture: null },\n });\n writeErrorResponse(\n res,\n 400,\n JSON.stringify({\n error: { message: \"Missing required parameter: 'prompt'\", type: \"invalid_request_error\" },\n }),\n );\n return;\n }\n\n const syntheticReq = buildSyntheticRequest(model, prompt, getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/images/edits\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const items = response.images ?? (response.image ? [response.image] : []);\n serializeOpenAIImageResponse(res, items);\n}\n\n/**\n * Handle POST /v1/images/variations — OpenAI Image Variations API.\n *\n * Request uses multipart/form-data. We extract text fields (`model`, `n`,\n * `size`, `response_format`) and ignore the binary `image` field.\n * Unlike edit, no `prompt` field is required.\n *\n * The response envelope is identical to /v1/images/generations.\n */\nexport async function handleImageVariations(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n raw: string,\n fixtures: Fixture[],\n journal: Journal,\n defaults: HandlerDefaults,\n setCorsHeaders: (res: http.ServerResponse) => void,\n): Promise<void> {\n setCorsHeaders(res);\n const path = req.url ?? \"/v1/images/variations\";\n const method = req.method ?? \"POST\";\n\n const contentType = Array.isArray(req.headers[\"content-type\"])\n ? req.headers[\"content-type\"][0]\n : req.headers[\"content-type\"];\n const boundary = extractBoundary(contentType);\n\n const model = extractFormField(raw, \"model\", boundary) ?? \"dall-e-2\";\n\n // Variations don't have a prompt — use a synthetic placeholder for fixture matching\n const syntheticReq = buildSyntheticRequest(model, \"[variation]\", getContext(req));\n const testId = getTestId(req);\n const { fixture, skippedBySequenceOrTurn } = matchFixtureDiagnostic(\n fixtures,\n syntheticReq,\n journal.getFixtureMatchCountsForTest(testId),\n defaults.requestTransform,\n );\n\n if (fixture) {\n journal.incrementFixtureMatchCount(fixture, fixtures, testId);\n defaults.logger.debug(`Fixture matched: ${JSON.stringify(fixture.match).slice(0, 120)}`);\n } else {\n defaults.logger.debug(`No fixture matched for request`);\n }\n\n if (\n applyChaos(\n res,\n fixture,\n defaults.chaos,\n req.headers,\n journal,\n { method, path, headers: flattenHeaders(req.headers), body: syntheticReq },\n fixture ? \"fixture\" : \"proxy\",\n defaults.registry,\n defaults.logger,\n )\n )\n return;\n\n if (!fixture) {\n const effectiveStrict = resolveStrictMode(defaults.strict, req.headers);\n if (effectiveStrict) {\n const strictMessage = strictNoMatchMessage(skippedBySequenceOrTurn);\n defaults.logger.error(strictNoMatchLogLine(method, path, skippedBySequenceOrTurn));\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 503,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 503,\n JSON.stringify({\n error: {\n message: strictMessage,\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n if (defaults.record) {\n const outcome = await proxyAndRecord(\n req,\n res,\n syntheticReq,\n \"openai\",\n req.url ?? \"/v1/images/variations\",\n fixtures,\n defaults,\n raw,\n );\n if (outcome === \"handled_by_hook\") return;\n if (outcome !== \"not_configured\") {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: res.statusCode ?? 200, fixture: null, source: \"proxy\" },\n });\n return;\n }\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: {\n status: 404,\n fixture: null,\n ...strictOverrideField(defaults.strict, req.headers),\n },\n });\n writeErrorResponse(\n res,\n 404,\n JSON.stringify({\n error: {\n message: \"No fixture matched\",\n type: \"invalid_request_error\",\n code: \"no_fixture_match\",\n },\n }),\n );\n return;\n }\n\n const response = await resolveResponse(fixture, syntheticReq);\n\n if (isErrorResponse(response)) {\n const status = response.status ?? 500;\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status, fixture },\n });\n writeErrorResponse(res, status, serializeErrorResponse(response), {\n retryAfter: response.retryAfter,\n });\n return;\n }\n\n if (!isImageResponse(response)) {\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 500, fixture },\n });\n writeErrorResponse(\n res,\n 500,\n JSON.stringify({\n error: { message: \"Fixture response is not an image type\", type: \"server_error\" },\n }),\n );\n return;\n }\n\n journal.add({\n method,\n path,\n headers: flattenHeaders(req.headers),\n body: syntheticReq,\n response: { status: 200, fixture },\n });\n\n const items = response.images ?? (response.image ? [response.image] : []);\n serializeOpenAIImageResponse(res, items);\n}\n"],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ const require_fal = require('./fal.cjs');
|
|
|
33
33
|
const require_openrouter_video = require('./openrouter-video.cjs');
|
|
34
34
|
const require_veo_video = require('./veo-video.cjs');
|
|
35
35
|
const require_grok_video = require('./grok-video.cjs');
|
|
36
|
+
const require_byteplus_video = require('./byteplus-video.cjs');
|
|
36
37
|
const require_elevenlabs_audio = require('./elevenlabs-audio.cjs');
|
|
37
38
|
const require_ndjson_writer = require('./ndjson-writer.cjs');
|
|
38
39
|
const require_ollama = require('./ollama.cjs');
|
|
@@ -55,6 +56,9 @@ const require_suite = require('./suite.cjs');
|
|
|
55
56
|
exports.A2AMock = require_a2a_mock.A2AMock;
|
|
56
57
|
exports.AGUIMock = require_agui_mock.AGUIMock;
|
|
57
58
|
exports.AGUI_RECORD_BUFFER_HARD_CEILING = require_agui_recorder.AGUI_RECORD_BUFFER_HARD_CEILING;
|
|
59
|
+
exports.BYTEPLUS_VIDEO_MAX_ENTRIES = require_byteplus_video.BYTEPLUS_VIDEO_MAX_ENTRIES;
|
|
60
|
+
exports.BYTEPLUS_VIDEO_TASKS_PATH = require_byteplus_video.BYTEPLUS_VIDEO_TASKS_PATH;
|
|
61
|
+
exports.BytePlusVideoJobMap = require_byteplus_video.BytePlusVideoJobMap;
|
|
58
62
|
exports.DEFAULT_AGUI_RECORD_BUFFER_BYTES = require_agui_recorder.DEFAULT_AGUI_RECORD_BUFFER_BYTES;
|
|
59
63
|
exports.DEFAULT_TEST_ID = require_constants.DEFAULT_TEST_ID;
|
|
60
64
|
exports.FORMAT_TO_CONTENT_TYPE = require_helpers.FORMAT_TO_CONTENT_TYPE;
|
|
@@ -93,6 +97,7 @@ exports.buildAGUITextChunkResponse = require_agui_handler.buildTextChunkResponse
|
|
|
93
97
|
exports.buildAGUITextResponse = require_agui_handler.buildTextResponse;
|
|
94
98
|
exports.buildAGUIToolCallChunk = require_agui_handler.buildToolCallChunk;
|
|
95
99
|
exports.buildAGUIToolCallResponse = require_agui_handler.buildToolCallResponse;
|
|
100
|
+
exports.buildBytePlusMatchText = require_byteplus_video.buildBytePlusMatchText;
|
|
96
101
|
exports.buildContentWithToolCallsChunks = require_helpers.buildContentWithToolCallsChunks;
|
|
97
102
|
exports.buildContentWithToolCallsCompletion = require_helpers.buildContentWithToolCallsCompletion;
|
|
98
103
|
exports.buildContentWithToolCallsStreamEvents = require_responses.buildContentWithToolCallsStreamEvents;
|
|
@@ -139,6 +144,8 @@ exports.getAGUILastMessageIfToolResult = require_agui_handler.getLastMessageIfTo
|
|
|
139
144
|
exports.getTextContent = require_router.getTextContent;
|
|
140
145
|
exports.handleBedrock = require_bedrock.handleBedrock;
|
|
141
146
|
exports.handleBedrockStream = require_bedrock.handleBedrockStream;
|
|
147
|
+
exports.handleBytePlusVideoCreate = require_byteplus_video.handleBytePlusVideoCreate;
|
|
148
|
+
exports.handleBytePlusVideoStatus = require_byteplus_video.handleBytePlusVideoStatus;
|
|
142
149
|
exports.handleCohere = require_cohere.handleCohere;
|
|
143
150
|
exports.handleConverse = require_bedrock_converse.handleConverse;
|
|
144
151
|
exports.handleConverseStream = require_bedrock_converse.handleConverseStream;
|
package/dist/index.d.cts
CHANGED
|
@@ -20,6 +20,7 @@ import { VideoStateMap, handleVideoCreate, handleVideoStatus } from "./video.cjs
|
|
|
20
20
|
import { OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus } from "./openrouter-video.cjs";
|
|
21
21
|
import { VEO_VIDEO_MAX_ENTRIES, VeoVideoJobMap, handleVeoVideoCreate, handleVeoVideoStatus } from "./veo-video.cjs";
|
|
22
22
|
import { GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, handleGrokVideoCreate, handleGrokVideoStatus } from "./grok-video.cjs";
|
|
23
|
+
import { BYTEPLUS_VIDEO_MAX_ENTRIES, BYTEPLUS_VIDEO_TASKS_PATH, BytePlusVideoJobMap, buildBytePlusMatchText, handleBytePlusVideoCreate, handleBytePlusVideoStatus } from "./byteplus-video.cjs";
|
|
23
24
|
import { ServerInstance, ServiceFixtures, createServer } from "./server.cjs";
|
|
24
25
|
import { ValidationResult, loadFixtureFile, loadFixturesFromDir, normalizeResponse, validateFixtures } from "./fixture-loader.cjs";
|
|
25
26
|
import { MatchFixtureDiagnostic, getTextContent, matchFixture, matchFixtureDiagnostic } from "./router.cjs";
|
|
@@ -55,4 +56,4 @@ import { MCPMock } from "./mcp-mock.cjs";
|
|
|
55
56
|
import { VectorMock } from "./vector-mock.cjs";
|
|
56
57
|
import { JsonRpcDispatcherOptions, JsonRpcResponse, MethodHandler, createJsonRpcDispatcher } from "./jsonrpc.cjs";
|
|
57
58
|
import { MockSuite, MockSuiteOptions, createMockSuite } from "./suite.cjs";
|
|
58
|
-
export { type A2AAgentDefinition, type A2AArtifact, type A2AMessage, A2AMock, type A2AMockOptions, type A2APart, type A2ARole, type A2AStreamEvent, type A2ATask, type A2ATaskResponse, type A2ATaskState, type AGUIActivityDeltaEvent, type AGUIActivitySnapshotEvent, type AGUIBaseEvent, type AGUIBuildOpts, type AGUICustomEvent, type AGUIEvent, type AGUIEventType, type AGUIFixture, type AGUIFixtureMatch, type AGUIInterrupt, type AGUIMessage, type AGUIMessageContentPart, type AGUIMessageRole, type AGUIMessagesSnapshotEvent, AGUIMock, type AGUIMockOptions, type AGUIRawEvent, type AGUIReasoningEncryptedValueEvent, type AGUIReasoningEncryptedValueSubtype, type AGUIReasoningEndEvent, type AGUIReasoningMessageChunkEvent, type AGUIReasoningMessageContentEvent, type AGUIReasoningMessageEndEvent, type AGUIReasoningMessageStartEvent, type AGUIReasoningStartEvent, type AGUIRecordConfig, type AGUIResumeEntry, type AGUIRunAgentInput, type AGUIRunErrorEvent, type AGUIRunFinishedEvent, type AGUIRunFinishedOutcome, type AGUIRunStartedEvent, type AGUIStateDeltaEvent, type AGUIStateSnapshotEvent, type AGUIStepFinishedEvent, type AGUIStepStartedEvent, type AGUISubagentErrorEvent, type AGUISubagentFinishedEvent, type AGUISubagentFinishedOutcome, type AGUISubagentStartedEvent, type AGUITextMessageChunkEvent, type AGUITextMessageContentEvent, type AGUITextMessageEndEvent, type AGUITextMessageRole, type AGUITextMessageStartEvent, type AGUIThinkingEndEvent, type AGUIThinkingStartEvent, type AGUIThinkingTextMessageContentEvent, type AGUIThinkingTextMessageEndEvent, type AGUIThinkingTextMessageStartEvent, type AGUITokenUsage, type AGUIToolCall, type AGUIToolCallArgsEvent, type AGUIToolCallChunkEvent, type AGUIToolCallEndEvent, type AGUIToolCallResultEvent, type AGUIToolCallStartEvent, type AGUIToolDefinition, AGUI_RECORD_BUFFER_HARD_CEILING, type AimockConfig, type ApiKeyAuthConfig, type AudioResponse, type ChaosAction, type ChaosConfig, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionMessage, type ChatCompletionRequest, type ChatMessage, type CollapseResult, type ContentPart, type ContentWithToolCallsResponse, DEFAULT_AGUI_RECORD_BUFFER_BYTES, DEFAULT_TEST_ID, type EmbeddingAPIResponse, type EmbeddingFixtureOpts, type EmbeddingResponse, type ErrorResponse, type ErrorResponseOptions, FORMAT_TO_CONTENT_TYPE, FalQueueStateMap, type Fixture, type FixtureBlock, type FixtureFile, type FixtureFileContentWithToolCallsResponse, type FixtureFileEntry, type FixtureFileResponse, type FixtureFileTextResponse, type FixtureFileToolCall, type FixtureFileToolCallResponse, type FixtureMatch, type FixtureOpts, type FixtureResponse, GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, type ImageItem, type ImageResponse, type InterruptionControl, Journal, type JournalEntry, type JsonRpcDispatcherOptions, type JsonRpcResponse, LLMock, type LogLevel, Logger, MAX_COLLAPSE_STRING_LENGTH, type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition, type MatchFixtureDiagnostic, type MethodHandler, type MetricsRegistry, type MockServerOptions, type MockSuite, type MockSuiteOptions, type ModerationFixture, type ModerationResult, type Mountable, type NDJSONStreamOptions, OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, type QueryHandler, type QueryResult, type RawJSONResponse, type RecordConfig, type RecordProviderKey, type RerankFixture, type RerankResult, type ResponseOverrides, type ResponsesSSEEvent, type SSEChoice, type SSEChunk, type SSEDelta, type SSEToolCallDelta, type SearchFixture, type SearchResult, type ServerInstance, type ServiceFixtures, type StreamOptions, type StreamingProfile, type TextResponse, type ToolCall, type ToolCallMessage, type ToolCallResponse, type ToolDefinition, type TranscriptionResponse, VEO_VIDEO_MAX_ENTRIES, type ValidationResult, type VectorCollection, type VectorEntry, VectorMock, type VectorMockOptions, type VectorQuery, VeoVideoJobMap, type VideoResponse, VideoStateMap, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildActivityDelta as buildAGUIActivityDelta, buildActivityResponse as buildAGUIActivityResponse, buildCompositeResponse as buildAGUICompositeResponse, buildCustomEvent as buildAGUICustomEvent, buildErrorResponse as buildAGUIErrorResponse, buildMessagesSnapshot as buildAGUIMessagesSnapshot, buildRawEvent as buildAGUIRawEvent, buildReasoningChunk as buildAGUIReasoningChunk, buildReasoningEncryptedValue as buildAGUIReasoningEncryptedValue, buildReasoningResponse as buildAGUIReasoningResponse, buildStateDelta as buildAGUIStateDelta, buildStateUpdate as buildAGUIStateUpdate, buildStepWithText as buildAGUIStepWithText, buildTextChunkResponse as buildAGUITextChunkResponse, buildTextResponse as buildAGUITextResponse, buildToolCallChunk as buildAGUIToolCallChunk, buildToolCallResponse as buildAGUIToolCallResponse, buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildContentWithToolCallsStreamEvents, buildEmbeddingResponse, buildTextChunks, buildTextCompletion, buildTextStreamEvents, buildToolCallChunks, buildToolCallCompletion, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, extractLastUserMessage as extractAGUILastUserMessage, extractOverrides, findFixture as findAGUIFixture, flattenHeaders, formatToMime, geminiInteractionsToCompletionRequest, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getLastMessageIfToolResult as getAGUILastMessageIfToolResult, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleElevenLabsAudio, handleEmbeddings, handleFal, handleFalQueue, handleGemini, handleGeminiInteractions, handleGrokVideoCreate, handleGrokVideoStatus, handleImages, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus, handleRerank, handleResponses, handleSearch, handleSpeech, handleTranscription, handleVeoVideoCreate, handleVeoVideoStatus, handleVideoCreate, handleVideoStatus, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isAudioResponse, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isImageResponse, isTextResponse, isToolCallResponse, isTranscriptionResponse, isVideoResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, matchFixtureDiagnostic, matchesFixture as matchesAGUIFixture, normalizePathLabel, normalizeResponse, ollamaToCompletionRequest, proxyAndRecord, proxyAndRecordAGUI, resolveFixtureBlocks, resolveUpstreamUrl, setAGUIRecordBufferCeilingForTests, setCollapseStringLimitForTests, startFromConfig, strictNoMatchLogLine, strictNoMatchMessage, upgradeToWebSocket, validateFixtures, writeAGUIEventStream, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
|
|
59
|
+
export { type A2AAgentDefinition, type A2AArtifact, type A2AMessage, A2AMock, type A2AMockOptions, type A2APart, type A2ARole, type A2AStreamEvent, type A2ATask, type A2ATaskResponse, type A2ATaskState, type AGUIActivityDeltaEvent, type AGUIActivitySnapshotEvent, type AGUIBaseEvent, type AGUIBuildOpts, type AGUICustomEvent, type AGUIEvent, type AGUIEventType, type AGUIFixture, type AGUIFixtureMatch, type AGUIInterrupt, type AGUIMessage, type AGUIMessageContentPart, type AGUIMessageRole, type AGUIMessagesSnapshotEvent, AGUIMock, type AGUIMockOptions, type AGUIRawEvent, type AGUIReasoningEncryptedValueEvent, type AGUIReasoningEncryptedValueSubtype, type AGUIReasoningEndEvent, type AGUIReasoningMessageChunkEvent, type AGUIReasoningMessageContentEvent, type AGUIReasoningMessageEndEvent, type AGUIReasoningMessageStartEvent, type AGUIReasoningStartEvent, type AGUIRecordConfig, type AGUIResumeEntry, type AGUIRunAgentInput, type AGUIRunErrorEvent, type AGUIRunFinishedEvent, type AGUIRunFinishedOutcome, type AGUIRunStartedEvent, type AGUIStateDeltaEvent, type AGUIStateSnapshotEvent, type AGUIStepFinishedEvent, type AGUIStepStartedEvent, type AGUISubagentErrorEvent, type AGUISubagentFinishedEvent, type AGUISubagentFinishedOutcome, type AGUISubagentStartedEvent, type AGUITextMessageChunkEvent, type AGUITextMessageContentEvent, type AGUITextMessageEndEvent, type AGUITextMessageRole, type AGUITextMessageStartEvent, type AGUIThinkingEndEvent, type AGUIThinkingStartEvent, type AGUIThinkingTextMessageContentEvent, type AGUIThinkingTextMessageEndEvent, type AGUIThinkingTextMessageStartEvent, type AGUITokenUsage, type AGUIToolCall, type AGUIToolCallArgsEvent, type AGUIToolCallChunkEvent, type AGUIToolCallEndEvent, type AGUIToolCallResultEvent, type AGUIToolCallStartEvent, type AGUIToolDefinition, AGUI_RECORD_BUFFER_HARD_CEILING, type AimockConfig, type ApiKeyAuthConfig, type AudioResponse, BYTEPLUS_VIDEO_MAX_ENTRIES, BYTEPLUS_VIDEO_TASKS_PATH, BytePlusVideoJobMap, type ChaosAction, type ChaosConfig, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionMessage, type ChatCompletionRequest, type ChatMessage, type CollapseResult, type ContentPart, type ContentWithToolCallsResponse, DEFAULT_AGUI_RECORD_BUFFER_BYTES, DEFAULT_TEST_ID, type EmbeddingAPIResponse, type EmbeddingFixtureOpts, type EmbeddingResponse, type ErrorResponse, type ErrorResponseOptions, FORMAT_TO_CONTENT_TYPE, FalQueueStateMap, type Fixture, type FixtureBlock, type FixtureFile, type FixtureFileContentWithToolCallsResponse, type FixtureFileEntry, type FixtureFileResponse, type FixtureFileTextResponse, type FixtureFileToolCall, type FixtureFileToolCallResponse, type FixtureMatch, type FixtureOpts, type FixtureResponse, GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, type ImageItem, type ImageResponse, type InterruptionControl, Journal, type JournalEntry, type JsonRpcDispatcherOptions, type JsonRpcResponse, LLMock, type LogLevel, Logger, MAX_COLLAPSE_STRING_LENGTH, type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition, type MatchFixtureDiagnostic, type MethodHandler, type MetricsRegistry, type MockServerOptions, type MockSuite, type MockSuiteOptions, type ModerationFixture, type ModerationResult, type Mountable, type NDJSONStreamOptions, OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, type QueryHandler, type QueryResult, type RawJSONResponse, type RecordConfig, type RecordProviderKey, type RerankFixture, type RerankResult, type ResponseOverrides, type ResponsesSSEEvent, type SSEChoice, type SSEChunk, type SSEDelta, type SSEToolCallDelta, type SearchFixture, type SearchResult, type ServerInstance, type ServiceFixtures, type StreamOptions, type StreamingProfile, type TextResponse, type ToolCall, type ToolCallMessage, type ToolCallResponse, type ToolDefinition, type TranscriptionResponse, VEO_VIDEO_MAX_ENTRIES, type ValidationResult, type VectorCollection, type VectorEntry, VectorMock, type VectorMockOptions, type VectorQuery, VeoVideoJobMap, type VideoResponse, VideoStateMap, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildActivityDelta as buildAGUIActivityDelta, buildActivityResponse as buildAGUIActivityResponse, buildCompositeResponse as buildAGUICompositeResponse, buildCustomEvent as buildAGUICustomEvent, buildErrorResponse as buildAGUIErrorResponse, buildMessagesSnapshot as buildAGUIMessagesSnapshot, buildRawEvent as buildAGUIRawEvent, buildReasoningChunk as buildAGUIReasoningChunk, buildReasoningEncryptedValue as buildAGUIReasoningEncryptedValue, buildReasoningResponse as buildAGUIReasoningResponse, buildStateDelta as buildAGUIStateDelta, buildStateUpdate as buildAGUIStateUpdate, buildStepWithText as buildAGUIStepWithText, buildTextChunkResponse as buildAGUITextChunkResponse, buildTextResponse as buildAGUITextResponse, buildToolCallChunk as buildAGUIToolCallChunk, buildToolCallResponse as buildAGUIToolCallResponse, buildBytePlusMatchText, buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildContentWithToolCallsStreamEvents, buildEmbeddingResponse, buildTextChunks, buildTextCompletion, buildTextStreamEvents, buildToolCallChunks, buildToolCallCompletion, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, extractLastUserMessage as extractAGUILastUserMessage, extractOverrides, findFixture as findAGUIFixture, flattenHeaders, formatToMime, geminiInteractionsToCompletionRequest, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getLastMessageIfToolResult as getAGUILastMessageIfToolResult, getTextContent, handleBedrock, handleBedrockStream, handleBytePlusVideoCreate, handleBytePlusVideoStatus, handleCohere, handleConverse, handleConverseStream, handleElevenLabsAudio, handleEmbeddings, handleFal, handleFalQueue, handleGemini, handleGeminiInteractions, handleGrokVideoCreate, handleGrokVideoStatus, handleImages, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus, handleRerank, handleResponses, handleSearch, handleSpeech, handleTranscription, handleVeoVideoCreate, handleVeoVideoStatus, handleVideoCreate, handleVideoStatus, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isAudioResponse, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isImageResponse, isTextResponse, isToolCallResponse, isTranscriptionResponse, isVideoResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, matchFixtureDiagnostic, matchesFixture as matchesAGUIFixture, normalizePathLabel, normalizeResponse, ollamaToCompletionRequest, proxyAndRecord, proxyAndRecordAGUI, resolveFixtureBlocks, resolveUpstreamUrl, setAGUIRecordBufferCeilingForTests, setCollapseStringLimitForTests, startFromConfig, strictNoMatchLogLine, strictNoMatchMessage, upgradeToWebSocket, validateFixtures, writeAGUIEventStream, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { VideoStateMap, handleVideoCreate, handleVideoStatus } from "./video.js"
|
|
|
20
20
|
import { OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus } from "./openrouter-video.js";
|
|
21
21
|
import { VEO_VIDEO_MAX_ENTRIES, VeoVideoJobMap, handleVeoVideoCreate, handleVeoVideoStatus } from "./veo-video.js";
|
|
22
22
|
import { GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, handleGrokVideoCreate, handleGrokVideoStatus } from "./grok-video.js";
|
|
23
|
+
import { BYTEPLUS_VIDEO_MAX_ENTRIES, BYTEPLUS_VIDEO_TASKS_PATH, BytePlusVideoJobMap, buildBytePlusMatchText, handleBytePlusVideoCreate, handleBytePlusVideoStatus } from "./byteplus-video.js";
|
|
23
24
|
import { ServerInstance, ServiceFixtures, createServer } from "./server.js";
|
|
24
25
|
import { ValidationResult, loadFixtureFile, loadFixturesFromDir, normalizeResponse, validateFixtures } from "./fixture-loader.js";
|
|
25
26
|
import { MatchFixtureDiagnostic, getTextContent, matchFixture, matchFixtureDiagnostic } from "./router.js";
|
|
@@ -55,4 +56,4 @@ import { MCPMock } from "./mcp-mock.js";
|
|
|
55
56
|
import { VectorMock } from "./vector-mock.js";
|
|
56
57
|
import { JsonRpcDispatcherOptions, JsonRpcResponse, MethodHandler, createJsonRpcDispatcher } from "./jsonrpc.js";
|
|
57
58
|
import { MockSuite, MockSuiteOptions, createMockSuite } from "./suite.js";
|
|
58
|
-
export { type A2AAgentDefinition, type A2AArtifact, type A2AMessage, A2AMock, type A2AMockOptions, type A2APart, type A2ARole, type A2AStreamEvent, type A2ATask, type A2ATaskResponse, type A2ATaskState, type AGUIActivityDeltaEvent, type AGUIActivitySnapshotEvent, type AGUIBaseEvent, type AGUIBuildOpts, type AGUICustomEvent, type AGUIEvent, type AGUIEventType, type AGUIFixture, type AGUIFixtureMatch, type AGUIInterrupt, type AGUIMessage, type AGUIMessageContentPart, type AGUIMessageRole, type AGUIMessagesSnapshotEvent, AGUIMock, type AGUIMockOptions, type AGUIRawEvent, type AGUIReasoningEncryptedValueEvent, type AGUIReasoningEncryptedValueSubtype, type AGUIReasoningEndEvent, type AGUIReasoningMessageChunkEvent, type AGUIReasoningMessageContentEvent, type AGUIReasoningMessageEndEvent, type AGUIReasoningMessageStartEvent, type AGUIReasoningStartEvent, type AGUIRecordConfig, type AGUIResumeEntry, type AGUIRunAgentInput, type AGUIRunErrorEvent, type AGUIRunFinishedEvent, type AGUIRunFinishedOutcome, type AGUIRunStartedEvent, type AGUIStateDeltaEvent, type AGUIStateSnapshotEvent, type AGUIStepFinishedEvent, type AGUIStepStartedEvent, type AGUISubagentErrorEvent, type AGUISubagentFinishedEvent, type AGUISubagentFinishedOutcome, type AGUISubagentStartedEvent, type AGUITextMessageChunkEvent, type AGUITextMessageContentEvent, type AGUITextMessageEndEvent, type AGUITextMessageRole, type AGUITextMessageStartEvent, type AGUIThinkingEndEvent, type AGUIThinkingStartEvent, type AGUIThinkingTextMessageContentEvent, type AGUIThinkingTextMessageEndEvent, type AGUIThinkingTextMessageStartEvent, type AGUITokenUsage, type AGUIToolCall, type AGUIToolCallArgsEvent, type AGUIToolCallChunkEvent, type AGUIToolCallEndEvent, type AGUIToolCallResultEvent, type AGUIToolCallStartEvent, type AGUIToolDefinition, AGUI_RECORD_BUFFER_HARD_CEILING, type AimockConfig, type ApiKeyAuthConfig, type AudioResponse, type ChaosAction, type ChaosConfig, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionMessage, type ChatCompletionRequest, type ChatMessage, type CollapseResult, type ContentPart, type ContentWithToolCallsResponse, DEFAULT_AGUI_RECORD_BUFFER_BYTES, DEFAULT_TEST_ID, type EmbeddingAPIResponse, type EmbeddingFixtureOpts, type EmbeddingResponse, type ErrorResponse, type ErrorResponseOptions, FORMAT_TO_CONTENT_TYPE, FalQueueStateMap, type Fixture, type FixtureBlock, type FixtureFile, type FixtureFileContentWithToolCallsResponse, type FixtureFileEntry, type FixtureFileResponse, type FixtureFileTextResponse, type FixtureFileToolCall, type FixtureFileToolCallResponse, type FixtureMatch, type FixtureOpts, type FixtureResponse, GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, type ImageItem, type ImageResponse, type InterruptionControl, Journal, type JournalEntry, type JsonRpcDispatcherOptions, type JsonRpcResponse, LLMock, type LogLevel, Logger, MAX_COLLAPSE_STRING_LENGTH, type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition, type MatchFixtureDiagnostic, type MethodHandler, type MetricsRegistry, type MockServerOptions, type MockSuite, type MockSuiteOptions, type ModerationFixture, type ModerationResult, type Mountable, type NDJSONStreamOptions, OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, type QueryHandler, type QueryResult, type RawJSONResponse, type RecordConfig, type RecordProviderKey, type RerankFixture, type RerankResult, type ResponseOverrides, type ResponsesSSEEvent, type SSEChoice, type SSEChunk, type SSEDelta, type SSEToolCallDelta, type SearchFixture, type SearchResult, type ServerInstance, type ServiceFixtures, type StreamOptions, type StreamingProfile, type TextResponse, type ToolCall, type ToolCallMessage, type ToolCallResponse, type ToolDefinition, type TranscriptionResponse, VEO_VIDEO_MAX_ENTRIES, type ValidationResult, type VectorCollection, type VectorEntry, VectorMock, type VectorMockOptions, type VectorQuery, VeoVideoJobMap, type VideoResponse, VideoStateMap, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildActivityDelta as buildAGUIActivityDelta, buildActivityResponse as buildAGUIActivityResponse, buildCompositeResponse as buildAGUICompositeResponse, buildCustomEvent as buildAGUICustomEvent, buildErrorResponse as buildAGUIErrorResponse, buildMessagesSnapshot as buildAGUIMessagesSnapshot, buildRawEvent as buildAGUIRawEvent, buildReasoningChunk as buildAGUIReasoningChunk, buildReasoningEncryptedValue as buildAGUIReasoningEncryptedValue, buildReasoningResponse as buildAGUIReasoningResponse, buildStateDelta as buildAGUIStateDelta, buildStateUpdate as buildAGUIStateUpdate, buildStepWithText as buildAGUIStepWithText, buildTextChunkResponse as buildAGUITextChunkResponse, buildTextResponse as buildAGUITextResponse, buildToolCallChunk as buildAGUIToolCallChunk, buildToolCallResponse as buildAGUIToolCallResponse, buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildContentWithToolCallsStreamEvents, buildEmbeddingResponse, buildTextChunks, buildTextCompletion, buildTextStreamEvents, buildToolCallChunks, buildToolCallCompletion, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, extractLastUserMessage as extractAGUILastUserMessage, extractOverrides, findFixture as findAGUIFixture, flattenHeaders, formatToMime, geminiInteractionsToCompletionRequest, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getLastMessageIfToolResult as getAGUILastMessageIfToolResult, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleElevenLabsAudio, handleEmbeddings, handleFal, handleFalQueue, handleGemini, handleGeminiInteractions, handleGrokVideoCreate, handleGrokVideoStatus, handleImages, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus, handleRerank, handleResponses, handleSearch, handleSpeech, handleTranscription, handleVeoVideoCreate, handleVeoVideoStatus, handleVideoCreate, handleVideoStatus, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isAudioResponse, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isImageResponse, isTextResponse, isToolCallResponse, isTranscriptionResponse, isVideoResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, matchFixtureDiagnostic, matchesFixture as matchesAGUIFixture, normalizePathLabel, normalizeResponse, ollamaToCompletionRequest, proxyAndRecord, proxyAndRecordAGUI, resolveFixtureBlocks, resolveUpstreamUrl, setAGUIRecordBufferCeilingForTests, setCollapseStringLimitForTests, startFromConfig, strictNoMatchLogLine, strictNoMatchMessage, upgradeToWebSocket, validateFixtures, writeAGUIEventStream, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
|
|
59
|
+
export { type A2AAgentDefinition, type A2AArtifact, type A2AMessage, A2AMock, type A2AMockOptions, type A2APart, type A2ARole, type A2AStreamEvent, type A2ATask, type A2ATaskResponse, type A2ATaskState, type AGUIActivityDeltaEvent, type AGUIActivitySnapshotEvent, type AGUIBaseEvent, type AGUIBuildOpts, type AGUICustomEvent, type AGUIEvent, type AGUIEventType, type AGUIFixture, type AGUIFixtureMatch, type AGUIInterrupt, type AGUIMessage, type AGUIMessageContentPart, type AGUIMessageRole, type AGUIMessagesSnapshotEvent, AGUIMock, type AGUIMockOptions, type AGUIRawEvent, type AGUIReasoningEncryptedValueEvent, type AGUIReasoningEncryptedValueSubtype, type AGUIReasoningEndEvent, type AGUIReasoningMessageChunkEvent, type AGUIReasoningMessageContentEvent, type AGUIReasoningMessageEndEvent, type AGUIReasoningMessageStartEvent, type AGUIReasoningStartEvent, type AGUIRecordConfig, type AGUIResumeEntry, type AGUIRunAgentInput, type AGUIRunErrorEvent, type AGUIRunFinishedEvent, type AGUIRunFinishedOutcome, type AGUIRunStartedEvent, type AGUIStateDeltaEvent, type AGUIStateSnapshotEvent, type AGUIStepFinishedEvent, type AGUIStepStartedEvent, type AGUISubagentErrorEvent, type AGUISubagentFinishedEvent, type AGUISubagentFinishedOutcome, type AGUISubagentStartedEvent, type AGUITextMessageChunkEvent, type AGUITextMessageContentEvent, type AGUITextMessageEndEvent, type AGUITextMessageRole, type AGUITextMessageStartEvent, type AGUIThinkingEndEvent, type AGUIThinkingStartEvent, type AGUIThinkingTextMessageContentEvent, type AGUIThinkingTextMessageEndEvent, type AGUIThinkingTextMessageStartEvent, type AGUITokenUsage, type AGUIToolCall, type AGUIToolCallArgsEvent, type AGUIToolCallChunkEvent, type AGUIToolCallEndEvent, type AGUIToolCallResultEvent, type AGUIToolCallStartEvent, type AGUIToolDefinition, AGUI_RECORD_BUFFER_HARD_CEILING, type AimockConfig, type ApiKeyAuthConfig, type AudioResponse, BYTEPLUS_VIDEO_MAX_ENTRIES, BYTEPLUS_VIDEO_TASKS_PATH, BytePlusVideoJobMap, type ChaosAction, type ChaosConfig, type ChatCompletion, type ChatCompletionChoice, type ChatCompletionMessage, type ChatCompletionRequest, type ChatMessage, type CollapseResult, type ContentPart, type ContentWithToolCallsResponse, DEFAULT_AGUI_RECORD_BUFFER_BYTES, DEFAULT_TEST_ID, type EmbeddingAPIResponse, type EmbeddingFixtureOpts, type EmbeddingResponse, type ErrorResponse, type ErrorResponseOptions, FORMAT_TO_CONTENT_TYPE, FalQueueStateMap, type Fixture, type FixtureBlock, type FixtureFile, type FixtureFileContentWithToolCallsResponse, type FixtureFileEntry, type FixtureFileResponse, type FixtureFileTextResponse, type FixtureFileToolCall, type FixtureFileToolCallResponse, type FixtureMatch, type FixtureOpts, type FixtureResponse, GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, type ImageItem, type ImageResponse, type InterruptionControl, Journal, type JournalEntry, type JsonRpcDispatcherOptions, type JsonRpcResponse, LLMock, type LogLevel, Logger, MAX_COLLAPSE_STRING_LENGTH, type MCPContent, MCPMock, type MCPMockOptions, type MCPPromptDefinition, type MCPPromptResult, type MCPResourceContent, type MCPResourceDefinition, type MCPSession, type MCPToolDefinition, type MatchFixtureDiagnostic, type MethodHandler, type MetricsRegistry, type MockServerOptions, type MockSuite, type MockSuiteOptions, type ModerationFixture, type ModerationResult, type Mountable, type NDJSONStreamOptions, OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, type QueryHandler, type QueryResult, type RawJSONResponse, type RecordConfig, type RecordProviderKey, type RerankFixture, type RerankResult, type ResponseOverrides, type ResponsesSSEEvent, type SSEChoice, type SSEChunk, type SSEDelta, type SSEToolCallDelta, type SearchFixture, type SearchResult, type ServerInstance, type ServiceFixtures, type StreamOptions, type StreamingProfile, type TextResponse, type ToolCall, type ToolCallMessage, type ToolCallResponse, type ToolDefinition, type TranscriptionResponse, VEO_VIDEO_MAX_ENTRIES, type ValidationResult, type VectorCollection, type VectorEntry, VectorMock, type VectorMockOptions, type VectorQuery, VeoVideoJobMap, type VideoResponse, VideoStateMap, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildActivityDelta as buildAGUIActivityDelta, buildActivityResponse as buildAGUIActivityResponse, buildCompositeResponse as buildAGUICompositeResponse, buildCustomEvent as buildAGUICustomEvent, buildErrorResponse as buildAGUIErrorResponse, buildMessagesSnapshot as buildAGUIMessagesSnapshot, buildRawEvent as buildAGUIRawEvent, buildReasoningChunk as buildAGUIReasoningChunk, buildReasoningEncryptedValue as buildAGUIReasoningEncryptedValue, buildReasoningResponse as buildAGUIReasoningResponse, buildStateDelta as buildAGUIStateDelta, buildStateUpdate as buildAGUIStateUpdate, buildStepWithText as buildAGUIStepWithText, buildTextChunkResponse as buildAGUITextChunkResponse, buildTextResponse as buildAGUITextResponse, buildToolCallChunk as buildAGUIToolCallChunk, buildToolCallResponse as buildAGUIToolCallResponse, buildBytePlusMatchText, buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildContentWithToolCallsStreamEvents, buildEmbeddingResponse, buildTextChunks, buildTextCompletion, buildTextStreamEvents, buildToolCallChunks, buildToolCallCompletion, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, extractLastUserMessage as extractAGUILastUserMessage, extractOverrides, findFixture as findAGUIFixture, flattenHeaders, formatToMime, geminiInteractionsToCompletionRequest, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getLastMessageIfToolResult as getAGUILastMessageIfToolResult, getTextContent, handleBedrock, handleBedrockStream, handleBytePlusVideoCreate, handleBytePlusVideoStatus, handleCohere, handleConverse, handleConverseStream, handleElevenLabsAudio, handleEmbeddings, handleFal, handleFalQueue, handleGemini, handleGeminiInteractions, handleGrokVideoCreate, handleGrokVideoStatus, handleImages, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus, handleRerank, handleResponses, handleSearch, handleSpeech, handleTranscription, handleVeoVideoCreate, handleVeoVideoStatus, handleVideoCreate, handleVideoStatus, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isAudioResponse, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isImageResponse, isTextResponse, isToolCallResponse, isTranscriptionResponse, isVideoResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, matchFixtureDiagnostic, matchesFixture as matchesAGUIFixture, normalizePathLabel, normalizeResponse, ollamaToCompletionRequest, proxyAndRecord, proxyAndRecordAGUI, resolveFixtureBlocks, resolveUpstreamUrl, setAGUIRecordBufferCeilingForTests, setCollapseStringLimitForTests, startFromConfig, strictNoMatchLogLine, strictNoMatchMessage, upgradeToWebSocket, validateFixtures, writeAGUIEventStream, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
|
package/dist/index.js
CHANGED
|
@@ -32,6 +32,7 @@ import { FalQueueStateMap, handleFal } from "./fal.js";
|
|
|
32
32
|
import { OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus } from "./openrouter-video.js";
|
|
33
33
|
import { VEO_VIDEO_MAX_ENTRIES, VeoVideoJobMap, handleVeoVideoCreate, handleVeoVideoStatus } from "./veo-video.js";
|
|
34
34
|
import { GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, handleGrokVideoCreate, handleGrokVideoStatus } from "./grok-video.js";
|
|
35
|
+
import { BYTEPLUS_VIDEO_MAX_ENTRIES, BYTEPLUS_VIDEO_TASKS_PATH, BytePlusVideoJobMap, buildBytePlusMatchText, handleBytePlusVideoCreate, handleBytePlusVideoStatus } from "./byteplus-video.js";
|
|
35
36
|
import { handleElevenLabsAudio } from "./elevenlabs-audio.js";
|
|
36
37
|
import { writeNDJSONStream } from "./ndjson-writer.js";
|
|
37
38
|
import { handleOllama, handleOllamaGenerate, ollamaToCompletionRequest } from "./ollama.js";
|
|
@@ -51,4 +52,4 @@ import { VectorMock } from "./vector-mock.js";
|
|
|
51
52
|
import { loadConfig, startFromConfig } from "./config-loader.js";
|
|
52
53
|
import { createMockSuite } from "./suite.js";
|
|
53
54
|
|
|
54
|
-
export { A2AMock, AGUIMock, AGUI_RECORD_BUFFER_HARD_CEILING, DEFAULT_AGUI_RECORD_BUFFER_BYTES, DEFAULT_TEST_ID, FORMAT_TO_CONTENT_TYPE, FalQueueStateMap, GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, Journal, LLMock, Logger, MAX_COLLAPSE_STRING_LENGTH, MCPMock, OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, VEO_VIDEO_MAX_ENTRIES, VectorMock, VeoVideoJobMap, VideoStateMap, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildActivityDelta as buildAGUIActivityDelta, buildActivityResponse as buildAGUIActivityResponse, buildCompositeResponse as buildAGUICompositeResponse, buildCustomEvent as buildAGUICustomEvent, buildErrorResponse as buildAGUIErrorResponse, buildMessagesSnapshot as buildAGUIMessagesSnapshot, buildRawEvent as buildAGUIRawEvent, buildReasoningChunk as buildAGUIReasoningChunk, buildReasoningEncryptedValue as buildAGUIReasoningEncryptedValue, buildReasoningResponse as buildAGUIReasoningResponse, buildStateDelta as buildAGUIStateDelta, buildStateUpdate as buildAGUIStateUpdate, buildStepWithText as buildAGUIStepWithText, buildTextChunkResponse as buildAGUITextChunkResponse, buildTextResponse as buildAGUITextResponse, buildToolCallChunk as buildAGUIToolCallChunk, buildToolCallResponse as buildAGUIToolCallResponse, buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildContentWithToolCallsStreamEvents, buildEmbeddingResponse, buildTextChunks, buildTextCompletion, buildTextStreamEvents, buildToolCallChunks, buildToolCallCompletion, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, extractLastUserMessage as extractAGUILastUserMessage, extractOverrides, findFixture as findAGUIFixture, flattenHeaders, formatToMime, geminiInteractionsToCompletionRequest, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getLastMessageIfToolResult as getAGUILastMessageIfToolResult, getTextContent, handleBedrock, handleBedrockStream, handleCohere, handleConverse, handleConverseStream, handleElevenLabsAudio, handleEmbeddings, handleFal, handleFalQueue, handleGemini, handleGeminiInteractions, handleGrokVideoCreate, handleGrokVideoStatus, handleImages, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus, handleRerank, handleResponses, handleSearch, handleSpeech, handleTranscription, handleVeoVideoCreate, handleVeoVideoStatus, handleVideoCreate, handleVideoStatus, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isAudioResponse, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isImageResponse, isTextResponse, isToolCallResponse, isTranscriptionResponse, isVideoResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, matchFixtureDiagnostic, matchesFixture as matchesAGUIFixture, normalizePathLabel, normalizeResponse, ollamaToCompletionRequest, proxyAndRecord, proxyAndRecordAGUI, resolveFixtureBlocks, resolveUpstreamUrl, setAGUIRecordBufferCeilingForTests, setCollapseStringLimitForTests, startFromConfig, strictNoMatchLogLine, strictNoMatchMessage, upgradeToWebSocket, validateFixtures, writeAGUIEventStream, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
|
|
55
|
+
export { A2AMock, AGUIMock, AGUI_RECORD_BUFFER_HARD_CEILING, BYTEPLUS_VIDEO_MAX_ENTRIES, BYTEPLUS_VIDEO_TASKS_PATH, BytePlusVideoJobMap, DEFAULT_AGUI_RECORD_BUFFER_BYTES, DEFAULT_TEST_ID, FORMAT_TO_CONTENT_TYPE, FalQueueStateMap, GROK_VIDEO_MAX_ENTRIES, GrokVideoJobMap, Journal, LLMock, Logger, MAX_COLLAPSE_STRING_LENGTH, MCPMock, OPENROUTER_VIDEO_DEFAULT_MAX_CONTENT_BYTES, OPENROUTER_VIDEO_MAX_ENTRIES, OpenRouterVideoJobMap, VEO_VIDEO_MAX_ENTRIES, VectorMock, VeoVideoJobMap, VideoStateMap, WebSocketConnection, applyChaos, bedrockToCompletionRequest, buildActivityDelta as buildAGUIActivityDelta, buildActivityResponse as buildAGUIActivityResponse, buildCompositeResponse as buildAGUICompositeResponse, buildCustomEvent as buildAGUICustomEvent, buildErrorResponse as buildAGUIErrorResponse, buildMessagesSnapshot as buildAGUIMessagesSnapshot, buildRawEvent as buildAGUIRawEvent, buildReasoningChunk as buildAGUIReasoningChunk, buildReasoningEncryptedValue as buildAGUIReasoningEncryptedValue, buildReasoningResponse as buildAGUIReasoningResponse, buildStateDelta as buildAGUIStateDelta, buildStateUpdate as buildAGUIStateUpdate, buildStepWithText as buildAGUIStepWithText, buildTextChunkResponse as buildAGUITextChunkResponse, buildTextResponse as buildAGUITextResponse, buildToolCallChunk as buildAGUIToolCallChunk, buildToolCallResponse as buildAGUIToolCallResponse, buildBytePlusMatchText, buildContentWithToolCallsChunks, buildContentWithToolCallsCompletion, buildContentWithToolCallsStreamEvents, buildEmbeddingResponse, buildTextChunks, buildTextCompletion, buildTextStreamEvents, buildToolCallChunks, buildToolCallCompletion, buildToolCallStreamEvents, calculateDelay, cohereToCompletionRequest, collapseAnthropicSSE, collapseBedrockEventStream, collapseCohereSSE, collapseGeminiInteractionsSSE, collapseGeminiSSE, collapseOllamaNDJSON, collapseOpenAISSE, collapseStreamingResponse, computeAcceptKey, converseToCompletionRequest, createInterruptionSignal, createJsonRpcDispatcher, createMetricsRegistry, createMockSuite, createServer, delay, encodeEventStreamFrame, encodeEventStreamMessage, evaluateChaos, extractLastUserMessage as extractAGUILastUserMessage, extractOverrides, findFixture as findAGUIFixture, flattenHeaders, formatToMime, geminiInteractionsToCompletionRequest, generateDeterministicEmbedding, generateId, generateMessageId, generateToolCallId, generateToolUseId, getLastMessageIfToolResult as getAGUILastMessageIfToolResult, getTextContent, handleBedrock, handleBedrockStream, handleBytePlusVideoCreate, handleBytePlusVideoStatus, handleCohere, handleConverse, handleConverseStream, handleElevenLabsAudio, handleEmbeddings, handleFal, handleFalQueue, handleGemini, handleGeminiInteractions, handleGrokVideoCreate, handleGrokVideoStatus, handleImages, handleMessages, handleModeration, handleOllama, handleOllamaGenerate, handleOpenRouterVideoContent, handleOpenRouterVideoCreate, handleOpenRouterVideoModels, handleOpenRouterVideoStatus, handleRerank, handleResponses, handleSearch, handleSpeech, handleTranscription, handleVeoVideoCreate, handleVeoVideoStatus, handleVideoCreate, handleVideoStatus, handleWebSocketGeminiLive, handleWebSocketRealtime, handleWebSocketResponses, isAudioResponse, isContentWithToolCallsResponse, isEmbeddingResponse, isErrorResponse, isImageResponse, isTextResponse, isToolCallResponse, isTranscriptionResponse, isVideoResponse, loadConfig, loadFixtureFile, loadFixturesFromDir, matchFixture, matchFixtureDiagnostic, matchesFixture as matchesAGUIFixture, normalizePathLabel, normalizeResponse, ollamaToCompletionRequest, proxyAndRecord, proxyAndRecordAGUI, resolveFixtureBlocks, resolveUpstreamUrl, setAGUIRecordBufferCeilingForTests, setCollapseStringLimitForTests, startFromConfig, strictNoMatchLogLine, strictNoMatchMessage, upgradeToWebSocket, validateFixtures, writeAGUIEventStream, writeErrorResponse, writeEventStream, writeNDJSONStream, writeSSEStream };
|
package/dist/metrics.cjs
CHANGED
|
@@ -147,6 +147,22 @@ const VEO_OPERATION_RE = /^\/v1beta\/(operations\/.+)$/;
|
|
|
147
147
|
const GROK_VIDEO_SUBMIT_PATH = "/v1/videos/generations";
|
|
148
148
|
const GROK_VIDEO_STATUS_RE = /^\/v1\/videos\/([^/]+)$/;
|
|
149
149
|
/**
|
|
150
|
+
* BytePlus Ark (Seedance) async video task routes. The `/api/v3` prefix is
|
|
151
|
+
* ENUMERATED rather than wildcarded: Ark's data-plane base carries it, but a
|
|
152
|
+
* client may point `baseURL` at a bare aimock root instead, so both forms must
|
|
153
|
+
* route. A tolerant `(?:\/[^?]*)?` prefix would additionally claim
|
|
154
|
+
* `/fal/contents/generations/tasks` — and these routes dispatch in the
|
|
155
|
+
* pre-rewrite band, ~1,100 lines ahead of every fal branch, so it would take
|
|
156
|
+
* that path away from the fal proxy. Enumerating the one real prefix also
|
|
157
|
+
* blocks a doubled suffix from matching the status RE.
|
|
158
|
+
*
|
|
159
|
+
* Declared here (not in server.ts) because normalizePathLabel below consumes
|
|
160
|
+
* them, matching the existing OpenRouter/Veo/Grok route-regex edge where
|
|
161
|
+
* server.ts imports its route regexes from this module.
|
|
162
|
+
*/
|
|
163
|
+
const BYTEPLUS_VIDEO_SUBMIT_RE = /^(?:\/api\/v3)?\/contents\/generations\/tasks$/;
|
|
164
|
+
const BYTEPLUS_VIDEO_STATUS_RE = /^(?:\/api\/v3)?\/contents\/generations\/tasks\/([^/]+)$/;
|
|
165
|
+
/**
|
|
150
166
|
* Normalize parametric API paths to route patterns for use as metric labels.
|
|
151
167
|
* Replaces dynamic segments (model IDs, deployment names, etc.) with placeholders.
|
|
152
168
|
*/
|
|
@@ -166,10 +182,14 @@ function normalizePathLabel(pathname) {
|
|
|
166
182
|
if (VEO_OPERATION_RE.test(pathname)) return "/v1beta/operations/{name}";
|
|
167
183
|
if (pathname === GROK_VIDEO_SUBMIT_PATH) return GROK_VIDEO_SUBMIT_PATH;
|
|
168
184
|
if (OPENAI_VIDEO_STATUS_RE.test(pathname)) return "/v1/videos/{id}";
|
|
185
|
+
if (BYTEPLUS_VIDEO_STATUS_RE.test(pathname)) return "/contents/generations/tasks/{id}";
|
|
186
|
+
if (BYTEPLUS_VIDEO_SUBMIT_RE.test(pathname)) return "/contents/generations/tasks";
|
|
169
187
|
return pathname;
|
|
170
188
|
}
|
|
171
189
|
|
|
172
190
|
//#endregion
|
|
191
|
+
exports.BYTEPLUS_VIDEO_STATUS_RE = BYTEPLUS_VIDEO_STATUS_RE;
|
|
192
|
+
exports.BYTEPLUS_VIDEO_SUBMIT_RE = BYTEPLUS_VIDEO_SUBMIT_RE;
|
|
173
193
|
exports.GROK_VIDEO_STATUS_RE = GROK_VIDEO_STATUS_RE;
|
|
174
194
|
exports.GROK_VIDEO_SUBMIT_PATH = GROK_VIDEO_SUBMIT_PATH;
|
|
175
195
|
exports.OPENROUTER_VIDEO_CONTENT_RE = OPENROUTER_VIDEO_CONTENT_RE;
|