[fix] plugin: accept version pinned model names
The pattern that validates the model name rejected "@", so names like gemini-1.5-pro@001 were refused with "no valid model configured". Those names are ordinary on the gateways this plugin can be pointed at, which made the api_key support less useful than it looks. Verified against a LiteLLM gateway serving an alias named gemma4-e4b@001: the model list, the request and the streamed answer all carry the pinned name. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,7 +45,11 @@ if t.TYPE_CHECKING:
|
||||
from . import PluginCfg
|
||||
|
||||
VALID_ROLES = ("user", "assistant")
|
||||
MODEL_NAME_REGEXP = re.compile(r"[A-Za-z0-9._:/-]{1,128}")
|
||||
# Model names differ per provider: "gemma3:4b" (Ollama), "bedrock/anthropic.
|
||||
# claude-3-5-sonnet" (a gateway's routing prefix), "gemini-1.5-pro@001" (a
|
||||
# pinned version). The pattern accepts those and rejects anything that could
|
||||
# change the meaning of the request body it is placed into.
|
||||
MODEL_NAME_REGEXP = re.compile(r"[A-Za-z0-9._:/@-]{1,128}")
|
||||
|
||||
log = logging.getLogger("searx.plugins.ai_summary")
|
||||
|
||||
|
||||
@@ -324,9 +324,29 @@ class PluginAISummary(SearxTestCase):
|
||||
self.assertEqual(res.status_code, 400)
|
||||
|
||||
def test_endpoint_invalid_model_pref(self):
|
||||
self.client.set_cookie("ai_summary_model", "bad model name!")
|
||||
res = self.client.post("/ai_summary", json={"messages": [{"role": "user", "content": "hi"}]})
|
||||
self.assertEqual(res.status_code, 400)
|
||||
# an empty preference is not invalid -- it falls back to the
|
||||
# administrator's default, which is covered by the tests above
|
||||
for model in ["bad model name!", "model;rm -rf", 'model"quoted', "model\nname", "x" * 129]:
|
||||
self.client.set_cookie("ai_summary_model", model)
|
||||
res = self.client.post("/ai_summary", json={"messages": [{"role": "user", "content": "hi"}]})
|
||||
self.assertEqual(res.status_code, 400, model)
|
||||
|
||||
def test_endpoint_accepts_provider_model_names(self):
|
||||
# model names differ per provider: a version pin (@), a gateway's
|
||||
# routing prefix (/) and an Ollama tag (:) are all valid names
|
||||
for model in [
|
||||
"gemma3:4b",
|
||||
"llama3.2:3b",
|
||||
"gemini-1.5-pro@001",
|
||||
"bedrock/anthropic.claude-3-5-sonnet",
|
||||
"azure/my-deployment",
|
||||
]:
|
||||
self.mock_upstream(sse_stream_mock([]))
|
||||
self.client.set_cookie("ai_summary_model", model)
|
||||
res = self.client.post("/ai_summary", json={"messages": [{"role": "user", "content": "hi"}]})
|
||||
self.assertEqual(res.status_code, 200, model)
|
||||
lines = [json.loads(line) for line in res.data.decode().splitlines() if line]
|
||||
self.assertEqual(lines[-1], {"done": True, "model": model})
|
||||
|
||||
def test_endpoint_no_server_configured(self):
|
||||
self.setattr4test(searx.get_setting("ai_summary"), "base_url", "")
|
||||
|
||||
Reference in New Issue
Block a user