Files
diegosouzapw--omniroute/tests/unit/gemini-models-parser.test.ts
2026-07-13 13:39:12 +08:00

111 lines
4.3 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { parseGeminiModelsList } from "../../src/lib/providerModels/geminiModelsParser";
// A representative slice of the live generativelanguage v1beta/models response — including the
// image models (gemini-*-image via generateContent, imagen-* via predict) that the Vertex catalog
// must surface dynamically.
const SAMPLE = {
models: [
{
name: "models/gemini-2.5-flash",
displayName: "Gemini 2.5 Flash",
inputTokenLimit: 1048576,
outputTokenLimit: 65536,
supportedGenerationMethods: ["generateContent", "countTokens", "batchGenerateContent"],
thinking: true,
},
{
name: "models/gemini-3-pro-image-preview",
displayName: "Gemini 3 Pro Image Preview",
supportedGenerationMethods: ["generateContent", "countTokens"],
},
{
name: "models/imagen-4.0-generate-001",
displayName: "Imagen 4.0",
supportedGenerationMethods: ["predict"],
},
{
name: "models/text-embedding-004",
displayName: "Text Embedding 004",
supportedGenerationMethods: ["embedContent"],
},
{
name: "models/gemini-live-2.5-flash",
displayName: "Gemini Live",
supportedGenerationMethods: ["bidiGenerateContent"],
},
{
name: "models/veo-3.0-generate-001",
displayName: "Veo 3.0",
supportedGenerationMethods: ["predictLongRunning"],
},
{
// Defensive: an Imagen model exposed via a long-running method must stay
// "images", never "video".
name: "models/imagen-future-preview",
displayName: "Imagen Future",
supportedGenerationMethods: ["predictLongRunning"],
},
],
};
test("parseGeminiModelsList strips the models/ prefix and maps display name", () => {
const models = parseGeminiModelsList(SAMPLE);
const flash = models.find((m) => m.id === "gemini-2.5-flash");
assert.ok(flash, "gemini-2.5-flash should be present");
assert.equal(flash!.name, "Gemini 2.5 Flash");
assert.equal(flash!.inputTokenLimit, 1048576);
assert.equal(flash!.outputTokenLimit, 65536);
assert.equal(flash!.supportsThinking, true);
assert.deepEqual(flash!.supportedEndpoints, ["chat"]);
});
test("parseGeminiModelsList maps generateContent image models to the chat endpoint", () => {
const models = parseGeminiModelsList(SAMPLE);
const proImage = models.find((m) => m.id === "gemini-3-pro-image-preview");
assert.ok(proImage, "gemini-3-pro-image-preview should be present");
// gemini-*-image models generate images via generateContent (chat-with-modalities path).
assert.deepEqual(proImage!.supportedEndpoints, ["chat"]);
});
test("parseGeminiModelsList maps Imagen predict models to the images endpoint", () => {
const models = parseGeminiModelsList(SAMPLE);
const imagen = models.find((m) => m.id === "imagen-4.0-generate-001");
assert.ok(imagen, "imagen-4.0-generate-001 should be present");
assert.deepEqual(imagen!.supportedEndpoints, ["images"]);
});
test("parseGeminiModelsList maps embedContent and bidiGenerateContent", () => {
const models = parseGeminiModelsList(SAMPLE);
assert.deepEqual(models.find((m) => m.id === "text-embedding-004")!.supportedEndpoints, [
"embeddings",
]);
assert.deepEqual(models.find((m) => m.id === "gemini-live-2.5-flash")!.supportedEndpoints, [
"audio",
]);
});
test("parseGeminiModelsList maps Veo predictLongRunning models to the video endpoint", () => {
const models = parseGeminiModelsList(SAMPLE);
const veo = models.find((m) => m.id === "veo-3.0-generate-001");
assert.ok(veo, "veo-3.0-generate-001 should be present");
assert.deepEqual(veo!.supportedEndpoints, ["video"]);
});
test("parseGeminiModelsList keeps Imagen as images even via a long-running method", () => {
const models = parseGeminiModelsList(SAMPLE);
const imagen = models.find((m) => m.id === "imagen-future-preview");
assert.ok(imagen, "imagen-future-preview should be present");
assert.deepEqual(imagen!.supportedEndpoints, ["images"]);
});
test("parseGeminiModelsList defaults to chat and tolerates empty/missing input", () => {
assert.deepEqual(parseGeminiModelsList({}), []);
assert.deepEqual(parseGeminiModelsList(null), []);
const [m] = parseGeminiModelsList({ models: [{ name: "models/mystery" }] });
assert.equal(m.id, "mystery");
assert.deepEqual(m.supportedEndpoints, ["chat"]);
});