fix(codex-bridge): strip a stray ide/ prefix from stored model names
Server CI and Windows package / verify (push) Successful in 4m30s
Server CI and Windows package / windows-package (push) Successful in 16m59s

A hand- or agent-edited jev-settings.json could store a model name that
already carries the gateway's own "ide/" prefix. The bridge adds "ide/"
again when it routes, producing "ide/ide/<model>" — an unknown model whose
context window the bridge reads as the 32768 default and then silently
drops the request, answering "." with a wrong "model seçildi" instead of
the chosen model. jev_settings.read()/_policy() now normalize every stored
model name (fallbackModel, watchModels, exemptModels, prefilter.target,
autoRoute.model/targets) by stripping a leading "ide/". No real
provider/model id begins with "ide/", so valid settings are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
yilsemandClaude Opus 4.8 committed 2026-10-17 02:09:30 +03:00
1 parent 86a6621936
commit 65ce4be58b
2 files changed
+60

No files matched your search

@@ -59,6 +59,42 @@ def _https(value):
return url.scheme == 'https' and bool(url.netloc) and not url.username and not url.password
IDE_PREFIX = 'ide/'
def _strip_ide(value):
"""A stored model name must never carry the gateway's own 'ide/' prefix; the bridge adds it when
it routes. A doubled 'ide/ide/...' makes the bridge treat the name as an unknown model, read its
context window as the 32768 default and silently drop the request. No real provider/model id
begins with 'ide/', so stripping a leading 'ide/' here can only undo an accidental prefix."""
if isinstance(value, str):
while value.startswith(IDE_PREFIX):
value = value[len(IDE_PREFIX):]
return value
def _normalize_models(settings):
"""Strip a stray 'ide/' prefix from every stored model name so routing can never double it."""
if 'fallbackModel' in settings:
settings['fallbackModel'] = _strip_ide(settings['fallbackModel'])
for key in ('watchModels', 'exemptModels'):
values = settings.get(key)
if isinstance(values, list):
settings[key] = [_strip_ide(x) for x in values]
prefilter = settings.get('prefilter')
if isinstance(prefilter, dict) and 'target' in prefilter:
prefilter['target'] = _strip_ide(prefilter['target'])
auto = settings.get('autoRoute')
if isinstance(auto, dict):
if 'model' in auto:
auto['model'] = _strip_ide(auto['model'])
targets = auto.get('targets')
if isinstance(targets, dict):
for key in list(targets):
targets[key] = _strip_ide(targets[key])
return settings
def validate(settings):
"""Raise ValueError when a value could route to the wrong place or wait without bound."""
# A corrupted file must not silently change routing or contact another host.
@@ -115,6 +151,7 @@ def _policy(settings):
for key in POLICY_KEYS:
if isinstance(overrides.get(key), dict):
merged[key] = _fill(overrides[key], settings[key])
_normalize_models(merged)
return validate(merged)
except (OSError, ValueError, KeyError, TypeError, AttributeError):
return settings
@@ -129,6 +166,7 @@ def read(overlay=True):
settings = data['settings']
for section in SECTIONS:
settings[section] = _fill(settings[section], DEFAULTS[section]) if section in settings else copy.deepcopy(DEFAULTS[section])
_normalize_models(settings)
validate(settings)
return (_policy(settings) if overlay else settings), data.get('protectedKey')