diff --git a/.changeset/silent-cameras-embed.md b/.changeset/silent-cameras-embed.md new file mode 100644 index 000000000000..6097e3401148 --- /dev/null +++ b/.changeset/silent-cameras-embed.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +fix(ai): default missing embedding warnings to an empty array diff --git a/packages/ai/src/embed/embed-many.test.ts b/packages/ai/src/embed/embed-many.test.ts index 068499fbc426..f4a5b0c2076a 100644 --- a/packages/ai/src/embed/embed-many.test.ts +++ b/packages/ai/src/embed/embed-many.test.ts @@ -10,6 +10,7 @@ import { vitest, } from 'vitest'; import * as logWarningsModule from '../logger/log-warnings'; +import { MockEmbeddingModelV2 } from '../test/mock-embedding-model-v2'; import { MockEmbeddingModelV4 } from '../test/mock-embedding-model-v4'; import type { Embedding, EmbeddingModelUsage, Warning } from '../types'; import { createResolvablePromise } from '../util/create-resolvable-promise'; @@ -423,6 +424,21 @@ describe('result.warnings', () => { expect(result.warnings).toStrictEqual(expectedWarnings); }); + it('should default missing v2 provider warnings to an empty array in the single call path', async () => { + const result = await embedMany({ + model: new MockEmbeddingModelV2({ + maxEmbeddingsPerCall: null, + doEmbed: async () => ({ + embeddings: dummyEmbeddings, + usage: { tokens: 3 }, + }), + }), + values: testValues, + }); + + expect(result.warnings).toStrictEqual([]); + }); + it('should aggregate warnings from multiple calls', async () => { const warning1: Warning = { type: 'other', @@ -460,6 +476,35 @@ describe('result.warnings', () => { expect(result.warnings).toStrictEqual([warning1, warning2]); }); + + it('should default missing v2 provider warnings to an empty array in the chunked path', async () => { + let callCount = 0; + + const result = await embedMany({ + model: new MockEmbeddingModelV2({ + maxEmbeddingsPerCall: 2, + doEmbed: async () => { + switch (callCount++) { + case 0: + return { + embeddings: dummyEmbeddings.slice(0, 2), + usage: { tokens: 2 }, + }; + case 1: + return { + embeddings: dummyEmbeddings.slice(2), + usage: { tokens: 1 }, + }; + default: + throw new Error('Unexpected call'); + } + }, + }), + values: testValues, + }); + + expect(result.warnings).toStrictEqual([]); + }); }); describe('logWarnings', () => { diff --git a/packages/ai/src/embed/embed-many.ts b/packages/ai/src/embed/embed-many.ts index a3f08902ba46..a1c80e077c59 100644 --- a/packages/ai/src/embed/embed-many.ts +++ b/packages/ai/src/embed/embed-many.ts @@ -215,7 +215,7 @@ export async function embedMany({ return { embeddings, usage, - warnings: modelResponse.warnings, + warnings: modelResponse.warnings ?? [], providerMetadata: modelResponse.providerMetadata, response: modelResponse.response, }; @@ -317,7 +317,7 @@ export async function embedMany({ return { embeddings: chunkEmbeddings, usage, - warnings: modelResponse.warnings, + warnings: modelResponse.warnings ?? [], providerMetadata: modelResponse.providerMetadata, response: modelResponse.response, }; diff --git a/packages/ai/src/embed/embed.test.ts b/packages/ai/src/embed/embed.test.ts index 32842fdb876d..c85ad7d9afe5 100644 --- a/packages/ai/src/embed/embed.test.ts +++ b/packages/ai/src/embed/embed.test.ts @@ -2,6 +2,7 @@ import type { EmbeddingModelV4 } from '@ai-sdk/provider'; import assert from 'node:assert'; import { beforeEach, describe, expect, it, vi, vitest } from 'vitest'; import * as logWarningsModule from '../logger/log-warnings'; +import { MockEmbeddingModelV2 } from '../test/mock-embedding-model-v2'; import { MockEmbeddingModelV4 } from '../test/mock-embedding-model-v4'; import type { Embedding, EmbeddingModelUsage, Warning } from '../types'; import { embed } from './embed'; @@ -181,6 +182,20 @@ describe('result.warnings', () => { expect(result.warnings).toStrictEqual(expectedWarnings); }); + + it('should default missing v2 provider warnings to an empty array', async () => { + const result = await embed({ + model: new MockEmbeddingModelV2({ + doEmbed: async () => ({ + embeddings: [dummyEmbedding], + usage: { tokens: 1 }, + }), + }), + value: testValue, + }); + + expect(result.warnings).toStrictEqual([]); + }); }); describe('logWarnings', () => { diff --git a/packages/ai/src/embed/embed.ts b/packages/ai/src/embed/embed.ts index 81dec7708625..808d56e898ed 100644 --- a/packages/ai/src/embed/embed.ts +++ b/packages/ai/src/embed/embed.ts @@ -193,7 +193,7 @@ export async function embed({ return { embedding, usage, - warnings: modelResponse.warnings, + warnings: modelResponse.warnings ?? [], providerMetadata: modelResponse.providerMetadata, response: modelResponse.response, };