fix: route telegram vision through ollama first
All checks were successful
CD Pipeline / deploy (push) Successful in 1m4s

This commit is contained in:
OoO
2026-05-18 14:07:49 +08:00
parent b361ca7723
commit c021945047
10 changed files with 283 additions and 48 deletions

View File

@@ -41,6 +41,7 @@ def test_registry_contains_core_callers():
'sales_copy', 'trend_match', 'trend_qa', 'product_insights',
# Bot
'openclaw_bot_main', 'openclaw_bot_gemini', 'openclaw_bot_nim',
'openclaw_bot_image', 'openclaw_bot_image_gemini',
}
missing = must_have - CALLER_REGISTRY

View File

@@ -149,6 +149,124 @@ def test_is_authorized_private_mode_switch(monkeypatch):
assert bot._is_authorized("private", 777, 42) is False
def test_photo_message_uses_ollama_vision_before_gemini(monkeypatch):
from routes import openclaw_bot_routes as bot
sent = []
handled = []
class FakeResponse:
def __init__(self, json_data=None, content=b"fake-image"):
self._json_data = json_data or {}
self.content = content
def json(self):
return self._json_data
def fake_get(url, **_kwargs):
if "getFile" in url:
return FakeResponse({"result": {"file_path": "photos/product.jpg"}})
return FakeResponse(content=b"fake-image")
monkeypatch.setattr(bot.requests, "get", fake_get)
monkeypatch.setattr(bot, "_is_authorized", lambda _chat_type, _chat_id, _uid: True)
monkeypatch.setattr(bot, "send_typing", lambda _chat_id: None)
monkeypatch.setattr(
bot,
"send_message",
lambda *args, **kwargs: sent.append((args, kwargs)),
)
monkeypatch.setattr(
bot,
"handle_cmd",
lambda cmd, arg, chat_id, reply_to: handled.append((cmd, arg, chat_id, reply_to)),
)
monkeypatch.setattr(
bot,
"_identify_product_name_with_ollama_vision",
lambda img_b64, request_id: "理膚寶水 B5 修復霜",
)
monkeypatch.setattr(
bot,
"_identify_product_name_with_gemini_vision",
lambda img_b64, request_id: (_ for _ in ()).throw(AssertionError("Gemini should not run first")),
)
app = _build_request_app()
payload = {
"update_id": 10030,
"message": {
"message_id": 80,
"chat": {"id": 777, "type": "private"},
"from": {"id": 777777},
"photo": [{"file_id": "small"}, {"file_id": "large"}],
},
}
with app.test_request_context("/bot/telegram/webhook", method="POST", json=payload):
bot.telegram_webhook()
assert handled == [("competitor", "理膚寶水 B5 修復霜", 777, 80)]
assert "理膚寶水 B5 修復霜" in sent[0][0][1]
def test_photo_message_falls_back_to_gemini_when_ollama_empty(monkeypatch):
from routes import openclaw_bot_routes as bot
handled = []
calls = []
class FakeResponse:
def __init__(self, json_data=None, content=b"fake-image"):
self._json_data = json_data or {}
self.content = content
def json(self):
return self._json_data
def fake_get(url, **_kwargs):
if "getFile" in url:
return FakeResponse({"result": {"file_path": "photos/product.jpg"}})
return FakeResponse(content=b"fake-image")
def fake_ollama(_img_b64, _request_id):
calls.append("ollama")
return ""
def fake_gemini(_img_b64, _request_id):
calls.append("gemini")
return "飛利浦 Sonicare"
monkeypatch.setattr(bot.requests, "get", fake_get)
monkeypatch.setattr(bot, "_is_authorized", lambda _chat_type, _chat_id, _uid: True)
monkeypatch.setattr(bot, "send_typing", lambda _chat_id: None)
monkeypatch.setattr(bot, "send_message", lambda *args, **kwargs: None)
monkeypatch.setattr(
bot,
"handle_cmd",
lambda cmd, arg, chat_id, reply_to: handled.append((cmd, arg, chat_id, reply_to)),
)
monkeypatch.setattr(bot, "_identify_product_name_with_ollama_vision", fake_ollama)
monkeypatch.setattr(bot, "_identify_product_name_with_gemini_vision", fake_gemini)
app = _build_request_app()
payload = {
"update_id": 10031,
"message": {
"message_id": 81,
"chat": {"id": 777, "type": "private"},
"from": {"id": 777777},
"photo": [{"file_id": "small"}, {"file_id": "large"}],
},
}
with app.test_request_context("/bot/telegram/webhook", method="POST", json=payload):
bot.telegram_webhook()
assert calls == ["ollama", "gemini"]
assert handled == [("competitor", "飛利浦 Sonicare", 777, 81)]
def test_obs_heal_audit_uses_current_callback_user(monkeypatch):
from types import SimpleNamespace
from routes import openclaw_bot_routes as bot

View File

@@ -142,6 +142,9 @@ def test_env_example_documents_runtime_and_ai_automation_variables():
"OPENCLAW_DAILY_HERMES_TEMPLATE",
"OPENCLAW_OLLAMA_MODEL",
"OPENCLAW_PPT_CACHE_TTL_HOURS",
"OPENCLAW_IMAGE_GEMINI_MODEL",
"OPENCLAW_IMAGE_OLLAMA_TIMEOUT",
"OPENCLAW_IMAGE_VISION_MODEL",
"OPENCLAW_QA_OLLAMA_FIRST",
"OPENCLAW_QA_OLLAMA_MODEL",
"OPENCLAW_QA_OLLAMA_TIMEOUT",