* feat(sse): route GitHub Copilot Claude models through native /v1/messages
GitHub Copilot's /chat/completions and /responses endpoints never surface
prompt-cache token counts (cached_tokens) for Claude models, and round-tripping
Claude tool_use/tool_result/thinking content blocks through the OpenAI shape
is lossy. Copilot also exposes an Anthropic-native /v1/messages shim that
reports cached_tokens correctly and accepts native content blocks as-is.
Tag each github registry claude-* model with targetFormat: "claude" so
chatCore.ts translates the request to Anthropic-native shape before the
executor ever sees it (the same mechanism opencode/zen's Qwen entries and
opencode/go already use), and teach the github executor's buildUrl() /
buildHeaders() to dispatch those models at the new messagesUrl
(api.githubcopilot.com/v1/messages) with the required anthropic-version
header. transformRequest() now skips its /chat/completions-only quirks
(content-part flattening, trailing-assistant-prefill drop, the
response_format-as-system-prompt workaround) for the native path — the first
would destroy native tool_use/tool_result blocks, the prefill drop is
unnecessary because the real Anthropic API supports assistant prefill, and
the response_format workaround is superseded by the generic openai-to-claude
translator's own JSON-mode handling.
Co-authored-by: luoyide <ydhome.code@gmail.com>
Inspired-by: https://github.com/decolua/9router/pull/2608
* chore(changelog): fragment for #7223
* fix(sse): green PR #7223 CI — complexity ratchet + stale test expectations
- Extract applyChatCompletionsOnlyQuirks() and resolveInitiatorHeader()
out of GithubExecutor.transformRequest()/buildHeaders() so the two
methods drop back under the complexity/cognitive-complexity ratchets
(2058/891 -> 2056/890, matching the frozen baseline). No behavior
change — same guards, just relocated.
- Update 4 pre-existing unit tests that hard-coded now-native claude-*
Copilot ids (claude-sonnet-4.5/4.6) to exercise the /chat/completions
legacy path via an unregistered id (claude-sonnet-4), matching the
sibling test already using that pattern. These ids now intentionally
route to the native /v1/messages shim added by this PR, which
correctly skips the /chat/completions-only workarounds these tests
were built to verify — the native path's own coverage lives in
github-copilot-claude-native-messages.test.ts.
- Split the routing invariant test (copilot-gemini-claude-route-no-responses.test.ts)
into a Claude case (expects /v1/messages) and a Gemini case (still
expects /chat/completions), reflecting the intentional routing change.
---------
Co-authored-by: luoyide <ydhome.code@gmail.com>