|
| 1 | +# 010 — Bug A: Copilot mixed-wire routing (#746 / #748) |
| 2 | + |
| 3 | +Consumed by work-phase wp-a. Verified against dev@478354ee8 (2026-08-02, sol-medium researcher; per-source evidence below). |
| 4 | + |
| 5 | +## Mechanism (decided) |
| 6 | + |
| 7 | +The tree ALREADY owns the correct mechanism; this fix declares data, not new routing: |
| 8 | + |
| 9 | +```text |
| 10 | +hard wire pin |
| 11 | +→ explicit user modelAdapters |
| 12 | +→ registry modelWireDefaults ← the fix adds entries here |
| 13 | +→ provider-wide adapter |
| 14 | +``` |
| 15 | + |
| 16 | +- `src/providers/registry.ts:101` — registry metadata owns mixed-wire defaults (`modelWireDefaults`). |
| 17 | +- `src/providers/registry.ts:140` — registry defaults stay separate from persisted user overrides. |
| 18 | +- `src/server/adapter-resolve.ts:14` — resolver implements the precedence above, preserving credentials/base URL through a copy. |
| 19 | +- `src/providers/registry.ts:1552` — registry defaults constrained to recognized destinations + the two OpenAI wires. |
| 20 | +- `src/server/responses/core.ts:1434` — final route resolves transport, then the effective model adapter. |
| 21 | +- `src/providers/github-copilot-transport.ts:29` — transport has no model argument; do NOT branch here. |
| 22 | + |
| 23 | +Rejected alternatives (with reasons): provider-wide `openai-responses` (breaks Copilot's Claude/Gemini/GPT-4/gpt-5-mini chat models); transport-level switch (wrong owner, no model arg); runtime endpoint probing (quota-cost + nondeterminism; live discovery hints are not routing metadata); new config flag (`modelAdapters` is already the operator escape hatch). |
| 24 | + |
| 25 | +## File map |
| 26 | + |
| 27 | +- MODIFY `src/providers/registry.ts` (github-copilot entry at :1470) — add `modelWireDefaults` with the conservative verified set: |
| 28 | + `gpt-5.3-codex`, `gpt-5.4`, `gpt-5.4-mini`, `gpt-5.5`, `gpt-5.6-luna`, `gpt-5.6-terra` → `"openai-responses"`. |
| 29 | + Refresh the cold-start seed model list as justified by the same evidence (static seed is a cold-start fallback per the entry's FREEZE comment). |
| 30 | +- NEW `tests/github-copilot-wire-defaults.test.ts` — focused suite (cases below). |
| 31 | +- DOCS `docs-site/src/content/docs/guides/providers.md` + `docs-site/src/content/docs/reference/configuration.md` + maintained locales — name the built-in defaults and the `modelAdapters` escape hatch for lead-only models. |
| 32 | +- NO CHANGES: `github-copilot-transport.ts`, `adapter-resolve.ts`, `types.ts`, `derive.ts`. The sampling/credential-replay parts of PR #746 are a separate parity/security unit — out of scope here. |
| 33 | + |
| 34 | +## Model evidence table |
| 35 | + |
| 36 | +| Model | Evidence | Status | In built-in set | |
| 37 | +|---|---|---|---| |
| 38 | +| `gpt-5.3-codex` | #748 field run + Pi metadata declares Responses | field-verified, corroborated | yes | |
| 39 | +| `gpt-5.4` | exact tools+reasoning chat failure + successful Responses run in #748; litellm#23332 | verified Responses-required | yes | |
| 40 | +| `gpt-5.4-mini` | #748 field run + Pi metadata | field-verified, corroborated | yes | |
| 41 | +| `gpt-5.5` | #748 field run + Pi metadata | field-verified, corroborated | yes | |
| 42 | +| `gpt-5.6-luna` | #748 field run + Pi metadata | field-verified, corroborated | yes | |
| 43 | +| `gpt-5.6-terra` | #748 field run + Pi metadata | field-verified, corroborated | yes | |
| 44 | +| `gpt-5.4-nano` | GitHub catalog + Pi labels; NOT in captured catalog, never field-run | lead-only | NO — document `modelAdapters` override | |
| 45 | +| `gpt-5.6-sol` | #748 claims a run; JetBrains LLM-29711 shows tools+reasoning rejected on chat; no authoritative endpoint contract | lead-only | NO — document `modelAdapters` override | |
| 46 | + |
| 47 | +Exact normalized-ID lookup only — no family/snapshot prefix matching (this tree's resolver behavior; PR #746's dated-snapshot matching was dropped at its final head too). |
| 48 | + |
| 49 | +## Acceptance + activation scenarios |
| 50 | + |
| 51 | +1. `gpt-5.4` via the github-copilot preset resolves to the Responses wire and the upstream request goes to the Responses endpoint, never `/chat/completions`. Activation: captured-upstream-URL test (runtime-wire proof, not just resolver proof). |
| 52 | +2. All six built-in models resolve Responses on all three inbound wires (Responses, Chat Completions, Anthropic inbound). Activation: parametrized resolver + URL tests. |
| 53 | +3. Explicit user `modelAdapters` override beats the registry default in BOTH directions (user pins a listed model back to chat; user maps `gpt-5.6-sol` to Responses). Activation: precedence tests. |
| 54 | +4. Chat-served Copilot models (`gpt-4o`, `gpt-4.1`, `claude-sonnet-4`, `gemini-2.5-pro`, `gpt-5-mini`) still use chat completions. Activation: regression assertions on the existing seed set. |
| 55 | +5. Unrelated providers are isolated (no wire change for non-copilot providers with same-named models). Activation: isolation test. |
| 56 | +6. Credentials/base URL preserved through the resolved copy. Activation: adapter-resolve test shape per `adapter-resolve.ts:14`. |
| 57 | + |
| 58 | +## Verification gate |
| 59 | + |
| 60 | +`bun test tests/github-copilot-wire-defaults.test.ts` + `bun run typecheck` + `bun run test` (registry is shared) + `bun run privacy:scan`. |
0 commit comments