diff --git a/src/providers/embedding/index.ts b/src/providers/embedding/index.ts index d18de232..ea4259d3 100644 --- a/src/providers/embedding/index.ts +++ b/src/providers/embedding/index.ts @@ -35,7 +35,11 @@ export function createEmbeddingProvider(): EmbeddingProvider | null { case "gemini": return withDimensionGuard(new GeminiEmbeddingProvider(getEnvVar("GEMINI_API_KEY")!)); case "openai": - return withDimensionGuard(new OpenAIEmbeddingProvider(getEnvVar("OPENAI_API_KEY")!)); + return withDimensionGuard( + new OpenAIEmbeddingProvider( + getEnvVar("OPENAI_EMBEDDING_API_KEY") || getEnvVar("OPENAI_API_KEY")!, + ), + ); case "voyage": return withDimensionGuard(new VoyageEmbeddingProvider(getEnvVar("VOYAGE_API_KEY")!)); case "cohere": diff --git a/test/embedding-provider.test.ts b/test/embedding-provider.test.ts index 6c2d263e..7c531957 100644 --- a/test/embedding-provider.test.ts +++ b/test/embedding-provider.test.ts @@ -43,6 +43,23 @@ describe("createEmbeddingProvider", () => { expect(provider!.name).toBe("openai"); }); + it("passes OPENAI_EMBEDDING_API_KEY to OpenAIEmbeddingProvider when set", async () => { + process.env["OPENAI_API_KEY"] = "text-llm-key"; + process.env["OPENAI_EMBEDDING_API_KEY"] = "embedding-key"; + const provider = createEmbeddingProvider(); + + const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue( + new Response(JSON.stringify({ data: [{ embedding: new Array(1536).fill(0.1) }] }), { status: 200 }), + ); + + await provider!.embed("hello"); + expect(fetchSpy.mock.calls[0][1]?.headers).toMatchObject({ + Authorization: "Bearer embedding-key", + }); + + fetchSpy.mockRestore(); + }); + it("EMBEDDING_PROVIDER override takes precedence", () => { process.env["GEMINI_API_KEY"] = "test-key-123"; process.env["OPENAI_API_KEY"] = "test-key-456";