Skip to content

fix(messages): preserve Claude 4.x version suffix so vision routes to the right model#254

Open
dsgn93-creator wants to merge 1 commit intoericc-ch:masterfrom
dsgn93-creator:fix/preserve-claude-4x-version-suffix
Open

fix(messages): preserve Claude 4.x version suffix so vision routes to the right model#254
dsgn93-creator wants to merge 1 commit intoericc-ch:masterfrom
dsgn93-creator:fix/preserve-claude-4x-version-suffix

Conversation

@dsgn93-creator
Copy link
Copy Markdown

Problem

Vision requests through --claude-code mode fail with an internal server error on Copilot Enterprise even though:

  • copilot-vision-request: true is correctly added by create-chat-completions.ts when an image_url part is detected
  • The Anthropic image block is correctly translated to OpenAI image_url with a base64 data URI in mapContent
  • The user's plan (Enterprise) and target model (Opus 4.7) both support vision

The failure is in translateModelName. Copilot lists its Claude models as dot-versioned:

claude-opus-4.7
claude-opus-4.6
claude-sonnet-4.6

…but Claude Code sends dash-versioned IDs with a date suffix, e.g. claude-opus-4-7-20251030. The current regex:

if (model.startsWith("claude-opus-")) {
  return model.replace(/^claude-opus-4-.*/, "claude-opus-4")
}

…rewrites that to plain claude-opus-4, which (a) loses the 4.5/4.6/4.7 capability tier and (b) routes vision-bearing requests to a fallback model that does not have vision enabled — producing the internal server error.

Repro: send any image via Claude Code → 500 from Copilot. Text-only requests succeed because Copilot is forgiving about unknown model aliases for non-vision payloads.

Fix

Match claude-(opus|sonnet|haiku)-N-M(-YYYYMMDD)? and convert dash → dot, producing the actual model ID Copilot exposes (claude-opus-4.7). Legacy fallbacks remain unchanged for any shape that doesn't match.

const versioned = model.match(
  /^claude-(opus|sonnet|haiku)-(\d+)-(\d+)(?:-\d{6,8})?$/,
)
if (versioned) {
  return `claude-${versioned[1]}-${versioned[2]}.${versioned[3]}`
}

Verification

claude-opus-4-7-20251030    -> claude-opus-4.7   ✅
claude-opus-4-6-20250901    -> claude-opus-4.6   ✅
claude-sonnet-4-6-20250901  -> claude-sonnet-4.6 ✅
claude-opus-4-1-20250805    -> claude-opus-4.1   ✅
claude-opus-4               -> claude-opus-4     (legacy, unchanged)
claude-3-5-sonnet-20241022  -> claude-3-5-sonnet-20241022 (passthrough)

After patching locally and reinstalling, vision requests through --claude-code now succeed because Copilot routes them to the actual Opus 4.7 endpoint instead of the unknown-alias fallback.

Related: #16, #36, #60 (all touched the vision pipeline but none addressed the model-name rewriting).

…form

Copilot exposes models as claude-opus-4.7 / claude-opus-4.6 / claude-sonnet-4.6
(dot-versioned), but Claude Code sends dash-versioned IDs with date suffixes
like claude-opus-4-7-20251030. The previous translateModelName regex stripped
the entire suffix and rewrote everything to claude-opus-4 / claude-sonnet-4,
which (a) loses the 4.5/4.6/4.7 capability tier and (b) routes vision
requests to a fallback model that may not have vision enabled — producing
an internal server error when image_url parts are present even though
copilot-vision-request: true is sent.

Convert dash-versioned 4.x families to their dot form
(claude-opus-4-7-20251030 -> claude-opus-4.7) so vision-capable variants
route correctly. Falls back to the previous behavior for unknown shapes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant