fix(codex-bridge): remaining audit findings (routing, trimming, retries, model list fallback, logging)

Second batch from the ten read-only audits; 126 bridge tests. Among them: a spoken number
("opus beş beş") resolves, a used route no longer expires after 7 days, the local reply says how to
go back, an unrouted 9r/ name gets a local 503 instead of going to chatgpt.com, a combo request is not
resent after the upstream closed it, the last model list is served when chatgpt.com is unreachable,
trimming keeps the real last user message, Claude-member combos use the Claude estimate, CRLF SSE is
handled, log lines carry the date and the status endpoint reports a code fingerprint.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
yilsemandClaude Opus 5.5 committed 2026-10-11 01:50:08 +03:00
1 parent e2793fa38f
commit 7c0dc467d5
10 files changed
+731 -101

No files matched your search

+21 -5
View File
@@ -13,10 +13,10 @@ Codex depends on it while `openai_base_url` points here.
The public `/models` catalog supplies every OmniRoute chat model; a member does
not need a private local model allowlist. `/router/catalog` supplies only the
`kind` metadata used for sorting, never additional model IDs. Direct 9Router
entries and internal 9Router combos are excluded. Combos sort A–Z first, then
individual models by provider and name, including OpenAI subscription models.
Codex labels the first visible row `isDefault`; a saved model selection remains
unchanged. A failed or empty refresh keeps the last successful catalog.
entries and internal 9Router combos are excluded. Codex's own subscription models
stay first, in their own order and under their own names; added entries follow
them: combos A–Z, then individual models by provider and name. A saved model
selection remains unchanged. A failed or empty refresh keeps the last successful catalog.
- `ozet_kopru.py`: conversation summaries are produced as plain text, so a summary made
by one provider stays readable after the user switches to another.
- `gemini_context.py`, `resim_context.py`: request fixes for routed models.
@@ -45,6 +45,22 @@ for the chat, i.e. until the user picks another one in the list.
Setting: `sesle_model` (default on).
Audit follow-up (11 Oct 2026, same version number; `GET .../status` now also returns `kod`, the first 8 hex digits
of `bridge.py`'s SHA-256, to tell builds apart):
- Numbers said as words ("opus beş beş", "üç nokta sekiz") and a trailing "ve devam et" no longer drop the command.
- Picking the same model again in the list does not clear a spoken route (Codex sends the same name), so the
bridge's answer says how to go back. A route that is in use no longer expires after 7 days.
- A command is turned into a "model was changed" note only if it took effect; a mid-turn note also reaches a
subscription model when hook messages follow it.
- Combos: a Claude member selects the stricter token estimate; one unknown member no longer switches the overflow
guard off for a known small member; a combo dropped by the peer after the request was sent is not resent.
- An old `9r/…` name without a route gets a local 503 instead of going to chatgpt.com; upstream error bodies
reach Codex whole, with `Retry-After`.
- The last model list is also served when chatgpt.com cannot be reached at all, and is cached when the answer
was gzip-compressed. The old `display_map` setting is no longer read (subscription models keep their names).
- Log lines carry the date; the access-token tail is no longer logged.
### Work handoff instruction (prepared, off by default)
`is_hatti.py`: when `aiturk_hat` is enabled and has a `komut`, the bridge prepends a developer message ("small work
@@ -72,4 +88,4 @@ Not changed: subscription models, their order and names, and everything on the v
Settings in `bridge.json` (all optional): `dis_arac_modu`, `tasma_bekcisi`, `yarim_cevap`, `ozet_kopru.dongu_siniri`, `ozet_kopru.dongu_art_arda`.
A lone `.` sent as the user's message (used to apply a model change during a voice session) is answered by the bridge itself with "<model> hazır." and never reaches a model (`nokta_karsila`, default on). Targets that reject tool calls are remembered (`aracsiz-modeller.json`) and marked "araçsız" in the picker.
A lone `.` sent as the user's message (used to apply a model change during a voice session) is answered by the bridge itself with "<model> seçildi." (the target is not probed, so it does not say "ready") and never reaches a model (`nokta_karsila`, default on). Targets that reject tool calls are remembered (`aracsiz-modeller.json`) and marked "araçsız" in the picker.