AI SDK 7 does not convert file data when adapting v3 language models
Description
AI SDK 7 accepts LanguageModelV3, but file data is not converted between the v3 and v4 formats:
- Input: a v3 model receives
{ type: 'data', data: Uint8Array(...) }instead of the rawUint8Arrayrequired by its interface. Supported file URLs likewise arrive as{ type: 'url', url }instead ofURL. - Output: when a v3 model returns valid inline file data (
Uint8Arrayor base64),generateTextthrowsTypeError: Cannot read properties of undefined (reading 'toString').streamTextalso errors on the file chunk.
Expected: the v3 compatibility adapter preserves the v3 file contract in both directions.
asLanguageModelV4 currently proxies the model and changes only specificationVersion. It forwards v4 prompt data to the v3 model and passes v3 results back unchanged. The core then reads the result as tagged v4 file data. That adapter and the relevant file types are unchanged on current main (12845693d7a6a517dc633d6b6a2e4f5bfd24d2ec; source comparison, not a full-main runtime test).
This differs from #20951: these are inline files from a v3 model, not generated URLs from a v4 model.
Reproduction
No API key or network calls needed. With Node 24, install [email protected] and [email protected], save this as repro.mts, and run node repro.mts:
import { generateText } from 'ai';
import { MockLanguageModelV3 } from 'ai/test';
const usage = {
inputTokens: { total: 1, noCache: 1, cacheRead: 0, cacheWrite: 0 },
outputTokens: { total: 1, text: 1, reasoning: 0 },
};
const inputModel = new MockLanguageModelV3({
doGenerate: {
content: [{ type: 'text', text: 'Synthetic response.' }],
finishReason: { unified: 'stop', raw: 'stop' },
usage,
warnings: [],
},
});
await generateText({
model: inputModel,
messages: [{ role: 'user', content: [{
type: 'file', mediaType: 'application/pdf', data: new Uint8Array([37, 80, 68, 70]),
}] }],
maxRetries: 0,
});
for (const message of inputModel.doGenerateCalls[0].prompt) {
if (message.role !== 'user') continue;
for (const part of message.content) {
if (part.type === 'file') console.log('v3 input data:', part.data);
}
}
const outputModel = new MockLanguageModelV3({
doGenerate: {
content: [{ type: 'file', mediaType: 'image/png', data: new Uint8Array([1, 2, 3]) }],
finishReason: { unified: 'stop', raw: 'stop' },
usage,
warnings: [],
},
});
try {
const result = await generateText({ model: outputModel, prompt: 'Synthetic prompt.', maxRetries: 0 });
console.log('v3 output data:', result.files[0].uint8Array);
} catch (error) {
console.log('v3 output:', error instanceof Error ? `${error.name}: ${error.message}` : error);
}
Actual output:
v3 input data: { type: 'data', data: Uint8Array(4) [ 37, 80, 68, 70 ] }
v3 output: TypeError: Cannot read properties of undefined (reading 'toString')The input should be the raw byte array; the output should be Uint8Array(3) [1, 2, 3].
Additional local regression checks cover generateText and streamText, byte/URL inputs, and byte/base64 outputs. On both Node 22 and 24, all eight v3 file cases fail; the two v3 text cases and all ten v4 controls pass. The reproduction also passes strict TypeScript checking.
I used AI assistance to investigate and prepare the reproduction and tests.
AI SDK Version
ai:7.0.101zod:4.4.3- Node.js:
22.20.0and24.13.0
Code of Conduct
- I agree to follow this project's Code of Conduct
Source: vercel/ai