diff --git a/dist/index.js b/dist/index.js --- a/dist/index.js +++ b/dist/index.js @@ -571,6 +571,17 @@ type: "reasoning", text: reasoning }); + } + if (choice.message.images) { + for (const image of choice.message.images) { + const match1 = image.image_url.url.match(/^data:([^;]+)/); + const match2 = image.image_url.url.match(/^data:[^;]*;base64,(.+)$/); + content.push({ + type: 'file', + mediaType: match1 ? (match1[1] ?? 'image/jpeg') : 'image/jpeg', + data: match2 ? match2[1] : image.image_url.url, + }); + } } if (choice.message.tool_calls != null) { for (const toolCall of choice.message.tool_calls) { @@ -732,6 +743,17 @@ delta: delta.content }); } + if (delta.images) { + for (const image of delta.images) { + const match1 = image.image_url.url.match(/^data:([^;]+)/); + const match2 = image.image_url.url.match(/^data:[^;]*;base64,(.+)$/); + controller.enqueue({ + type: 'file', + mediaType: match1 ? (match1[1] ?? 'image/jpeg') : 'image/jpeg', + data: match2 ? match2[1] : image.image_url.url, + }); + } + } if (delta.tool_calls != null) { if (isActiveReasoning) { controller.enqueue({ @@ -927,6 +949,14 @@ thought_signature: import_v43.z.string().nullish() }).nullish() }).nullish() + }) + ).nullish(), + images: import_v43.z.array( + import_v43.z.object({ + type: import_v43.z.literal('image_url'), + image_url: import_v43.z.object({ + url: import_v43.z.string(), + }) }) ).nullish() }), @@ -963,6 +993,14 @@ thought_signature: import_v43.z.string().nullish() }).nullish() }).nullish() + }) + ).nullish(), + images: import_v43.z.array( + import_v43.z.object({ + type: import_v43.z.literal('image_url'), + image_url: import_v43.z.object({ + url: import_v43.z.string(), + }) }) ).nullish() }).nullish(), @@ -1529,6 +1567,16 @@ // src/image/openai-compatible-image-model.ts var import_provider_utils5 = require("@ai-sdk/provider-utils"); var import_v48 = require("zod/v4"); +var defaultResponseFormatPrefixes = [ + "chatgpt-image-", + "gpt-image-1-mini", + "gpt-image-1.5", + "gpt-image-1", + "gpt-image-2" +]; +function hasDefaultResponseFormat(modelId) { + return defaultResponseFormatPrefixes.some((prefix) => modelId.startsWith(prefix)); +} var OpenAICompatibleImageModel = class { constructor(modelId, config) { this.modelId = modelId; @@ -1604,7 +1652,11 @@ fetch: this.config.fetch }); return { - images: response2.data.map((item) => item.b64_json), + images: response2.data.flatMap((item) => { + if (typeof item.b64_json === 'string') return [item.b64_json]; + if (typeof item.url === 'string') return [item.url]; + return []; + }), warnings, response: { timestamp: currentDate, @@ -1625,7 +1677,7 @@ n, size, ...args, - response_format: "b64_json" + ...(!hasDefaultResponseFormat(this.modelId) ? { response_format: "b64_json" } : {}) }, failedResponseHandler: (0, import_provider_utils5.createJsonErrorResponseHandler)( (_e = this.config.errorStructure) != null ? _e : defaultOpenAICompatibleErrorStructure @@ -1637,7 +1693,11 @@ fetch: this.config.fetch }); return { - images: response.data.map((item) => item.b64_json), + images: response.data.flatMap((item) => { + if (typeof item.b64_json === 'string') return [item.b64_json]; + if (typeof item.url === 'string') return [item.url]; + return []; + }), warnings, response: { timestamp: currentDate, @@ -1648,7 +1708,7 @@ } }; var openaiCompatibleImageResponseSchema = import_v48.z.object({ - data: import_v48.z.array(import_v48.z.object({ b64_json: import_v48.z.string() })) + data: import_v48.z.array(import_v48.z.object({ b64_json: import_v48.z.string().nullish(), url: import_v48.z.string().nullish() })) }); async function fileToBlob(file) { if (file.type === "url") { diff --git a/dist/index.mjs b/dist/index.mjs --- a/dist/index.mjs +++ b/dist/index.mjs @@ -558,6 +558,17 @@ type: "reasoning", text: reasoning }); + } + if (choice.message.images) { + for (const image of choice.message.images) { + const match1 = image.image_url.url.match(/^data:([^;]+)/); + const match2 = image.image_url.url.match(/^data:[^;]*;base64,(.+)$/); + content.push({ + type: 'file', + mediaType: match1 ? (match1[1] ?? 'image/jpeg') : 'image/jpeg', + data: match2 ? match2[1] : image.image_url.url, + }); + } } if (choice.message.tool_calls != null) { for (const toolCall of choice.message.tool_calls) { @@ -719,6 +730,17 @@ delta: delta.content }); } + if (delta.images) { + for (const image of delta.images) { + const match1 = image.image_url.url.match(/^data:([^;]+)/); + const match2 = image.image_url.url.match(/^data:[^;]*;base64,(.+)$/); + controller.enqueue({ + type: 'file', + mediaType: match1 ? (match1[1] ?? 'image/jpeg') : 'image/jpeg', + data: match2 ? match2[1] : image.image_url.url, + }); + } + } if (delta.tool_calls != null) { if (isActiveReasoning) { controller.enqueue({ @@ -914,6 +936,14 @@ thought_signature: z3.string().nullish() }).nullish() }).nullish() + }) + ).nullish(), + images: z3.array( + z3.object({ + type: z3.literal('image_url'), + image_url: z3.object({ + url: z3.string(), + }) }) ).nullish() }), @@ -950,6 +980,14 @@ thought_signature: z3.string().nullish() }).nullish() }).nullish() + }) + ).nullish(), + images: z3.array( + z3.object({ + type: z3.literal('image_url'), + image_url: z3.object({ + url: z3.string(), + }) }) ).nullish() }).nullish(), @@ -1543,6 +1581,16 @@ postJsonToApi as postJsonToApi4 } from "@ai-sdk/provider-utils"; import { z as z8 } from "zod/v4"; +var defaultResponseFormatPrefixes = [ + "chatgpt-image-", + "gpt-image-1-mini", + "gpt-image-1.5", + "gpt-image-1", + "gpt-image-2" +]; +function hasDefaultResponseFormat(modelId) { + return defaultResponseFormatPrefixes.some((prefix) => modelId.startsWith(prefix)); +} var OpenAICompatibleImageModel = class { constructor(modelId, config) { this.modelId = modelId; @@ -1618,7 +1666,11 @@ fetch: this.config.fetch }); return { - images: response2.data.map((item) => item.b64_json), + images: response2.data.flatMap((item) => { + if (typeof item.b64_json === 'string') return [item.b64_json]; + if (typeof item.url === 'string') return [item.url]; + return []; + }), warnings, response: { timestamp: currentDate, @@ -1639,7 +1691,7 @@ n, size, ...args, - response_format: "b64_json" + ...(!hasDefaultResponseFormat(this.modelId) ? { response_format: "b64_json" } : {}) }, failedResponseHandler: createJsonErrorResponseHandler4( (_e = this.config.errorStructure) != null ? _e : defaultOpenAICompatibleErrorStructure @@ -1651,7 +1707,11 @@ fetch: this.config.fetch }); return { - images: response.data.map((item) => item.b64_json), + images: response.data.flatMap((item) => { + if (typeof item.b64_json === 'string') return [item.b64_json]; + if (typeof item.url === 'string') return [item.url]; + return []; + }), warnings, response: { timestamp: currentDate, @@ -1662,7 +1722,7 @@ } }; var openaiCompatibleImageResponseSchema = z8.object({ - data: z8.array(z8.object({ b64_json: z8.string() })) + data: z8.array(z8.object({ b64_json: z8.string().nullish(), url: z8.string().nullish() })) }); async function fileToBlob(file) { if (file.type === "url") {