Files
pikasTech-unidesk/scripts/fake-responses-provider-smoke.ts
2026-06-28 02:34:20 +00:00

81 lines
3.2 KiB
TypeScript

#!/usr/bin/env bun
// SPEC: issue-1190 fake Responses provider P1.
// Responsibility: Local protocol smoke for fake Responses provider without Docker or k3s.
import { createFakeResponsesProviderService, loadFakeResponsesProviderConfig } from "./src/fake-responses-provider-service";
const config = loadFakeResponsesProviderConfig({ ...process.env, LISTEN_HOST: "127.0.0.1" });
const service = createFakeResponsesProviderService(config);
const server = Bun.serve({ hostname: "127.0.0.1", port: 0, fetch: service.fetch });
try {
const baseUrl = server.url.href.replace(/\/$/u, "");
const health = await fetchJson(`${baseUrl}/healthz`);
const models = await fetchJson(`${baseUrl}/v1/models`);
const echo = await fetch(`${baseUrl}/v1/responses`, {
method: "POST",
headers: { "content-type": "application/json", authorization: "Bearer smoke-redacted" },
body: JSON.stringify({
model: config.modelId,
stream: true,
input: [{ role: "user", content: [{ type: "input_text", text: "ECHO sentinel-01" }] }],
}),
});
const echoText = await echo.text();
const events = parseSseEvents(echoText);
const nonEcho = await fetch(`${baseUrl}/v1/responses`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ model: config.modelId, stream: true, input: "hello" }),
});
const ok = health.ok === true
&& Array.isArray(models.data)
&& echo.ok
&& echo.headers.get("content-type")?.includes("text/event-stream") === true
&& events.some((event) => event.event === "response.output_text.delta" && event.data.delta === "sentinel-01")
&& events.some((event) => event.event === "response.completed")
&& nonEcho.status === 400;
console.log(JSON.stringify({
ok,
command: "fake-responses-provider-smoke",
baseUrl,
checks: {
health: health.ok === true,
models: Array.isArray(models.data),
echoStatus: echo.status,
echoDelta: events.find((event) => event.event === "response.output_text.delta")?.data.delta ?? null,
completed: events.some((event) => event.event === "response.completed"),
nonEchoStatus: nonEcho.status,
},
valuesPrinted: false,
}, null, 2));
process.exitCode = ok ? 0 : 1;
} finally {
server.stop(true);
}
async function fetchJson(url: string): Promise<Record<string, unknown>> {
const response = await fetch(url);
const parsed = await response.json() as unknown;
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) ? parsed as Record<string, unknown> : {};
}
function parseSseEvents(text: string): Array<{ event: string; data: Record<string, unknown> }> {
return text
.split(/\n\n/u)
.map((chunk) => chunk.trim())
.filter(Boolean)
.flatMap((chunk) => {
const event = /^event:\s*(.+)$/mu.exec(chunk)?.[1] ?? "message";
const dataLine = /^data:\s*(.+)$/mu.exec(chunk)?.[1] ?? "";
if (dataLine === "[DONE]" || dataLine.length === 0) return [];
try {
const parsed = JSON.parse(dataLine) as unknown;
return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)
? [{ event, data: parsed as Record<string, unknown> }]
: [];
} catch {
return [];
}
});
}