- ab_ai_bot: raise requests.post timeout 120s -> 600s so long OCR+LLM
runs don't silently drop the reply in Discuss
- upload: run parse_upload in ThreadPoolExecutor so tesseract OCR
doesn't block the FastAPI event loop
- expenses_agent: parse all receipts concurrently with asyncio.gather
(Ollama semaphore caps parallelism at 2); reduces 13-receipt LLM
time from ~39s sequential to ~20s parallel
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- ollama_backend: add format='json' for 'master' and receipt_parser
callers so llama3.1:8b returns valid JSON instead of plain English
- ab_ai_mail: add debug logging to trace attachment_ids from Discuss;
handle file-only messages and clarification look-back flow
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Discuss bot now reads ir.attachment from incoming messages; file-only
messages no longer silently dropped
- ZIP files are described (contents listed) and bot asks clarifying
question before acting; user's follow-up reply looks back for pending
attachments so files don't need to be re-uploaded
- receipt_parser: extracts text from ZIP (recursive), JPG/PNG/etc (OCR),
PDF (pdfplumber), HTML, TXT
- expenses_agent: full rewrite fixing broken method signatures; adds
create_expense_sheet / create_expense / attach_receipt flow driven by
LLM receipt parsing (Ollama, HIPAA-locked)
- master_agent: extra_context threads receipts + user_id into directives
- FastAPI /upload multipart endpoint; registered in main.py
- Odoo /ai/upload controller proxies files to agent service
- ab_ai_bot: dispatch_message_with_files() for multipart uploads
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- docker-compose.odoo.yml: add activeblue-net so Odoo can reach
activeblue-agent by hostname; fix addons volume mount (was odoo_module)
- ab_ai_bot.py: bus.presence.status is computed — write only last_poll
and last_presence; set last_poll 90s ahead when online so the bot
stays green across the 60s cron cycle (DISCONNECTION_TIMER=30s)
- ir_cron.xml: reduce ping interval to 20s (uses Odoo 18 seconds type)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.
env.get() isn't an Odoo Environment method, so the existence guard
silently returned without ever writing the bot's presence row. Use the
'in self.env' check instead.
Extend cron_ping_all to upsert a bus.presence row for the
activeblue_ai_bot user, mirroring the agent service's reachability:
green dot when /health responds 200, offline otherwise. Drop the cron
interval from 5m to 1m so the presence stays fresh (Odoo's presence
client expects refreshes well under a minute).
- Create res.partner for the AI bot (appears in DM contacts)
- Override mail.channel.message_post to intercept direct messages
to the bot partner and forward them to the agent service
- Post the agent reply back into the Discuss channel as the bot
- Add discuss to depends; load res_partner_bot.xml data
Users can now open Discuss -> New Message -> search 'ActiveBlue AI'
to start a conversation with the agent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>