fix(addon): require LLM backend reachability for bot online state
action_ping was hitting /health, which returns 200 as long as the FastAPI app responds — even when Ollama is down, dispatch fails. So the bot showed online while every DM errored. Switch to /health/detailed and gate 'online' on db, master_agent and the active LLM backend (ollama for local privacy mode, claude otherwise) all reporting 'ok'. Anything else flips the bot to error or offline, which propagates through _sync_bot_user_presence to a grey dot in Discuss.
This commit is contained in:
@@ -57,17 +57,34 @@ class AbAiBot(models.Model):
|
|||||||
|
|
||||||
def action_ping(self):
|
def action_ping(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
url = self._get_service_url() + '/health'
|
url = self._get_service_url() + '/health/detailed'
|
||||||
try:
|
try:
|
||||||
resp = requests.get(url, timeout=5, headers=self._build_headers())
|
resp = requests.get(url, timeout=5, headers=self._build_headers())
|
||||||
if resp.status_code == 200:
|
if resp.status_code != 200:
|
||||||
self.write({'status': 'online', 'last_ping': fields.Datetime.now()})
|
|
||||||
return {'type': 'ir.actions.client', 'tag': 'display_notification',
|
|
||||||
'params': {'message': _('AI service is online'), 'type': 'success'}}
|
|
||||||
else:
|
|
||||||
self.write({'status': 'error'})
|
self.write({'status': 'error'})
|
||||||
return {'type': 'ir.actions.client', 'tag': 'display_notification',
|
return {'type': 'ir.actions.client', 'tag': 'display_notification',
|
||||||
'params': {'message': _('AI service returned %s') % resp.status_code, 'type': 'warning'}}
|
'params': {'message': _('AI service returned %s') % resp.status_code, 'type': 'warning'}}
|
||||||
|
data = resp.json() if resp.content else {}
|
||||||
|
# Bot is only "online" when every backend the LLM router needs is ok.
|
||||||
|
# Local privacy mode requires Ollama; cloud requires Claude. We treat
|
||||||
|
# any backend whose status is not 'ok' as a hard failure for the
|
||||||
|
# privacy mode in use, plus DB and master agent are always required.
|
||||||
|
db_ok = data.get('db') == 'ok'
|
||||||
|
master_ok = data.get('master_agent') == 'ok'
|
||||||
|
mode = data.get('privacy_mode') or self.privacy_mode
|
||||||
|
ollama_ok = data.get('ollama') == 'ok'
|
||||||
|
llm_ok = ollama_ok if mode == 'local' else True
|
||||||
|
if db_ok and master_ok and llm_ok:
|
||||||
|
self.write({'status': 'online', 'last_ping': fields.Datetime.now()})
|
||||||
|
return {'type': 'ir.actions.client', 'tag': 'display_notification',
|
||||||
|
'params': {'message': _('AI service is online'), 'type': 'success'}}
|
||||||
|
self.write({'status': 'error', 'last_ping': fields.Datetime.now()})
|
||||||
|
reason = ', '.join(
|
||||||
|
f'{k}={data.get(k)}' for k in ('db', 'master_agent', 'ollama')
|
||||||
|
if data.get(k) and data.get(k) != 'ok'
|
||||||
|
) or 'degraded'
|
||||||
|
return {'type': 'ir.actions.client', 'tag': 'display_notification',
|
||||||
|
'params': {'message': _('AI service degraded: %s') % reason, 'type': 'warning'}}
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self.write({'status': 'offline'})
|
self.write({'status': 'offline'})
|
||||||
return {'type': 'ir.actions.client', 'tag': 'display_notification',
|
return {'type': 'ir.actions.client', 'tag': 'display_notification',
|
||||||
|
|||||||
Reference in New Issue
Block a user