Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/routes/responses/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ export async function handleResponses(c: Context) {
contentLength: c.req.header('content-length') ?? undefined,
})

// Filter out unsupported tools (e.g. image_generation) before forwarding
const FILTERED_TOOL_TYPES = new Set(['image_generation'])
if (payload.tools?.length) {
const before = payload.tools.length
payload.tools = payload.tools.filter(t => !FILTERED_TOOL_TYPES.has(t.type))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silently dropping image_generation here changes the request semantics before routing. For direct Responses-backed models, a request that explicitly provided this hosted tool now succeeds without the tool instead of surfacing Copilot's unsupported result; for Anthropic-routed models this also removes a hosted tool before assertResponsesPayloadTranslatable, so a request that should be rejected as not translatable can be forwarded as tool-less. That conflicts with the proxy capability policy to keep upstream behavior as the source of truth and avoid false-success compatibility shims. Please either keep forwarding and let upstream reject, or gate a client-specific fallback with regression tests that preserve the existing hosted-tool rejection semantics.

if (payload.tools.length !== before) {
consola.debug(`Filtered ${before - payload.tools.length} unsupported tool(s): ${[...FILTERED_TOOL_TYPES].join(', ')}`)
}
}

if (responsesHasExternalImageUrls(payload)) {
throwOpenAIInvalidRequestError(OPENAI_EXTERNAL_IMAGE_URLS_UNSUPPORTED_MESSAGE)
}
Expand Down