repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/gratis/__tests__/router.test.ts
Rawimport {
type AssistantMessage,
type AssistantMessageEventStream,
createAssistantMessageEventStream,
type TranscriptContext,
} from "@earendil-works/pi-ai";
import { describe, expect, it } from "vitest";
import { AUTO_ID, type GratisModel, gratisModel } from "../src/catalog.ts";
import { createRouter } from "../src/router.ts";
// No module mocks: tests share a worker (isolate: false), so the router takes
// fake transports through its `apis` seam instead.
const model = gratisModel("kilo", {
id: "vendor/model:free",
name: "Model",
api: "openai-completions",
baseUrl: "https://api.kilo.ai/api/gateway",
contextWindow: 262_144,
maxTokens: 32_768,
input: ["text"],
reasoning: false,
});
const auto: GratisModel = { ...model, id: AUTO_ID };
const context = { messages: [] } as unknown as TranscriptContext;
function router(streamSimple: () => AssistantMessageEventStream) {
return createRouter({
key: () => undefined,
candidates: (backend) => (backend === "kilo" ? [model] : []),
resolveUrl: (url) => url,
apis: { "openai-completions": { stream: streamSimple, streamSimple } },
});
}
function message(stopReason: AssistantMessage["stopReason"]): AssistantMessage {
return {
role: "assistant",
content: [],
api: "openai-completions",
provider: "kilo",
model: "vendor/model:free",
usage: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
totalTokens: 0,
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
},
stopReason,
timestamp: 0,
};
}
/** Upstream that starts streaming text, then ends with the given terminal event. */
function upstreamEnding(ending: "done" | "error" | "aborted") {
return () => {
const stream = createAssistantMessageEventStream();
const partial = message("pending" as AssistantMessage["stopReason"]);
stream.push({ type: "start", partial });
partial.content.push({ type: "text", text: "thinking" });
stream.push({ type: "text_start", contentIndex: 0, partial });
if (ending === "done")
stream.push({ type: "done", reason: "stop", message: message("stop") });
else {
const failed = message(ending);
failed.errorMessage = "Provider finish_reason: content_filter";
stream.push({ type: "error", reason: ending, error: failed });
}
stream.end();
return stream;
};
}
describe("gratis router", () => {
it("turns a synchronous transport throw into a grts error message", async () => {
const result = await router(() => {
throw new Error("transport setup failed");
})
.streamSimple(model, context)
.result();
expect(result).toMatchObject({
stopReason: "error",
errorMessage: "transport setup failed",
provider: "grts",
model: "kilo/vendor/model:free",
api: "openai-completions",
});
});
for (const [route, requested] of [
["pinned", model],
["auto", auto],
] as const) {
it.each([
["error", "error"],
["aborted", "aborted"],
["done", "ok"],
] as const)(
`records a ${route} stream ending in %s as %s`,
async (ending, outcome) => {
const instance = router(upstreamEnding(ending));
await instance.streamSimple(requested, context).result();
await expect
.poll(() => instance.status().last)
.toMatchObject({ route, outcome });
},
);
}
});