diff --git a/packages/ai/src/protocols/cohere-chat.ts b/packages/ai/src/protocols/cohere-chat.ts index 876d5e297660..a32f9eefc6ae 100644 --- a/packages/ai/src/protocols/cohere-chat.ts +++ b/packages/ai/src/protocols/cohere-chat.ts @@ -190,7 +190,7 @@ const fromRequest = Effect.fn("CohereChat.fromRequest")(function* (request: LLMR calls.push({ id: part.id, type: "function", function: { name: part.name, arguments: args } }) continue } - if (message.role === "user" && part.type === "media" && part.media.mediaType.startsWith("image/")) { + if (message.role === "user" && part.type === "media" && part.media.mediaType.toLowerCase().startsWith("image/")) { const url = ProviderShared.mediaUrl(part.media) ?? (yield* ProviderShared.requireInlineMedia("Cohere Chat", part.media)).dataUrl diff --git a/packages/ai/test/provider/cohere.test.ts b/packages/ai/test/provider/cohere.test.ts index 608c5d247de6..bb41d719ff4a 100644 --- a/packages/ai/test/provider/cohere.test.ts +++ b/packages/ai/test/provider/cohere.test.ts @@ -209,6 +209,31 @@ it.effect("Cohere rejects unsupported media instead of silently dropping it", () }), ) +it.effect("Cohere accepts image media regardless of MIME type casing", () => + Effect.gen(function* () { + const prepared = yield* compileRequest( + LLM.request({ + model: cohere.model("command-a-03-2025"), + messages: [ + Message.user([ + { type: "media", media: Media.base64("aGVsbG8=", "IMAGE/PNG") }, + { type: "media", media: Media.url("https://files.example/pic.png", { mediaType: "Image/Png" }) }, + ]), + ], + }), + ) + expect(prepared.body.messages).toMatchObject([ + { + role: "user", + content: [ + { type: "image_url", image_url: { url: "data:image/png;base64,aGVsbG8=" } }, + { type: "image_url", image_url: { url: "https://files.example/pic.png" } }, + ], + }, + ]) + }), +) + it.effect("Cohere thinking budgets must be positive integers", () => Effect.gen(function* () { const error = yield* compileRequest(