Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
ebc6921
fix(combo): continue reasoning effort fallback
omar391 Nov 4, 2026
b2c99b5
test(combo): cover reasoning effort ladder fallback
omar391 Nov 4, 2026
02fd104
fix(combo): unwrap data: refusal and preserve 400 on unbudgeted effor…
omar391 Nov 6, 2026
b2fe595
merge upstream/dev
omar391 Nov 7, 2026
807a788
test(combo): cover unfunded downgrade send budget exhaustion and fall…
omar391 Nov 7, 2026
0077d86
fix(responses): update passthrough rawBody reasoning effort on downgr…
omar391 Nov 7, 2026
670df5b
fix(combo): keep effort ladder retries inside dispatch caps and budge…
lidge-jun Nov 8, 2026
f5f27ed
test(combo): pin the unfunded effort rung on a real five-rung ladder
lidge-jun Nov 8, 2026
4b3660b
fix(combo): stop effort downgrade on policy refusal and reject malfor…
omar391 Nov 8, 2026
d05fd2e
fix(combo): parse nested refusals before effort retry and reject conf…
omar391 Nov 8, 2026
a9faeca
fix(combo): pin root code classification against dev and verify combo…
omar391 Nov 8, 2026
3ecc0d8
fix(combo): traverse object envelopes for policy refusals and reject …
omar391 Nov 8, 2026
f2438d2
fix(combo): inspect serialized provider wrappers for conflicting code…
omar391 Nov 8, 2026
a64e0a7
fix(combo): reject competing carriers, fail closed on incomplete wrap…
omar391 Nov 8, 2026
27770ef
fix(combo): fail closed on incomplete outer objects and reject compet…
omar391 Nov 8, 2026
fd217db
fix(combo): fail closed on oversized diagnostic arrays and inspect er…
omar391 Nov 8, 2026
cdf68c7
fix(combo): inspect serialized diagnostics in arrays and limit effort…
omar391 Nov 8, 2026
0a207b1
fix(combo): parse serialized diagnostic messages and inspect detail c…
omar391 Nov 8, 2026
d1b5b35
fix(combo): reconcile competing diagnostic parameters and preserve de…
omar391 Nov 8, 2026
559ff61
fix(combo): reconcile non-effort parameters across carriers and prese…
omar391 Nov 8, 2026
4a37b53
Merge upstream/dev into fix/combo-reasoning-effort-fallback
omar391 Nov 8, 2026
18cb9e3
fix(combo): fail closed on malformed structured diagnostics before ef…
omar391 Nov 8, 2026
ac9952d
Merge upstream/dev into fix/combo-reasoning-effort-fallback
omar391 Nov 8, 2026
239fe3f
Merge upstream/dev into fix/combo-reasoning-effort-fallback
omar391 Nov 8, 2026
a636e4e
fix(reasoning): extract prefixed JSON diagnostic envelopes in hard re…
omar391 Nov 8, 2026
ecd01a0
fix(reasoning): fail closed on malformed bracket diagnostics and sync…
omar391 Nov 8, 2026
ac8b6f6
fix(reasoning): preserve hard-refusal envelope prefixes and parse ser…
omar391 Nov 8, 2026
24cc2d1
Merge upstream/dev into fix/combo-reasoning-effort-fallback
omar391 Nov 8, 2026
582583f
fix(reasoning): preserve conflicting envelope prefix text and qualify…
omar391 Nov 8, 2026
637c9ad
fix(combo): reconcile effort diagnostics, retain rebuild errors, and …
omar391 Nov 8, 2026
d90f622
Merge remote-tracking branch 'upstream/dev' into fix/combo-reasoning-…
omar391 Nov 8, 2026
aec4d88
fix(combo): preserve rotated refusal without aborting upstream signal
omar391 Nov 8, 2026
16d998d
fix(reasoning): fail closed on malformed bracket diagnostics and add …
omar391 Nov 8, 2026
7ac5737
Merge remote-tracking branch 'origin/dev' into HEAD
invalid-email-address Nov 9, 2026
f1649ea
fix(combo): reconcile competing diagnostic prose and prioritize cance…
omar391 Nov 9, 2026
15b4c48
Merge remote-tracking branch 'upstream/dev' into HEAD
omar391 Nov 9, 2026
006b2f5
chore(layout): pack layout entries to stay within 2000-line cap
omar391 Nov 9, 2026
b7d49a3
fix(reasoning): reconcile diagnostic subject for unlisted field names…
omar391 Nov 9, 2026
774ab4d
Merge remote-tracking branch 'upstream/dev' into fix/combo-reasoning-…
omar391 Nov 9, 2026
eb0b378
fix(reasoning): classify effort keywords as generic param words to su…
omar391 Nov 9, 2026
2dc0d6f
fix(reasoning): distinguish effort-value descriptions in context from…
omar391 Nov 9, 2026
478cf57
fix(providers): keep named effort value in diagnostic context eligibl…
omar391 Nov 9, 2026
12701a6
fix(providers): distinguish explicit field subjects from effort value…
omar391 Nov 9, 2026
7f06933
fix(providers): preserve explicitly named competing fields through de…
omar391 Nov 9, 2026
0fac6a3
Merge remote-tracking branch 'upstream/dev' into fix/combo-reasoning-…
omar391 Nov 9, 2026
2e5099c
fix(providers): recognize unquoted parameter subjects and ultra effor…
omar391 Nov 9, 2026
6a3eb49
Merge remote-tracking branch 'upstream/dev' into fix/combo-reasoning-…
omar391 Nov 9, 2026
18d7234
fix(providers): distinguish verbs following effort parameter from unq…
omar391 Nov 9, 2026
ace97bd
Merge remote-tracking branch 'upstream/dev' into fix/combo-reasoning-…
omar391 Nov 9, 2026
7741ab3
fix(providers): keep canonical effort refusals repairable
Nov 10, 2026
c1bc2ed
Merge origin/dev into fix/combo-reasoning-effort-fallback
lidge-jun Nov 10, 2026
0503252
fix(providers): read PascalCase error codes and 'not valid' as effort…
lidge-jun Nov 10, 2026
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
4 changes: 2 additions & 2 deletions docs-site/src/content/docs/fr/guides/combos.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ Les échecs d’un combo se répartissent entre ceux qui entraînent un **bascul
| Erreur classée comme erreur d’authentification, d’abonnement, de quota, de limitation de débit, de surcharge ou de serveur en amont | Place la cible en période de refroidissement et bascule, même si le statut seul ne suffit pas. |
| Annulation client (499), `origin_rejected`, refus de cyber-politique ou autre demande invalide | Arrêtez et renvoyez l'erreur ; une autre cible ne rendrait pas la demande valide. |
| Dépassement de contexte confirmé avant la sortie, y compris HTTP 400 | Essaie la prochaine cible admissible non tentée sans refroidissement ; à épuisement, renvoie la première erreur de contexte HTTP 400 confirmée (un refus de contexte avec un autre statut fait aussi passer à la cible suivante, sans être conservé). |
| Rejet structuré de `user`, valeur non prise en charge pour `reasoning.effort`/`reasoning_effort`, rejet d'entrée d'image propre à un modèle (`param: input`), ou refus d'un média d'entrée que la route ne peut pas lire (`unsupported_input_modality`) | Bascule vers la cible admissible suivante avant le début de la sortie, sans délai de refroidissement ; voir Compatibilité des paramètres facultatifs ci-dessous. |
| Rejet structuré de `user`, valeur non prise en charge pour `reasoning.effort`/`reasoning_effort`, rejet d'entrée d'image propre à un modèle (`param: input`), ou refus d'un média d'entrée que la route ne peut pas lire (`unsupported_input_modality`) | En cas de refus d'effort, tente le niveau publié immédiatement inférieur sur la même cible tant que le budget d'envoi le permet ; si aucun niveau ne fonctionne, bascule avant l'engagement de sortie sans refroidissement si le refus correspond à une enveloppe de compatibilité reconnue, sinon reste terminal. Les autres incompatibilités répertoriées basculent sans refroidissement ; voir Compatibilité des paramètres facultatifs ci-dessous. |
| Premier appel d'outil d'un tour Responses exécuté par un adaptateur interne (`runTurn`) que la requête courante n'a pas déclaré, avant toute sortie et tout effet de bord non rejouable | Met la cible en refroidissement et bascule avec le même catalogue d'outils. Après une sortie visible ou un effet de bord non rejouable, le refus est définitif. Les requêtes Chat Completions et Anthropic Messages ne changent pas. |
| Toute autre erreur non classifiée | Arrêtez et renvoyez l'erreur. |

Expand Down Expand Up @@ -378,7 +378,7 @@ gérer un refus de politique ou corriger l’origine de la demande rejetée. Les

## Compatibilité des paramètres facultatifs

Exception aux erreurs 400 terminales : un rejet structuré de `user`, une valeur non prise en charge pour `reasoning.effort`/`reasoning_effort`, un rejet d’entrée d’image propre à un modèle (`param: input`), ou le refus d’un média d’entrée que la route ne peut pas lire (`unsupported_input_modality`) peut faire passer le combo à la cible admissible suivante avant le début de la sortie, sans délai de refroidissement. Le refus de sécurité, l’annulation et une sortie déjà commencée restent non rejouables.
Exception aux erreurs 400 terminales : un rejet structuré de `user`, une valeur non prise en charge pour `reasoning.effort`/`reasoning_effort`, un rejet d’entrée d’image propre à un modèle (`param: input`), ou le refus d’un média d’entrée que la route ne peut pas lire (`unsupported_input_modality`), ainsi qu'après l'enveloppe fournisseur exacte `{"code":"invalid-argument","error":"Invalid reasoning effort."}`. Lorsqu'une cible de combo refuse l'effort de raisonnement demandé, le combo réessaye d'abord cette cible au niveau d'effort publié immédiatement inférieur, un niveau par refus et dans la limite du budget d'envoi partagé ; cela s'applique à tout refus d'effort reconnu. Si aucun niveau inférieur ne réussit, un refus correspondant à l'une des formes ci-dessus passe à une autre cible sans refroidir la cible rejetée, en conservant le 400 initial de cette cible lorsqu'il ne reste plus d'envoi disponible pour le niveau suivant ; les autres refus d'effort restent terminaux. Une route qui refuse le média de la requête avec le code `unsupported_input_modality` avance de la même façon. Ce sont des incompatibilités pour cette requête, et non la preuve que la cible est défaillante. Les requêtes directes conservent leur réparation unique par rétrogradation d'effort. La récupération de compatibilité ne transforme pas silencieusement `none` en un effort différent et n'élargit pas le saut de combo à des requêtes invalides arbitraires. Le refus de sécurité, l’annulation et une sortie déjà commencée restent non rejouables. Une requête à cible unique renvoie toujours un rejet non résolu en amont.

[Canonical compatibility details](/guides/combos/#request-local-target-compatibility).

Expand Down
4 changes: 2 additions & 2 deletions docs-site/src/content/docs/guides/combos.md
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ provider, see [Fallback off](/guides/fallback-off/).
| Confirmed context-window overflow before output, including HTTP 400 | Try the next untried eligible target without cooling this target; another model may have a larger window. Exhaustion returns the first confirmed HTTP 400 context-length error; a context refusal sent with another status still advances but is not retained. |
| Client cancellation (499), `origin_rejected`, cyber-policy refusal, or other invalid request | Stop and return the error; another target would not make the request valid. |
| Exact HTTP 400 saying a model is not supported when using Codex with a ChatGPT account | Try the next declared target before output commitment. The message must be the whole refusal in `detail`, `error.message`, or bare text; competing `detail` and `error` envelopes stay terminal. This does not quarantine the account or cool every model on the provider. |
| Structured HTTP 400 rejecting optional `user`, an unsupported reasoning effort, model-scoped image input, or input media the route cannot read (`unsupported_input_modality`) | Hop before output commitment without cooling; see request-local target compatibility below. |
| Structured HTTP 400 rejecting optional `user`, an unsupported reasoning effort, model-scoped image input, or input media the route cannot read (`unsupported_input_modality`) | For an effort refusal, try the next lower published rung on the same target while the send budget allows; if no rung works, hop before output commitment without cooling if the refusal matches a recognized compatibility shape, otherwise stay terminal. Other listed mismatches hop without cooling; see request-local target compatibility below. |
| First tool call of a Responses turn run by an in-process adapter (`runTurn`) that the current request did not declare, before any output or replay-unsafe side effect | Cool the target and hop with the same tool catalog. After visible output or a replay-unsafe side effect the refusal is final. Chat Completions and Anthropic Messages requests are unchanged. |
| Any other unclassified error | Stop and return the error. |

Expand Down Expand Up @@ -832,7 +832,7 @@ OpenCodex also commits the current target instead of growing memory without a bo

When routing Claude Code to the canonical ChatGPT Codex backend, OpenCodex removes the unsupported top-level `user` metadata field without changing the session/cache key, input messages, tool schemas, or safety identifiers. Public Responses API and noncanonical forward gateways keep that field.

A combo can also advance after an intact HTTP 400 `invalid_request_error` that specifically rejects `user`, reports `unsupported_value` for `reasoning.effort`/`reasoning_effort`, or reports `param: input` with an exact model-scoped `does not support image inputs` rejection. A route that refuses the request's media with code `unsupported_input_modality`, such as image input sent to a CLI provider route without a verified multimodal contract, advances the same way. This is a mismatch for that request, not evidence that the target is unhealthy, so it records no cooldown. This compatibility recovery does not silently change `none` into a different effort or broaden this exception to arbitrary invalid requests. Policy refusals, cancellation and already-committed output remain non-replayable. A single-target request still returns an unresolved upstream rejection.
A combo can also advance after an intact HTTP 400 `invalid_request_error` that specifically rejects `user`, reports `unsupported_value` for `reasoning.effort`/`reasoning_effort`, or reports `param: input` with an exact model-scoped `does not support image inputs` rejection, and after the exact vendor envelope `{"code":"invalid-argument","error":"Invalid reasoning effort."}`. When a combo target refuses the requested reasoning effort, the combo first retries that target at the next lower published effort rung, one rung per refusal and within the shared send budget; this applies to any recognized effort refusal. If no lower rung succeeds, a refusal in one of the shapes above advances to another target without cooling the rejected one, keeping that target's original 400 when the next rung has no send left; other effort refusals stay terminal. A route that refuses the request's media with code `unsupported_input_modality`, such as image input sent to a CLI provider route without a verified multimodal contract, advances the same way. These are mismatches for this request, not evidence that the target is unhealthy. Direct requests retain their single effort-downgrade repair. Compatibility recovery does not silently change `none` into a different effort or broaden the combo hop to arbitrary invalid requests. Policy refusals, cancellation and already-committed output remain non-replayable. A single-target request still returns an unresolved upstream rejection.

## Tool calls stay on one target

Expand Down
4 changes: 2 additions & 2 deletions docs-site/src/content/docs/ja/guides/combos.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ ocx combo set balanced \
|クライアントのキャンセル (499)、`origin_rejected`、サイバー ポリシーの拒否、またはその他の無効なリクエスト |停止してエラーを返します。別のターゲットではリクエストは有効になりません。 |
| 出力前に確認したコンテキスト超過(HTTP 400 を含む) | クールダウンせず次の未試行の適格な対象へ進み、使い切った場合は最初に確認した HTTP 400 のコンテキストエラーを返します(他のステータスのコンテキスト拒否も次へ進みますが、保持されません)。 |
| ChatGPT アカウントで Codex を使う際に、そのモデルをサポートしないことを示す正確な HTTP 400 の拒否 | 出力を確定する前に、次の設定済みターゲットを試します。拒否文全体が `detail`、`error.message`、または本文そのものにある場合に限ります。`detail` と `error` が競合する応答は終了扱いです。この拒否だけでアカウントを再認証待ちにしたり、プロバイダーの全モデルをクールダウンしたりしません。 |
|`user` の明示的な拒否、`reasoning.effort`/`reasoning_effort` の非対応値、モデル固有の画像入力拒否(`param: input`)、またはルートが読み取れない入力メディアの拒否(`unsupported_input_modality`)を示す構造化 HTTP 400 |出力開始前に次の適格なターゲットへ進み、クールダウンを記録しません。任意パラメーターの互換性を参照してください。 |
|`user` の明示的な拒否、`reasoning.effort`/`reasoning_effort` の非対応値、モデル固有の画像入力拒否(`param: input`)、またはルートが読み取れない入力メディアの拒否(`unsupported_input_modality`)を示す構造化 HTTP 400 |推論エフォートの拒否の場合、送信バジェットが許す限り同じターゲットで次に低い公開ラングを試行します。どのラングも機能しない場合は、認識された互換性のある形式に一致すれば冷却せずに出力確定前に次のターゲットへ進み、それ以外は終了します。その他の記載された不一致はクールダウンなしで進みます。任意パラメーターの互換性を参照してください。 |
|インプロセスアダプター(`runTurn`)が実行する Responses ターンで、現在のリクエストが宣言していない最初のツール呼び出し(出力やリプレイ不可の副作用より前) |ターゲットをクールダウンし、同じツールカタログで次へ進みます。可視出力やリプレイ不可の副作用の後は拒否が確定します。Chat Completions と Anthropic Messages のリクエストは変わりません。 |
|その他の未分類のエラー |停止してエラーを返します。 |

Expand Down Expand Up @@ -275,7 +275,7 @@ ocx combo remove <id> --yes

## 任意パラメーターの互換性

通常の 400 エラーは終了扱いですが、`user` の明示的な拒否、`reasoning.effort`/`reasoning_effort` の非対応値、モデル固有の画像入力拒否(`param: input`)、またはルートが読み取れない入力メディアの拒否(`unsupported_input_modality`)を示す構造化エラーでは、出力開始前に次の適格なターゲットへ進めます。この不一致ではクールダウンを記録しません。安全ポリシーによる拒否、キャンセル、出力開始後の再実行は禁止のままです。
通常の 400 エラーは終了扱いですが、`user` の明示的な拒否、`reasoning.effort`/`reasoning_effort` の非対応値、モデル固有の画像入力拒否(`param: input`)、またはルートが読み取れない入力メディアの拒否(`unsupported_input_modality`)を示す構造化エラー、およびベンダーエンベロープ `{"code":"invalid-argument","error":"Invalid reasoning effort."}` では、出力確定前に次の適格なターゲットへ進めます。コンボターゲットが要求された推論エフォートを拒否した場合、コンボはまずそのターゲットで次に低い公開エフォートラングを、拒否ごとに1ラングずつ、共有送信バジェットの範囲内で再試行します。これは認識されたすべてのエフォート拒否に適用されます。より低いラングがいずれも成功しない場合、上記のいずれかの形式の拒否は拒否されたターゲットを冷却することなく別のターゲットへ進み、次のラングに送信枠が残っていない場合はそのターゲットの元の 400 を保持します。その他のエフォート拒否は終了扱いのままです。メディアを `unsupported_input_modality` で拒否するルートも同様に進みます。これらはこのリクエストに対する不一致であり、ターゲットが異常である証拠ではありません。直接リクエストは単一のエフォートダウングレード修復を保持します。互換性回復によって `none` が別のエフォートに暗黙に変更されたり、任意の無効なリクエストにコンボホップが拡大されたりすることはありません。安全ポリシーによる拒否、キャンセル、出力開始後の再実行は禁止のままです。単一ターゲットのリクエストは未解決の上流拒否を返します。

[Canonical compatibility details](/guides/combos/#request-local-target-compatibility).

Expand Down
Loading
Loading