fix: strip @provider: prefix from auxiliary title_generation model id (#3430, @pamnard)

Manual title regeneration (POST /api/session/title/regenerate) and background
aux title generation failed with 422 / llm_error_aux when
auxiliary.title_generation.model in config.yaml used the WebUI-internal
@provider:model picker format (e.g. @gemini:gemini-3.1-flash-lite) — the raw
@-qualified id was forwarded to the provider API verbatim. Normalize it through
the canonical _split_webui_provider_model_value() helper before the aux call.

Co-authored-by: pamnard <pamnard@users.noreply.github.com>
This commit is contained in:
nesquena-hermes
2026-06-02 21:14:49 +00:00
parent b9a0b77baa
commit c556d649b7
2 changed files with 46 additions and 0 deletions

View File

@@ -1801,6 +1801,17 @@ def generate_title_raw_via_aux(
provider = ''
model = model or configured.get('model', '') or ''
base_url = base_url or configured.get('base_url', '') or ''
try:
from api.profiles import _split_webui_provider_model_value
normalized_model, normalized_provider = _split_webui_provider_model_value(
model or None,
provider or None,
)
model = normalized_model or ''
provider = normalized_provider or ''
except ValueError:
pass
api_key = ''
if not caller_supplied_route:
api_key = str(configured.get('api_key', '') or '').strip()

View File

@@ -109,6 +109,41 @@ class TestGenerateTitleRawViaAuxTimeout(unittest.TestCase):
30.0,
)
def test_webui_prefixed_model_id_is_stripped_before_aux_call(self):
"""Regression: @provider:model picker ids must not reach provider APIs verbatim."""
from api.streaming import generate_title_raw_via_aux
mock_resp = types.SimpleNamespace(
choices=[
types.SimpleNamespace(
message=types.SimpleNamespace(content='Gemini Title'),
finish_reason='stop',
)
]
)
captured = {}
def fake_call_llm(**kwargs):
captured.update(kwargs)
return mock_resp
tg_config = {
'provider': 'gemini',
'model': '@gemini:gemini-3.1-flash-lite',
'base_url': '',
}
with _patch_tg_config(tg_config):
with patch('agent.auxiliary_client.call_llm', side_effect=fake_call_llm, create=True):
result, status = generate_title_raw_via_aux(
user_text='Как настроить title generation?',
assistant_text='Нужно указать auxiliary.title_generation в config.yaml.',
)
self.assertEqual(result, 'Gemini Title')
self.assertEqual(status, 'llm_aux')
self.assertEqual(captured.get('provider'), 'gemini')
self.assertEqual(captured.get('model'), 'gemini-3.1-flash-lite')
def test_configured_provider_model_and_base_url_are_passed_to_aux_client(self):
"""Regression for #2235: task config must select the first title model.