fix(memory): add input_type to Voyage AI embeddings for improved retrieval (#10818)

* fix(memory): add input_type to Voyage AI embeddings for improved retrieval

Voyage AI recommends passing input_type='document' when indexing and
input_type='query' when searching. This improves retrieval quality by
optimising the embedding space for each direction.

Changes:
- embedQuery now passes input_type: 'query'
- embedBatch now passes input_type: 'document'
- Batch API request_params includes input_type: 'document'
- Tests updated to verify input_type is passed correctly

* Changelog: note Voyage embeddings input_type fix (#10818) (thanks @mcinteerj)

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
This commit is contained in:
Jake
2026-02-07 16:55:09 +13:00
committed by GitHub
parent 4c1da23a71
commit e78ae48e69
5 changed files with 57 additions and 8 deletions

View File

@@ -59,6 +59,7 @@ describe("voyage embedding provider", () => {
expect(body).toEqual({
model: "voyage-4-large",
input: ["test query"],
input_type: "query",
});
});
@@ -90,6 +91,43 @@ describe("voyage embedding provider", () => {
expect(headers["X-Custom"]).toBe("123");
});
it("passes input_type=document for embedBatch", async () => {
const fetchMock = vi.fn(async () => ({
ok: true,
status: 200,
json: async () => ({
data: [{ embedding: [0.1, 0.2] }, { embedding: [0.3, 0.4] }],
}),
})) as unknown as typeof fetch;
vi.stubGlobal("fetch", fetchMock);
const { createVoyageEmbeddingProvider } = await import("./embeddings-voyage.js");
const authModule = await import("../agents/model-auth.js");
vi.mocked(authModule.resolveApiKeyForProvider).mockResolvedValue({
apiKey: "voyage-key-123",
mode: "api-key",
source: "test",
});
const result = await createVoyageEmbeddingProvider({
config: {} as never,
provider: "voyage",
model: "voyage-4-large",
fallback: "none",
});
await result.provider.embedBatch(["doc1", "doc2"]);
const [, init] = fetchMock.mock.calls[0] ?? [];
const body = JSON.parse(init?.body as string);
expect(body).toEqual({
model: "voyage-4-large",
input: ["doc1", "doc2"],
input_type: "document",
});
});
it("normalizes model names", async () => {
const { normalizeVoyageModel } = await import("./embeddings-voyage.js");
expect(normalizeVoyageModel("voyage/voyage-large-2")).toBe("voyage-large-2");