diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 8e64cde3..18f2909a 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -12,6 +12,8 @@ - **Google baseUrl configuration**: Google provider now respects `baseUrl` configuration for custom endpoints or API proxies. ([#216](https://github.com/badlogic/pi-mono/issues/216), [#221](https://github.com/badlogic/pi-mono/pull/221) by [@theBucky](https://github.com/theBucky)) +- **GitHub Copilot vision requests**: Added `Copilot-Vision-Request` header when sending images to GitHub Copilot models. ([#222](https://github.com/badlogic/pi-mono/issues/222)) + ## [0.22.3] - 2025-12-16 ### Added diff --git a/packages/ai/src/providers/openai-completions.ts b/packages/ai/src/providers/openai-completions.ts index d817b25a..879cdd15 100644 --- a/packages/ai/src/providers/openai-completions.ts +++ b/packages/ai/src/providers/openai-completions.ts @@ -309,6 +309,20 @@ function createClient(model: Model<"openai-completions">, context: Context, apiK const isAgentCall = lastMessage ? lastMessage.role !== "user" : false; headers["X-Initiator"] = isAgentCall ? "agent" : "user"; headers["Openai-Intent"] = "conversation-edits"; + + // Copilot requires this header when sending images + const hasImages = messages.some((msg) => { + if (msg.role === "user" && Array.isArray(msg.content)) { + return msg.content.some((c) => c.type === "image"); + } + if (msg.role === "toolResult" && Array.isArray(msg.content)) { + return msg.content.some((c) => c.type === "image"); + } + return false; + }); + if (hasImages) { + headers["Copilot-Vision-Request"] = "true"; + } } return new OpenAI({ diff --git a/packages/ai/src/providers/openai-responses.ts b/packages/ai/src/providers/openai-responses.ts index 58538055..8d577276 100644 --- a/packages/ai/src/providers/openai-responses.ts +++ b/packages/ai/src/providers/openai-responses.ts @@ -317,6 +317,20 @@ function createClient(model: Model<"openai-responses">, context: Context, apiKey const isAgentCall = lastMessage ? lastMessage.role !== "user" : false; headers["X-Initiator"] = isAgentCall ? "agent" : "user"; headers["Openai-Intent"] = "conversation-edits"; + + // Copilot requires this header when sending images + const hasImages = messages.some((msg) => { + if (msg.role === "user" && Array.isArray(msg.content)) { + return msg.content.some((c) => c.type === "image"); + } + if (msg.role === "toolResult" && Array.isArray(msg.content)) { + return msg.content.some((c) => c.type === "image"); + } + return false; + }); + if (hasImages) { + headers["Copilot-Vision-Request"] = "true"; + } } return new OpenAI({