test: trim duplicate hotspot coverage

This commit is contained in:
Peter Steinberger
2026-04-16 22:19:24 +01:00
parent 98c681e033
commit 63e53fbf2e
5 changed files with 159 additions and 635 deletions

View File

@@ -47,11 +47,6 @@ function installFetchMock(fetchMock: typeof globalThis.fetch) {
vi.stubGlobal("fetch", fetchMock);
}
function readFirstFetchRequest(fetchMock: { mock: { calls: unknown[][] } }) {
const [url, init] = fetchMock.mock.calls[0] ?? [];
return { url, init: init as RequestInit | undefined };
}
function parseFetchBody(fetchMock: { mock: { calls: unknown[][] } }, callIndex = 0) {
const init = fetchMock.mock.calls[callIndex]?.[1] as RequestInit | undefined;
return JSON.parse((init?.body as string) ?? "{}") as Record<string, unknown>;
@@ -67,6 +62,7 @@ let createGeminiEmbeddingProvider: typeof import("./embeddings-gemini.js").creat
let DEFAULT_GEMINI_EMBEDDING_MODEL: typeof import("./embeddings-gemini.js").DEFAULT_GEMINI_EMBEDDING_MODEL;
let GEMINI_EMBEDDING_2_MODELS: typeof import("./embeddings-gemini.js").GEMINI_EMBEDDING_2_MODELS;
let isGeminiEmbedding2Model: typeof import("./embeddings-gemini.js").isGeminiEmbedding2Model;
let normalizeGeminiModel: typeof import("./embeddings-gemini.js").normalizeGeminiModel;
let resolveGeminiOutputDimensionality: typeof import("./embeddings-gemini.js").resolveGeminiOutputDimensionality;
beforeAll(async () => {
@@ -78,6 +74,7 @@ beforeAll(async () => {
DEFAULT_GEMINI_EMBEDDING_MODEL,
GEMINI_EMBEDDING_2_MODELS,
isGeminiEmbedding2Model,
normalizeGeminiModel,
resolveGeminiOutputDimensionality,
} = await import("./embeddings-gemini.js"));
});
@@ -224,346 +221,73 @@ describe("resolveGeminiOutputDimensionality", () => {
});
});
// ---------- Provider: gemini-embedding-001 (backward compat) ----------
// ---------- Provider behavior smoke coverage ----------
describe("gemini-embedding-001 provider (backward compat)", () => {
it("does NOT include outputDimensionality in embedQuery", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
describe("gemini embedding provider", () => {
it("handles legacy and v2 request/response behavior", async () => {
const legacyFetch = createGeminiBatchFetchMock(2);
const legacyProvider = await createProviderWithFetch(legacyFetch, {
model: "gemini-embedding-001",
});
await provider.embedQuery("test query");
await legacyProvider.embedQuery("test query");
await legacyProvider.embedBatch(["text1", "text2"]);
const body = parseFetchBody(fetchMock);
expect(body).not.toHaveProperty("outputDimensionality");
expect(body.taskType).toBe("RETRIEVAL_QUERY");
expect(body.content).toEqual({ parts: [{ text: "test query" }] });
});
it("does NOT include outputDimensionality in embedBatch", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-001",
expect(parseFetchBody(legacyFetch, 0)).toMatchObject({
taskType: "RETRIEVAL_QUERY",
content: { parts: [{ text: "test query" }] },
});
expect(parseFetchBody(legacyFetch, 0)).not.toHaveProperty("outputDimensionality");
expect(parseFetchBody(legacyFetch, 1)).not.toHaveProperty("outputDimensionality");
await provider.embedBatch(["text1", "text2"]);
const body = parseFetchBody(fetchMock);
expect(body).not.toHaveProperty("outputDimensionality");
});
});
// ---------- Provider: gemini-embedding-2-preview ----------
describe("gemini-embedding-2-preview provider", () => {
it("includes outputDimensionality in embedQuery request", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
await provider.embedQuery("test query");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(3072);
expect(body.taskType).toBe("RETRIEVAL_QUERY");
expect(body.content).toEqual({ parts: [{ text: "test query" }] });
});
it("normalizes embedQuery response vectors", async () => {
const fetchMock = createGeminiFetchMock([3, 4]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
const embedding = await provider.embedQuery("test query");
expectNormalizedThreeFourVector(embedding);
});
it("includes outputDimensionality in embedBatch request", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
await provider.embedBatch(["text1", "text2"]);
const body = parseFetchBody(fetchMock);
expect(body.requests).toEqual([
{
model: "models/gemini-embedding-2-preview",
content: { parts: [{ text: "text1" }] },
taskType: "RETRIEVAL_DOCUMENT",
outputDimensionality: 3072,
},
{
model: "models/gemini-embedding-2-preview",
content: { parts: [{ text: "text2" }] },
taskType: "RETRIEVAL_DOCUMENT",
outputDimensionality: 3072,
},
]);
});
it("normalizes embedBatch response vectors", async () => {
const fetchMock = createGeminiBatchFetchMock(2, [3, 4]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
const embeddings = await provider.embedBatch(["text1", "text2"]);
expect(embeddings).toHaveLength(2);
for (const embedding of embeddings) {
expectNormalizedThreeFourVector(embedding);
}
});
it("respects custom outputDimensionality", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
const v2QueryFetch = createGeminiFetchMock([3, 4]);
const v2QueryProvider = await createProviderWithFetch(v2QueryFetch, {
model: "gemini-embedding-2-preview",
outputDimensionality: 768,
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(768);
});
it("sanitizes and normalizes embedQuery responses", async () => {
const fetchMock = createGeminiFetchMock([3, 4, Number.NaN]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
await expect(provider.embedQuery("test")).resolves.toEqual([0.6, 0.8, 0]);
});
it("uses custom outputDimensionality for each embedBatch request", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
outputDimensionality: 768,
});
await provider.embedBatch(["text1", "text2"]);
const body = parseFetchBody(fetchMock);
expect(body.requests).toEqual([
expect.objectContaining({ outputDimensionality: 768 }),
expect.objectContaining({ outputDimensionality: 768 }),
]);
});
it("sanitizes and normalizes structured batch responses", async () => {
const fetchMock = createGeminiBatchFetchMock(1, [0, Number.POSITIVE_INFINITY, 5]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
await expect(
provider.embedBatchInputs?.([
{
text: "Image file: diagram.png",
parts: [
{ type: "text", text: "Image file: diagram.png" },
{ type: "inline-data", mimeType: "image/png", data: "img" },
],
},
]),
).resolves.toEqual([[0, 0, 1]]);
});
it("supports multimodal embedBatchInputs requests", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
expect(provider.embedBatchInputs).toBeDefined();
await provider.embedBatchInputs?.([
{
text: "Image file: diagram.png",
parts: [
{ type: "text", text: "Image file: diagram.png" },
{ type: "inline-data", mimeType: "image/png", data: "img" },
],
},
{
text: "Audio file: note.wav",
parts: [
{ type: "text", text: "Audio file: note.wav" },
{ type: "inline-data", mimeType: "audio/wav", data: "aud" },
],
},
]);
const body = parseFetchBody(fetchMock);
expect(body.requests).toEqual([
{
model: "models/gemini-embedding-2-preview",
content: {
parts: [
{ text: "Image file: diagram.png" },
{ inlineData: { mimeType: "image/png", data: "img" } },
],
},
taskType: "RETRIEVAL_DOCUMENT",
outputDimensionality: 3072,
},
{
model: "models/gemini-embedding-2-preview",
content: {
parts: [
{ text: "Audio file: note.wav" },
{ inlineData: { mimeType: "audio/wav", data: "aud" } },
],
},
taskType: "RETRIEVAL_DOCUMENT",
outputDimensionality: 3072,
},
]);
});
it("throws for invalid outputDimensionality", async () => {
mockResolvedProviderKey();
await expect(
createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "gemini-embedding-2-preview",
fallback: "none",
outputDimensionality: 512,
}),
).rejects.toThrow(/Invalid outputDimensionality 512/);
});
it("sanitizes non-finite values before normalization", async () => {
const fetchMock = createGeminiFetchMock([
1,
Number.NaN,
Number.POSITIVE_INFINITY,
Number.NEGATIVE_INFINITY,
]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
const embedding = await provider.embedQuery("test");
expect(embedding).toEqual([1, 0, 0, 0]);
});
it("uses correct endpoint URL", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
await provider.embedQuery("test");
const { url } = readFirstFetchRequest(fetchMock);
expect(url).toBe(
"https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2-preview:embedContent",
);
});
it("allows taskType override via options", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
taskType: "SEMANTIC_SIMILARITY",
});
expectNormalizedThreeFourVector(await v2QueryProvider.embedQuery("test query"));
await provider.embedQuery("test");
const v2BatchFetch = createGeminiBatchFetchMock(2, [3, 4]);
const v2BatchProvider = await createProviderWithFetch(v2BatchFetch, {
model: "gemini-embedding-2-preview",
outputDimensionality: 768,
taskType: "SEMANTIC_SIMILARITY",
});
const batch = await v2BatchProvider.embedBatch(["text1", "text2"]);
expect(batch).toHaveLength(2);
for (const embedding of batch) {
expectNormalizedThreeFourVector(embedding);
}
const body = parseFetchBody(fetchMock);
expect(body.taskType).toBe("SEMANTIC_SIMILARITY");
expect(parseFetchBody(v2QueryFetch)).toMatchObject({
outputDimensionality: 768,
taskType: "SEMANTIC_SIMILARITY",
});
expect(parseFetchBody(v2BatchFetch).requests).toEqual([
expect.objectContaining({ outputDimensionality: 768 }),
expect.objectContaining({ outputDimensionality: 768 }),
]);
});
});
// ---------- Model normalization ----------
describe("gemini model normalization", () => {
it("handles models/ prefix for v2 model", async () => {
const fetchMock = createGeminiFetchMock();
installFetchMock(fetchMock as unknown as typeof globalThis.fetch);
mockPublicPinnedHostname();
mockResolvedProviderKey();
const { provider } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "models/gemini-embedding-2-preview",
fallback: "none",
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(3072);
it("normalizes known model prefixes and default model", () => {
expect(normalizeGeminiModel("models/gemini-embedding-2-preview")).toBe(
"gemini-embedding-2-preview",
);
expect(normalizeGeminiModel("gemini/gemini-embedding-2-preview")).toBe(
"gemini-embedding-2-preview",
);
expect(normalizeGeminiModel("google/gemini-embedding-2-preview")).toBe(
"gemini-embedding-2-preview",
);
expect(normalizeGeminiModel("")).toBe(DEFAULT_GEMINI_EMBEDDING_MODEL);
});
it("handles gemini/ prefix for v2 model", async () => {
const fetchMock = createGeminiFetchMock();
installFetchMock(fetchMock as unknown as typeof globalThis.fetch);
mockPublicPinnedHostname();
mockResolvedProviderKey();
const { provider } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "gemini/gemini-embedding-2-preview",
fallback: "none",
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(3072);
});
it("handles google/ prefix for v2 model", async () => {
const fetchMock = createGeminiFetchMock();
installFetchMock(fetchMock as unknown as typeof globalThis.fetch);
mockPublicPinnedHostname();
mockResolvedProviderKey();
const { provider } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "google/gemini-embedding-2-preview",
fallback: "none",
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(3072);
});
it("defaults to gemini-embedding-001 when model is empty", async () => {
const fetchMock = createGeminiFetchMock();
installFetchMock(fetchMock as unknown as typeof globalThis.fetch);
mockResolvedProviderKey();
const { provider, client } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "",
fallback: "none",
});
expect(client.model).toBe(DEFAULT_GEMINI_EMBEDDING_MODEL);
expect(provider.model).toBe(DEFAULT_GEMINI_EMBEDDING_MODEL);
});
it("returns empty array for blank query text", async () => {
it("returns empty arrays without fetching for blank query and empty batch", async () => {
mockResolvedProviderKey();
const { provider } = await createGeminiEmbeddingProvider({
@@ -573,21 +297,7 @@ describe("gemini model normalization", () => {
fallback: "none",
});
const result = await provider.embedQuery(" ");
expect(result).toEqual([]);
});
it("returns empty array for empty batch", async () => {
mockResolvedProviderKey();
const { provider } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "gemini-embedding-2-preview",
fallback: "none",
});
const result = await provider.embedBatch([]);
expect(result).toEqual([]);
await expect(provider.embedQuery(" ")).resolves.toEqual([]);
await expect(provider.embedBatch([])).resolves.toEqual([]);
});
});

View File

@@ -651,7 +651,7 @@ describe("local embedding ensureContext concurrency", () => {
it("loads the model only once when embedBatch is called concurrently", async () => {
const { provider, getLlamaSpy, loadModelSpy, createContextSpy } =
await setupLocalProviderWithMockedInit({
initializationDelayMs: 50,
initializationDelayMs: 5,
});
const results = await Promise.all([
@@ -692,7 +692,7 @@ describe("local embedding ensureContext concurrency", () => {
it("shares initialization when embedQuery and embedBatch start concurrently", async () => {
const { provider, getLlamaSpy, loadModelSpy, createContextSpy } =
await setupLocalProviderWithMockedInit({
initializationDelayMs: 50,
initializationDelayMs: 5,
});
const [queryA, batch, queryB] = await Promise.all([

View File

@@ -26,6 +26,7 @@ let createGeminiEmbeddingProvider: typeof import("./embeddings-gemini.js").creat
let DEFAULT_GEMINI_EMBEDDING_MODEL: typeof import("./embeddings-gemini.js").DEFAULT_GEMINI_EMBEDDING_MODEL;
let GEMINI_EMBEDDING_2_MODELS: typeof import("./embeddings-gemini.js").GEMINI_EMBEDDING_2_MODELS;
let isGeminiEmbedding2Model: typeof import("./embeddings-gemini.js").isGeminiEmbedding2Model;
let normalizeGeminiModel: typeof import("./embeddings-gemini.js").normalizeGeminiModel;
let resolveGeminiOutputDimensionality: typeof import("./embeddings-gemini.js").resolveGeminiOutputDimensionality;
beforeAll(async () => {
@@ -37,6 +38,7 @@ beforeAll(async () => {
DEFAULT_GEMINI_EMBEDDING_MODEL,
GEMINI_EMBEDDING_2_MODELS,
isGeminiEmbedding2Model,
normalizeGeminiModel,
resolveGeminiOutputDimensionality,
} = await import("./embeddings-gemini.js"));
});
@@ -171,74 +173,47 @@ describe("resolveGeminiOutputDimensionality", () => {
});
});
// ---------- Provider: gemini-embedding-001 (backward compat) ----------
// ---------- Provider behavior ----------
describe("gemini-embedding-001 provider (backward compat)", () => {
it("does NOT include outputDimensionality in embedQuery", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
describe("gemini embedding provider", () => {
it("handles legacy and v2 request/response behavior", async () => {
const legacyFetch = createGeminiBatchFetchMock(2);
const legacyProvider = await createProviderWithFetch(legacyFetch, {
model: "gemini-embedding-001",
});
await provider.embedQuery("test query");
await legacyProvider.embedQuery("test query");
await legacyProvider.embedBatch(["text1", "text2"]);
const body = parseFetchBody(fetchMock);
expect(body).not.toHaveProperty("outputDimensionality");
expect(body.taskType).toBe("RETRIEVAL_QUERY");
expect(body.content).toEqual({ parts: [{ text: "test query" }] });
});
it("does NOT include outputDimensionality in embedBatch", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-001",
expect(parseFetchBody(legacyFetch, 0)).toMatchObject({
taskType: "RETRIEVAL_QUERY",
content: { parts: [{ text: "test query" }] },
});
expect(parseFetchBody(legacyFetch, 0)).not.toHaveProperty("outputDimensionality");
expect(parseFetchBody(legacyFetch, 1)).not.toHaveProperty("outputDimensionality");
await provider.embedBatch(["text1", "text2"]);
const body = parseFetchBody(fetchMock);
expect(body).not.toHaveProperty("outputDimensionality");
});
});
// ---------- Provider: gemini-embedding-2-preview ----------
describe("gemini-embedding-2-preview provider", () => {
it("includes outputDimensionality in embedQuery request", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
const v2QueryFetch = createGeminiFetchMock([3, 4]);
const v2QueryProvider = await createProviderWithFetch(v2QueryFetch, {
model: "gemini-embedding-2-preview",
});
expectNormalizedThreeFourVector(await v2QueryProvider.embedQuery("test query"));
await provider.embedQuery("test query");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(3072);
expect(body.taskType).toBe("RETRIEVAL_QUERY");
expect(body.content).toEqual({ parts: [{ text: "test query" }] });
});
it("normalizes embedQuery response vectors", async () => {
const fetchMock = createGeminiFetchMock([3, 4]);
const provider = await createProviderWithFetch(fetchMock, {
const v2BatchFetch = createGeminiBatchFetchMock(2, [3, 4]);
const v2BatchProvider = await createProviderWithFetch(v2BatchFetch, {
model: "gemini-embedding-2-preview",
});
const batch = await v2BatchProvider.embedBatch(["text1", "text2"]);
expect(batch).toHaveLength(2);
for (const embedding of batch) {
expectNormalizedThreeFourVector(embedding);
}
const embedding = await provider.embedQuery("test query");
expectNormalizedThreeFourVector(embedding);
});
it("includes outputDimensionality in embedBatch request", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
expect(parseFetchBody(v2QueryFetch)).toMatchObject({
outputDimensionality: 3072,
taskType: "RETRIEVAL_QUERY",
content: { parts: [{ text: "test query" }] },
});
await provider.embedBatch(["text1", "text2"]);
const body = parseFetchBody(fetchMock);
expect(body.requests).toEqual([
expect(parseFetchBody(v2BatchFetch).requests).toEqual([
{
model: "models/gemini-embedding-2-preview",
content: { parts: [{ text: "text1" }] },
@@ -254,84 +229,15 @@ describe("gemini-embedding-2-preview provider", () => {
]);
});
it("normalizes embedBatch response vectors", async () => {
const fetchMock = createGeminiBatchFetchMock(2, [3, 4]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
const embeddings = await provider.embedBatch(["text1", "text2"]);
expect(embeddings).toHaveLength(2);
for (const embedding of embeddings) {
expectNormalizedThreeFourVector(embedding);
}
});
it("respects custom outputDimensionality", async () => {
const fetchMock = createGeminiFetchMock();
it("supports custom dimensions, task type, multimodal inputs, and endpoint URL", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
outputDimensionality: 768,
taskType: "SEMANTIC_SIMILARITY",
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(768);
});
it("sanitizes and normalizes embedQuery responses", async () => {
const fetchMock = createGeminiFetchMock([3, 4, Number.NaN]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
await expect(provider.embedQuery("test")).resolves.toEqual([0.6, 0.8, 0]);
});
it("uses custom outputDimensionality for each embedBatch request", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
outputDimensionality: 768,
});
await provider.embedBatch(["text1", "text2"]);
const body = parseFetchBody(fetchMock);
expect(body.requests).toEqual([
expect.objectContaining({ outputDimensionality: 768 }),
expect.objectContaining({ outputDimensionality: 768 }),
]);
});
it("sanitizes and normalizes structured batch responses", async () => {
const fetchMock = createGeminiBatchFetchMock(1, [0, Number.POSITIVE_INFINITY, 5]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
await expect(
provider.embedBatchInputs?.([
{
text: "Image file: diagram.png",
parts: [
{ type: "text", text: "Image file: diagram.png" },
{ type: "inline-data", mimeType: "image/png", data: "img" },
],
},
]),
).resolves.toEqual([[0, 0, 1]]);
});
it("supports multimodal embedBatchInputs requests", async () => {
const fetchMock = createGeminiBatchFetchMock(2);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
expect(provider.embedBatchInputs).toBeDefined();
await provider.embedBatchInputs?.([
{
text: "Image file: diagram.png",
@@ -349,8 +255,15 @@ describe("gemini-embedding-2-preview provider", () => {
},
]);
const body = parseFetchBody(fetchMock);
expect(body.requests).toEqual([
const { url } = readFirstFetchRequest(fetchMock);
expect(url).toBe(
"https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2-preview:embedContent",
);
expect(parseFetchBody(fetchMock, 0)).toMatchObject({
outputDimensionality: 768,
taskType: "SEMANTIC_SIMILARITY",
});
expect(parseFetchBody(fetchMock, 1).requests).toEqual([
{
model: "models/gemini-embedding-2-preview",
content: {
@@ -359,8 +272,8 @@ describe("gemini-embedding-2-preview provider", () => {
{ inlineData: { mimeType: "image/png", data: "img" } },
],
},
taskType: "RETRIEVAL_DOCUMENT",
outputDimensionality: 3072,
taskType: "SEMANTIC_SIMILARITY",
outputDimensionality: 768,
},
{
model: "models/gemini-embedding-2-preview",
@@ -370,147 +283,54 @@ describe("gemini-embedding-2-preview provider", () => {
{ inlineData: { mimeType: "audio/wav", data: "aud" } },
],
},
taskType: "RETRIEVAL_DOCUMENT",
outputDimensionality: 3072,
taskType: "SEMANTIC_SIMILARITY",
outputDimensionality: 768,
},
]);
});
it("throws for invalid outputDimensionality", async () => {
mockResolvedProviderKey(authModule.resolveApiKeyForProvider);
it("sanitizes non-finite query and structured batch responses", async () => {
const queryFetch = createGeminiFetchMock([3, 4, Number.NaN]);
const queryProvider = await createProviderWithFetch(queryFetch, {
model: "gemini-embedding-2-preview",
});
await expect(queryProvider.embedQuery("test")).resolves.toEqual([0.6, 0.8, 0]);
const batchFetch = createGeminiBatchFetchMock(1, [0, Number.POSITIVE_INFINITY, 5]);
const batchProvider = await createProviderWithFetch(batchFetch, {
model: "gemini-embedding-2-preview",
});
await expect(
createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "gemini-embedding-2-preview",
fallback: "none",
outputDimensionality: 512,
}),
).rejects.toThrow(/Invalid outputDimensionality 512/);
});
it("sanitizes non-finite values before normalization", async () => {
const fetchMock = createGeminiFetchMock([
1,
Number.NaN,
Number.POSITIVE_INFINITY,
Number.NEGATIVE_INFINITY,
]);
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
const embedding = await provider.embedQuery("test");
expect(embedding).toEqual([1, 0, 0, 0]);
});
it("uses correct endpoint URL", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
});
await provider.embedQuery("test");
const { url } = readFirstFetchRequest(fetchMock);
expect(url).toBe(
"https://generativelanguage.googleapis.com/v1beta/models/gemini-embedding-2-preview:embedContent",
);
});
it("allows taskType override via options", async () => {
const fetchMock = createGeminiFetchMock();
const provider = await createProviderWithFetch(fetchMock, {
model: "gemini-embedding-2-preview",
taskType: "SEMANTIC_SIMILARITY",
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.taskType).toBe("SEMANTIC_SIMILARITY");
batchProvider.embedBatchInputs?.([
{
text: "Image file: diagram.png",
parts: [
{ type: "text", text: "Image file: diagram.png" },
{ type: "inline-data", mimeType: "image/png", data: "img" },
],
},
]),
).resolves.toEqual([[0, 0, 1]]);
});
});
// ---------- Model normalization ----------
describe("gemini model normalization", () => {
it("handles models/ prefix for v2 model", async () => {
const fetchMock = createGeminiFetchMock();
installFetchMock(fetchMock as unknown as typeof globalThis.fetch);
mockPublicPinnedHostname();
mockResolvedProviderKey(authModule.resolveApiKeyForProvider);
const { provider } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "models/gemini-embedding-2-preview",
fallback: "none",
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(3072);
it("normalizes known model prefixes and default model", () => {
expect(normalizeGeminiModel("models/gemini-embedding-2-preview")).toBe(
"gemini-embedding-2-preview",
);
expect(normalizeGeminiModel("gemini/gemini-embedding-2-preview")).toBe(
"gemini-embedding-2-preview",
);
expect(normalizeGeminiModel("google/gemini-embedding-2-preview")).toBe(
"gemini-embedding-2-preview",
);
expect(normalizeGeminiModel("")).toBe(DEFAULT_GEMINI_EMBEDDING_MODEL);
});
it("handles gemini/ prefix for v2 model", async () => {
const fetchMock = createGeminiFetchMock();
installFetchMock(fetchMock as unknown as typeof globalThis.fetch);
mockPublicPinnedHostname();
mockResolvedProviderKey(authModule.resolveApiKeyForProvider);
const { provider } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "gemini/gemini-embedding-2-preview",
fallback: "none",
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(3072);
});
it("handles google/ prefix for v2 model", async () => {
const fetchMock = createGeminiFetchMock();
installFetchMock(fetchMock as unknown as typeof globalThis.fetch);
mockPublicPinnedHostname();
mockResolvedProviderKey(authModule.resolveApiKeyForProvider);
const { provider } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "google/gemini-embedding-2-preview",
fallback: "none",
});
await provider.embedQuery("test");
const body = parseFetchBody(fetchMock);
expect(body.outputDimensionality).toBe(3072);
});
it("defaults to gemini-embedding-001 when model is empty", async () => {
const fetchMock = createGeminiFetchMock();
installFetchMock(fetchMock as unknown as typeof globalThis.fetch);
mockResolvedProviderKey(authModule.resolveApiKeyForProvider);
const { provider, client } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "",
fallback: "none",
});
expect(client.model).toBe(DEFAULT_GEMINI_EMBEDDING_MODEL);
expect(provider.model).toBe(DEFAULT_GEMINI_EMBEDDING_MODEL);
});
it("returns empty array for blank query text", async () => {
it("returns empty arrays without fetching for blank query and empty batch", async () => {
mockResolvedProviderKey(authModule.resolveApiKeyForProvider);
const { provider } = await createGeminiEmbeddingProvider({
@@ -520,21 +340,7 @@ describe("gemini model normalization", () => {
fallback: "none",
});
const result = await provider.embedQuery(" ");
expect(result).toEqual([]);
});
it("returns empty array for empty batch", async () => {
mockResolvedProviderKey(authModule.resolveApiKeyForProvider);
const { provider } = await createGeminiEmbeddingProvider({
config: {} as never,
provider: "gemini",
model: "gemini-embedding-2-preview",
fallback: "none",
});
const result = await provider.embedBatch([]);
expect(result).toEqual([]);
await expect(provider.embedQuery(" ")).resolves.toEqual([]);
await expect(provider.embedBatch([])).resolves.toEqual([]);
});
});

View File

@@ -660,7 +660,7 @@ describe("local embedding ensureContext concurrency", () => {
it("loads the model only once when embedBatch is called concurrently", async () => {
const { provider, getLlamaSpy, loadModelSpy, createContextSpy } =
await setupLocalProviderWithMockedInit({
initializationDelayMs: 50,
initializationDelayMs: 5,
});
const results = await Promise.all([
@@ -701,7 +701,7 @@ describe("local embedding ensureContext concurrency", () => {
it("shares initialization when embedQuery and embedBatch start concurrently", async () => {
const { provider, getLlamaSpy, loadModelSpy, createContextSpy } =
await setupLocalProviderWithMockedInit({
initializationDelayMs: 50,
initializationDelayMs: 5,
});
const [queryA, batch, queryB] = await Promise.all([

View File

@@ -247,27 +247,35 @@ describe("parseSlashCommand", () => {
it("caps remote command payload size and long metadata before it reaches UI state", async () => {
const longName = "x".repeat(260);
const longDescription = "d".repeat(2_500);
const request = async () => ({
commands: Array.from({ length: 520 }, (_, index) => ({
name: `plugin-${index}`,
textAliases: Array.from(
{ length: 25 },
(_, aliasIndex) => `/plugin-${index}-${aliasIndex}`,
),
const oversizedCommand = {
name: "plugin-0",
textAliases: Array.from({ length: 25 }, (_, aliasIndex) => `/plugin-0-${aliasIndex}`),
description: longDescription,
source: "plugin" as const,
scope: "both" as const,
acceptsArgs: true,
args: Array.from({ length: 25 }, (_, argIndex) => ({
name: `${longName}-${argIndex}`,
description: longDescription,
source: "plugin" as const,
scope: "both" as const,
acceptsArgs: true,
args: Array.from({ length: 25 }, (_, argIndex) => ({
name: `${longName}-${argIndex}`,
description: longDescription,
type: "string" as const,
choices: Array.from({ length: 55 }, (_, choiceIndex) => ({
value: `${longName}-${choiceIndex}`,
label: `${longName}-${choiceIndex}`,
})),
type: "string" as const,
choices: Array.from({ length: 55 }, (_, choiceIndex) => ({
value: `${longName}-${choiceIndex}`,
label: `${longName}-${choiceIndex}`,
})),
})),
};
const request = async () => ({
commands: [
oversizedCommand,
...Array.from({ length: 519 }, (_, index) => ({
name: `plugin-${index + 1}`,
textAliases: [`/plugin-${index + 1}`],
description: "Plugin command.",
source: "plugin" as const,
scope: "both" as const,
acceptsArgs: false,
})),
],
});
await refreshSlashCommands({