111 lines
4.3 KiB
TypeScript
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"]);
|
|
});
|