Files
openclaw/scripts/e2e/lib/mock-openai-http.mjs
2026-06-01 04:48:32 +02:00

98 lines
2.5 KiB
JavaScript

import { readPositiveIntEnv } from "./env-limits.mjs";
const DEFAULT_REQUEST_MAX_BYTES = 4 * 1024 * 1024;
const DEFAULT_REQUEST_LOG_BODY_MAX_BYTES = 256 * 1024;
const REQUEST_LOG_PREVIEW_CHARS = 4096;
export function readMockOpenAiHttpLimits(env = process.env) {
return {
requestMaxBytes: readPositiveIntEnv(
"OPENCLAW_MOCK_OPENAI_REQUEST_MAX_BYTES",
DEFAULT_REQUEST_MAX_BYTES,
env,
),
requestLogBodyMaxBytes: readPositiveIntEnv(
"OPENCLAW_MOCK_OPENAI_REQUEST_LOG_BODY_MAX_BYTES",
DEFAULT_REQUEST_LOG_BODY_MAX_BYTES,
env,
),
};
}
function requestBodyTooLargeError(limit) {
return Object.assign(new Error(`mock OpenAI request body exceeded ${limit} bytes`), {
code: "ETOOBIG",
});
}
export function isRequestBodyTooLargeError(error) {
return error instanceof Error && error.code === "ETOOBIG";
}
export function readBody(req, limits = readMockOpenAiHttpLimits()) {
const { requestMaxBytes } = limits;
return new Promise((resolve, reject) => {
let body = "";
let bytes = 0;
let settled = false;
req.setEncoding("utf8");
req.on("data", (chunk) => {
if (settled) {
return;
}
bytes += Buffer.byteLength(chunk, "utf8");
if (bytes > requestMaxBytes) {
settled = true;
body = "";
req.resume();
reject(requestBodyTooLargeError(requestMaxBytes));
return;
}
body += chunk;
});
req.on("end", () => {
if (!settled) {
settled = true;
resolve(body);
}
});
req.on("error", (error) => {
if (!settled) {
settled = true;
reject(error instanceof Error ? error : new Error(String(error)));
}
});
});
}
export function boundedRequestLogBody(value, bodyText, limits = readMockOpenAiHttpLimits()) {
const { requestLogBodyMaxBytes } = limits;
const byteLength = Buffer.byteLength(bodyText, "utf8");
if (byteLength <= requestLogBodyMaxBytes) {
return value;
}
return {
truncated: true,
byteLength,
preview: bodyText.slice(0, REQUEST_LOG_PREVIEW_CHARS),
};
}
export function writeJson(res, status, body) {
res.writeHead(status, { "content-type": "application/json" });
res.end(JSON.stringify(body));
}
export function writeSse(res, events) {
res.writeHead(200, {
"content-type": "text/event-stream",
"cache-control": "no-store",
connection: "keep-alive",
});
for (const event of events) {
res.write(`data: ${JSON.stringify(event)}\n\n`);
}
res.write("data: [DONE]\n\n");
res.end();
}