Skip to Content
Odoo Menu
  • Sign in
  • Try it free
  • Apps
    Finance
    • Accounting
    • Invoicing
    • Expenses
    • Spreadsheet (BI)
    • Documents
    • Sign
    Sales
    • CRM
    • Sales
    • POS Shop
    • POS Restaurant
    • Subscriptions
    • Rental
    Websites
    • Website Builder
    • eCommerce
    • Blog
    • Forum
    • Live Chat
    • eLearning
    Supply Chain
    • Inventory
    • Manufacturing
    • PLM
    • Purchase
    • Maintenance
    • Quality
    Human Resources
    • Employees
    • Recruitment
    • Time Off
    • Appraisals
    • Referrals
    • Fleet
    Marketing
    • Social Marketing
    • Email Marketing
    • SMS Marketing
    • Events
    • Marketing Automation
    • Surveys
    Services
    • Project
    • Timesheets
    • Field Service
    • Helpdesk
    • Planning
    • Appointments
    Productivity
    • Discuss
    • Approvals
    • IoT
    • VoIP
    • Knowledge
    • WhatsApp
    Third party apps Odoo Studio Odoo Cloud Platform
  • Industries
    Retail
    • Book Store
    • Clothing Store
    • Furniture Store
    • Grocery Store
    • Hardware Store
    • Toy Store
    Food & Hospitality
    • Bar and Pub
    • Restaurant
    • Fast Food
    • Guest House
    • Beverage Distributor
    • Hotel
    Real Estate
    • Real Estate Agency
    • Architecture Firm
    • Construction
    • Property Management
    • Gardening
    • Property Owner Association
    Consulting
    • Accounting Firm
    • Odoo Partner
    • Marketing Agency
    • Law firm
    • Talent Acquisition
    • Audit & Certification
    Manufacturing
    • Textile
    • Metal
    • Furnitures
    • Food
    • Brewery
    • Corporate Gifts
    Health & Fitness
    • Sports Club
    • Eyewear Store
    • Fitness Center
    • Wellness Practitioners
    • Pharmacy
    • Hair Salon
    Trades
    • Handyman
    • IT Hardware & Support
    • Solar Energy Systems
    • Shoe Maker
    • Cleaning Services
    • HVAC Services
    Others
    • Nonprofit Organization
    • Environmental Agency
    • Billboard Rental
    • Photography
    • Bike Leasing
    • Software Reseller
    Browse all Industries
  • Community
    Learn
    • Tutorials
    • Documentation
    • Certifications
    • Training
    • Blog
    • Podcast
    Empower Education
    • Education Program
    • Scale Up! Business Game
    • Visit Odoo
    Get the Software
    • Download
    • Compare Editions
    • Releases
    Collaborate
    • Github
    • Forum
    • Events
    • Translations
    • Become a Partner
    • Services for Partners
    • Register your Accounting Firm
    Get Services
    • Find a Partner
    • Find an Accountant
      • Get a Tailored Demo
    • Implementation Services
    • Customer References
    • Support
    • Upgrades
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +32 2 290 34 90
    • Get a Tailored Demo
  • Pricing
  • Help
  1. APPS
  2. Productivity
  3. MuK AI Assistant v 19.0
  4. Sales Conditions FAQ

MuK AI Assistant

by MuK IT http://www.mukit.at
Odoo
v 19.0 Third Party 311
Download for v 19.0 Deploy on Odoo.sh Live Preview
Apps purchases are linked to your Odoo account, please sign in or sign up first.
Versions 16.0 17.0 18.0 19.0
You bought this module and need support? Click here!
Versions 16.0 17.0 18.0 19.0
  • Description
  • Manifest
  • Documentation

MuK AI Assistant

Native AI Chat & Agent Runtime for Odoo

MuK IT GmbH - www.mukit.at

Community Enterprise

Overview

A complete agentic AI assistant inside Odoo. MuK AI ships a native OWL chat client, a session-based agent runtime, and three first-class LLM providers (OpenAI, Anthropic, Google Gemini) with live token and reasoning streaming. The assistant talks to your data through the same muk_mcp tool registry your external AI clients already use — one source of truth, one permission model, one audit trail.

Includes human-in-the-loop ask_user support, a session-scoped approval gate for risky writes, per-agent tool filters, read-only scope enforcement, multimodal attachments (images, PDFs, text files), lazy tool loading with a per-agent essentials list, agent suggestion prompts, field history versioning, and a prebuilt catalog of current GPT-5.x / Claude 4.x–5 / Gemini 2.5–3.x models with input, output and cache (read + write) pricing and per-model reasoning-effort tiers.

MuK AI is also the foundation for the rest of the MuK AI suite: adding a new provider is a single-file drop-in via the providers REGISTRY, and downstream add-ons plug extra tools, agents and UI extensions onto the same runtime.

Chat Client

A full OWL-based chat action lives under MuK AI > Chat (also reachable at /odoo/ai). Sessions auto-save to the database, stream replies live via the Odoo bus, and render tool calls inline as collapsible cards with live-filling arguments so users always see what the model is about to run. Markdown rendering covers headings, lists, tables, inline code, and fenced code blocks with syntax highlighting. A systray icon surfaces running sessions across the UI, and a floating chat window (Discuss-style) lets users keep talking while navigating other views.

Keyboard-first by design: Enter sends, Shift+Enter adds a newline, and a single Send/Stop toggle handles mid-stream cancellation. Auto-scroll pauses when the user scrolls up, so reading past replies is not interrupted by the next delta.

Spaces

Chats pile up fast. Spaces are folders in the sidebar: create one with the + next to Spaces, then drag chats into it to file them and drag them back out to loosen them again. Drag a space by its grip to reorder the list. Each space carries a name, a Font Awesome icon picked from a searchable grid, and an optional default agent that is preselected for every chat started inside it — so a “Finance” space can always open with your read-only analyst. Everything is editable from the chat itself, no backend menu required.

Unread chats are counted per space; click the badge to narrow a space to just its unread conversations. Modules can also ship system spaces whose membership is derived from a stored domain instead of manual filing — muk_ai_schedule ships a Scheduled space that collects every chat started by a schedule. One record serves the whole database: nothing is duplicated per user, and new matching chats appear in it retroactively.

Read-Only Sharing

A chat belongs to whoever started it — but it can be handed around to be read. The line above the composer names who can read the current chat and opens a picker of colleagues to add or drop. Everyone you pick sees the whole transcript, every tool call and every answer exactly as it ran, and nothing else: the composer says the chat is read only instead of offering an input, and the agent, the approval mode, rewind, branch and regenerate are all withheld. The same holds in the popped-out window, and add-ons inherit it, so a shared chat cannot be steered from anywhere. A reader watches the answer arrive as it is written — a chat streams on a channel of its own, which the server hands out only to the people allowed to read it, so their transcript and their chat list keep up on their own.

Reading is granted by a record rule of its own, so an administrator keeps their usual access and nobody else gains any. A system space, Shared with Me, collects everything shared with you. Hand a chat over to someone else and you stay on the list as a reader, so work you started never drops out of sight.

Live Reasoning Stream

When the underlying model exposes a reasoning channel (OpenAI o-series and GPT-5 family, Anthropic Opus 4.x and Sonnet 4.x with extended or adaptive thinking), the chat replaces the static “Thinking…” placeholder with the model's latest reasoning sentence as it streams. The line rotates as new thoughts arrive and disappears the moment the answer text starts — you see what the agent is currently working through, never a stale block of text. Models without a reasoning channel (Gemini, GPT-4 family, Haiku) keep the original animated dots fallback automatically.

Source Citations

Answers stay grounded in your data. Whenever the assistant reads records to build a reply, the records it relied on are collected as sources and surfaced as a compact chip under the message — expand it to see each cited record with its model and a one-click link that opens the record in Odoo. The same list is mirrored in the Artifacts side rail alongside the turn's attachments, so it is always clear where a number or a claim came from — no more guessing whether the model invented a figure or pulled it from an actual sale.order.

Reasoning Effort

Dial how hard a model thinks before it answers. Each agent carries a Reasoning Effort setting — Minimal, Low, Medium, High, Extra High or Maximum — and only the tiers the chosen model actually supports are offered; the field disappears entirely for models with no thinking knob. The catalog stores each model's supported efforts, so a request above what a model allows is clamped to the nearest tier, and a provider that still refuses is retried without the effort so the answer is always served. Leave it on Model Default to let the model decide.

Multi-Provider Architecture

The provider layer is a thin Python registry plus stored configuration records (muk_ai.provider). Each provider class declares name / label / default_model / default_url / supports_*, implements headers() and request(), and inherits shared HTTP + SSE streaming from ProviderBase. Settings, default-model lookup, capability probes, and dispatch are all derived from the same REGISTRY — new providers ship as one Python file and one mutate-line in the addon's __init__.py, no fork of muk_ai required.

Provider API surface Streaming Reasoning
openai Responses API SSE Summary stream on o-series & GPT-5; encrypted carry for stateless mode
anthropic Messages API SSE Extended thinking (legacy budget) and adaptive thinking (4.7+)
google Gemini API SSE Falls back to the static thinking indicator

The shipped catalog includes the current GPT-5.x family (5, 5.1, 5.2, 5.4 incl. Pro variants, 5.5 + Pro, 5.6), GPT-4.1 family, GPT-4o, the o-series; Claude Opus 4 / 4.1 / 4.5 / 4.6 / 4.7 / 4.8, Sonnet 4.x / 5, Haiku, Fable 5; Gemini 2.5 Pro/Flash/Flash-Lite/Flash-Image and the 3.x previews — each with context window and per-1M-token pricing for live cost display.

Agents & Tool Filters

An Agent is a named preset: system prompt (rendered with Odoo's inline-template engine for placeholders like {{ user.name }} or {{ today }}), model override, tool filter, an Essential Tools list that controls which schemas ship eagerly (the rest stay name-only and lazy-load on demand), native-tool toggles (web search, image generation, code interpreter — auto-hidden when the provider doesn't support them), read-only flag, approval mode, and starter suggestion prompts. Every chat session inherits from an agent — ship a "Sales Assistant" with write access to leads alongside a "Read-only Analyst" that cannot mutate anything. Read-only is enforced server-side through the MCP scope check, not just by prompt instruction.

System prompts are versioned: every edit captures the previous body into a Prompt History revision so you can audit and roll back. Per-user rate limits throttle session creation, and record rules keep each user's sessions private (own-only for internal users, full access for system).

Multiple Agents & Handoff

One chat can be served by several agents. Flip on Allow Handoff to make an agent a delegation target, and the built-in Router reads the opening request, calls list_agents, and hands the conversation to the best specialist with switch_agent — from the next turn that agent's prompt, tools and model take over the same session (the switch is logged inline as an A → B marker). Ship a “Sales Assistant” with write access alongside a “Read-only Analyst”, and let the Router pick. Type /agent to switch yourself, or hand the whole live chat to a colleague with the share button (or /handover) — they get the session, an inbox notification and an unread badge.

Session-Scoped Approval Gate

Risky write calls pause the session and ask before running. An update to a mail-tracked field, a workflow method like action_post on an invoice, a deletion, or a create on a high-impact model triggers an approval card inline in the chat. The card explains why it fired ("approving because state is tracked on account.move"), shows the proposed JSON arguments, and offers three buttons: Approve once, Allow for Session (auto-approves matching calls for the rest of this session only), and Reject (returns a rejected_by_user tool output so the model can recover). Every decision is logged under Reports > Approval Log with proposed vs. executed arguments.

Floating Window & View Context

A floating chat window (Discuss-style) lets the assistant stay reachable while users navigate other views. When open, the session sticks to the Odoo view the user is looking at — form record, list, kanban, pivot, graph — and a header pill shows the pinned context (e.g. sale.order · SO-00042) that opens that view on click. Navigation fired by the agent (open_record, open_view, open_action) updates the pin automatically. The context is injected at request time as a short <ui_ctx> tag, so the model can resolve references like "this order" or "the current list" without an extra tool call. Type /unpin to clear it.

Reshape Views from Chat

Ask the assistant to change the list, kanban, pivot or graph you are looking at — “group these orders by salesperson”, “only show drafts”, “switch to a bar chart” — and it reshapes that view in place instead of opening a new one. The adjust_search tool is a client tool: rather than running on the server it runs in your browser tab and drives the live search view — activating filters and group-bys (with date_order:month-style intervals), applying field searches and custom-domain facets, removing facets, switching view type, and setting pivot/graph measures, chart mode, ordering and stacking. It reports back exactly what it changed, and — as in the shot below — will pause to check with you first when a change would hide data.

Conversation Controls

The transcript is fully in your hands:

  • Tool groups — when a turn fires several tool calls they collapse into one Used N tools card with the tool chips and a green &check; / red × success-and-error badge; expand it for the individual calls. Each card fills its arguments live and then drops in its result in place.
  • Rewind, branch & regenerate — hover any message to rewind (remove it and everything after), branch (fork the history into a brand-new session), or regenerate the last answer.
  • Artifacts panel — a side rail that gathers every uploaded file, every AI-generated image (open full-size in the file viewer) and every cited source under Attachments and Sources tabs.
  • Find in conversation — a search bar highlights matches with a current/total counter and jumps between them.
  • Attention & notifications — the systray icon carries a live running dot and a red count of sessions awaiting you; unread sessions are marked and sorted to the top, and completion notices can arrive as web and Enterprise mobile push.

Tool Dispatch via muk_mcp

Agents call exactly the same tool surface as your external MCP clients — no duplicate catalog, no divergence. The MuK AI agent registry pulls tools from muk_mcp filtered by registry, and a handful of UI-specific tools (open_record, open_view, open_action, show_notification, ask_user, the view-reshaping adjust_search) are scoped to the in-Odoo agent. The chat UI auto-dispatches any returned ir.actions.* descriptor, so the model can navigate the user through the UI as part of a reply.

When the LLM calls ask_user the session pauses in waiting state and surfaces the question in the chat. The user's answer is fed back as a function_call_output so the model resumes the turn exactly where it left off. Beyond the UI tools, a built-in web_fetch tool reads a public web page as clean Markdown (boilerplate stripped, links kept) behind an SSRF guard that re-validates every redirect, and the fetched page joins the reply's Sources as a citable web link.

Lazy Tool Loading

Shipping every MCP tool's JSON schema in the tools array of every turn is expensive on context. Each agent declares a small Essential Tools set that loads eagerly; every other catalog tool is advertised by name only inside an <available_tools> block appended to the system prompt. The model fetches full schemas on demand through a built-in meta-tool:

  • tool_load(names=[...]) — pulls one or more schemas from the catalog. The names are appended to the session's loaded-tools list and stay available for the rest of the session.
  • tool_load(names=[...], call={name, arguments}) — load and execute one of the just-loaded tools in the same round-trip; the schemas plus the inline tool result come back in a single function_call_output, no follow-up turn needed. Preferred shape for one-shot lookups.

Unknown names come back under an unknown key so the model can recover gracefully. ask_user is auto-injected when approvals are on, regardless of the essentials list. Leaving Essential Tools empty enables the default lazy mode (read-side primitives + UI helpers + ask_user); populate it to override.

Runtime Context Block

Alongside the agent's system prompt and <available_tools> list, each session injects a short <runtime> block stating the current Odoo version, today's date, the user (id, timezone), the company (id), the active approval mode, and — when relevant — the list of companies the user can access with a hint to pass allowed_company_ids for cross-company searches. The model never has to spend a turn calling whoami or asking for the date to ground its first reply.

Multimodal Attachments

Drop a file onto the composer, paste a screenshot, or click the clip icon. Images render inline, PDFs and text files show as pills. On send, every attachment is streamed to the active provider as a native content block — input_image / input_file for OpenAI Responses, image / document blocks for Anthropic Messages, inline base64 for Gemini, inline text for small .txt / .csv / .md files. Accepted: PNG, JPEG, WebP, GIF, PDF, plain text, CSV, Markdown. Capped at 128 MiB per file with oversize and unknown-type uploads rejected server-side.

Context-Window Meter & Slash Commands

The chat header shows a colour-coded pill with the share of the current model's context window consumed by the last turn's input. Below 85 % is idle, 85–95 % flags a warning and offers to auto-compact, 95 %+ triggers auto-compaction silently — the conversation is replaced by a ≤500-token summary so the session can keep going without losing continuity. Context sizes come from the muk_ai.model record for the agent's active model.

Start a message with / to open a popover of available commands: /help, /clear (wipe conversation, keep agent), /compact (manual compaction), /unpin (clear view-context pin), /agent (switch the active agent), and /handover (transfer the chat to another user).

Streaming & Bus Events

Replies stream over the Odoo bus as they arrive from the provider. Each session inherits bus.listener.mixin and routes events through the owner's partner channel — not a guessable string — so sessions cannot be eavesdropped by other authenticated users. Text is delivered as text_delta events; reasoning summaries as reasoning_delta; tool calls stream as tool_call_start + tool_call_args_delta so the chat UI shows the tool card with live-filling arguments before the tool even fires.

A per-stream idle watchdog aborts dead connections and marks the session as errored. Runaway loops are capped per turn, and the ask_user-at-cap edge is handled gracefully so resumed sessions do not get stuck.

Security & Audit

Internal User opens the chat and manages their own sessions; System manages every session, edits agents and providers, reviews approvals and tool logs. Record rules scope sessions to their owner. open_action honours per-action groups_id so the model cannot hand a user a descriptor they would not be allowed to reach through the menu.

Every session carries an audit-ready tool log: user messages, tool calls, tool results, assistant text, ask_user prompts, answers, approval decisions — all JSON-serialised. Combined with muk_mcp's own log, any AI-driven write on your data is traceable end to end.

Settings

Two one-line defaults under Settings > General Settings > MuK AI: Default Provider (falls back to the first active provider when an agent doesn't pin one) and Default Agent (used for new chat sessions when the user hasn't picked one). Everything else is configured per-record on the provider, model, and agent forms. A Test Connection button on the provider form sends a tiny probe and reports success or failure without leaving the page. The same page holds the runtime guard-rails — Iteration Limit (rounds per slice), Turn Runtime and Slice Runtime wall-clock budgets, and a per-turn Cost Limit — and lists the installable MuK AI extensions (MCP, Compatible Providers, Mistral, Schedule, Skills, Voice, Workflows) as one-click toggles.

More Apps from MuK IT

MuK AI Schedule

MuK AI Schedule

Cron Agents
View Module ›
MuK AI Skills

MuK AI Skills

Agent Skills
View Module ›
MuK MCP OAuth

MuK MCP OAuth

MCP OAuth
View Module ›
MuK AI Workflows

MuK AI Workflows

Workflow Engine
View Module ›

All MuK Apps

Browse
View All ›

Want more?

Are you having troubles with your Odoo integration? Or do you feel your system lacks of essential features?
If your answer is YES to one of the above questions, feel free to contact us at anytime with your inquiry.
We are looking forward to discuss your needs and plan the next steps with you.

REQUEST QUOTE

Our Services

Odoo
Development

Odoo
Integration

Odoo
Infrastructure

Odoo
Training

Odoo
Support

Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies Discuss (mail)
Community Apps Dependencies Show
• MuK MCP Server
• MuK Web Utils
Lines of code 31434
Technical Name muk_ai
LicenseLGPL-3
Websitehttp://www.mukit.at

MuK AI Assistant

A complete agentic AI assistant inside Odoo. MuK AI ships a native OWL chat client, a session-based agent runtime, and three first-class LLM providers (OpenAI, Anthropic, Google Gemini) with live token and reasoning streaming. The assistant talks to your data through the same muk_mcp tool registry your external AI clients already use — one source of truth, one permission model, one audit trail.

Includes human-in-the-loop ask_user support, a session-scoped approval gate for risky writes, per-agent tool filters, read-only scope enforcement, multimodal attachments (images, PDFs, text files), lazy tool loading with a per-agent essentials list, agent suggestion prompts, field history versioning, and a prebuilt catalog of current GPT-5.x / Claude 4.x–5 / Gemini 2.5–3.x models with input, output and cache (read + write) pricing and per-model reasoning-effort tiers.

It is also the foundation for the rest of the MuK AI suite: the REGISTRY in providers/__init__.py drives both the in-memory dispatcher and the stored muk_ai.provider records, so adding a new provider is a single-file drop-in, and downstream add-ons plug extra tools, agents and UI extensions onto the same runtime.

Installation

To install this module, you need to:

Download the module and add it to your Odoo addons folder. Afterward, log on to your Odoo server and go to the Apps menu. Trigger the debug mode and update the list by clicking on the "Update Apps List" link. Now install the module by clicking on the install button.

Upgrade

To upgrade this module, you need to:

Download the module and add it to your Odoo addons folder. Restart the server and log on to your Odoo server. Select the Apps menu and upgrade the module by clicking on the upgrade button.

Menu layout

Everything lives under MuK AI in the app menu:

  • Chat — the main client action (also reachable at /odoo/ai).
  • Agents — named presets (system prompt, model, tool filter, approval mode, suggestions).
  • Reports (system) — Sessions, Tool Logs, Approval Log.
  • MCP (system) — the underlying tool Registry and Playground from muk_mcp.
  • Configuration (system) — Providers, Models, Spaces.
  • Settings (system) — one-line defaults under the standard General Settings page.

Configuration

Settings — Settings > General Settings > MuK AI

  • Default Provider — falls back to the first active provider when an agent does not pin one.
  • Default Agent — used for new chat sessions when the user hasn't picked one.
  • Iteration Limit — max tool-calling rounds per worker slice (default 20).
  • Turn Runtime — wall-clock budget for a whole user turn across all slices (default 3600 s).
  • Slice Runtime — wall-clock budget for one worker slice (default 600 s); a slice that exceeds it is checkpointed and resumed by a fresh worker.
  • Cost Limit — maximum spend per user turn in the model's price currency (0 disables).

The same page lists the installable MuK AI extensions (MCP, Compatible Providers, Mistral, Schedule, Skills, Voice, Workflows) as one-click toggles.

Everything else is configured per-record, not globally.

Providers — MuK AI > Configuration > Providers

One record per provider implementation (openai, anthropic, google). Fields:

  • API Key — authentication token for this provider.
  • Default Model — muk_ai.model used when an agent does not specify one.
  • Max Tokens — completion-token cap per request (default 4096).
  • Request Timeout — HTTP timeout in seconds (default 60).
  • Idle Timeout — seconds without a streamed chunk before the stream is aborted and the session is marked errored (default 45).
  • Rate Limit (per minute) — max sessions a single user may create per minute. 0 disables the cap.

A Test Connection button on the provider form sends a tiny probe (Reply with a single word.) and reports success or failure without leaving the page.

Models — MuK AI > Configuration > Models

The model catalog ships prefilled with current API-available SKUs — the GPT-5.x family (5, 5.1, 5.2, 5.4 + Pro, 5.5 + Pro, and the 5.6 Sol / Terra / Luna tiers), GPT-4.1 family, GPT-4o and the o-series; Claude (Opus 4.x through 4.8, Sonnet 4.x and Sonnet 5, Haiku, Fable 5); and Gemini (2.5 Pro/Flash/Flash-Lite/Flash-Image plus the 3.x previews). Each record carries:

  • Technical Name — API id (gpt-5.2, claude-sonnet-5, gemini-3.5-flash, …).
  • Provider — the parent muk_ai.provider.
  • Context Window — used for the colour-coded meter in the chat.
  • Input / Output Rate and Cache Read / Cache Write Rate — USD per 1M tokens. Input is split into fresh, cache-read and cache-write tokens so prompt-cached turns are billed at their real (much lower) cost; the rates drive the per-session cost display and the usage pivot.
  • Supported Reasoning Efforts / Default Reasoning Effort — the thinking tiers this model accepts (see Reasoning effort under Agents); models without a thinking knob leave these empty.

Access Groups

  • Internal User (base.group_user) — opens the chat, manages their own sessions, reads agents and their suggestions.
  • System (base.group_system) — manages every session, edits agents and providers, reviews approvals and tool logs.

Record rules keep each user's sessions private.

Usage

Chatting

Open MuK AI > Chat (or /odoo/ai). Create a session from the sidebar, pick an agent (optional), type a message and hit Enter. The reply streams in live via the Odoo bus; tool calls render as collapsible cards with live-filling arguments so you can see exactly what the model is about to run. Shift+Enter inserts a newline. A single Send/Stop toggle cancels an in-flight stream.

A systray icon in the top bar surfaces running sessions and lets you pop out a floating chat window so the assistant stays reachable while you navigate other views.

Spaces

Chats pile up fast, so the sidebar groups them into spaces. Create one with the + next to Spaces, drag chats into it to file them and drag them out to loosen them again, and drag a space by its grip to reorder the list. The pencil opens an editor for the space name, its Font Awesome icon (searchable grid) and an optional default agent preselected for every chat started inside it — the + on a space row starts such a chat. Unread chats are counted per space; click the badge to narrow that space to its unread conversations. Every branch paginates on its own, so opening a space with hundreds of chats costs one page.

Modules can ship system spaces whose membership comes from a stored domain instead of manual filing — muk_ai_schedule ships a Scheduled space collecting every chat a schedule started. They belong to nobody, are visible to everyone, and cannot be renamed, reordered or dropped into; one record serves the whole database, so nothing is duplicated per user and matching chats appear retroactively. Administrators manage every space under MuK AI > Configuration > Spaces.

Read-only sharing

A chat belongs to the person who started it, but it can be handed around to be read. The line above the composer names who can read the current chat and opens a picker of colleagues to add or drop. Everyone you pick sees the whole transcript — every tool call, every answer, exactly as it ran — and nothing else: the composer states that the chat is read only instead of offering an input, and the agent, the approval mode, rewind, branch and regenerate are all withheld. The same holds in the popped-out window, and add-ons inherit it, so a shared chat cannot be steered from anywhere. A reader watches the answer arrive as it is written: a chat streams on a channel of its own, which the server hands out only to the people allowed to read it, so their transcript and their chat list keep up on their own. Reading is granted by a record rule of its own, so an administrator keeps their usual access and nobody else gains any. A system space, Shared with Me, collects everything shared with you. Handing a chat over to someone else leaves you on the list as a reader, so work you started stays visible.

Source citations

When the assistant reads data to answer, what it relied on is collected as sources and shown as a chip under the reply. Expand it to see each source — an Odoo record (with its model and a one-click link that opens it) or, when the agent used web_fetch, the external web page it read. The same list is mirrored in the Artifacts side rail, so every figure is traceable to its origin.

Tool groups

When a turn fires several tool calls back to back, they collapse into a single Used N tools card instead of stacking many. The header shows the tool-name chips and aggregate status — a green check with the success count and a red × with the error count — and expands to reveal each individual call. Each card fills its arguments live as the model streams them and then drops in the result in place, so you watch the work happen without waiting for the whole turn to finish.

Rewind, branch & regenerate

Hover any message for its actions. Rewind removes that message and everything after it (after a confirmation that names how many events drop). Branch forks the conversation into a brand-new session seeded with the history up to that point, leaving the original intact. Regenerate, offered on the last answer, re-runs the turn. Rewind and Branch are disabled while a reply is streaming and on messages already folded into compacted history.

Artifacts panel

A collapsible Artifacts rail (paperclip icon in the header) gathers everything a conversation produced. An Attachments tab lists every uploaded file and every AI-generated image as a card you can open full-size in Odoo's file viewer; a Sources tab lists the cited records and web pages. Tabs appear only when they have content.

In-chat search

The search icon opens a find-in-conversation bar. Matches across user and assistant text are highlighted with a current/total counter; Enter / Shift+Enter jump to the next / previous hit and scroll it into view, Esc closes.

Notifications

Sessions that finish or need you while you are elsewhere signal you. The MuK AI systray icon carries a live running dot whenever a session is running or waiting, plus a red count of sessions awaiting your attention; unread sessions are marked and sorted to the top in both the systray dropdown and the chat sidebar. Users on the inbox notification preference also get completion notices as web push and Enterprise mobile (OCN) push. Opening the session clears the flag.

Write-tool safety (session-scoped approvals)

Risky write calls pause the session and ask before running. An update to a mail-tracked field, a workflow method like action_post on an invoice, a deletion, or a create on a high-impact model triggers an approval card inline in the chat. The card shows why it fired ("approving because state is tracked on account.move"), the proposed JSON arguments, and three buttons:

  • Approve once — dispatches this call and logs the decision.
  • Allow for Session — same, plus adds a signature to the session so matching calls (same tool, same model, same sensitive fields) auto-approve for the rest of this session.
  • Reject — returns a rejected_by_user tool output so the model can recover (clarify, propose a safer alternative).

Every decision is recorded under MuK AI > Reports > Approval Log with the proposed vs. executed arguments. Per-agent Approval Mode lets unattended agents skip the prompt (Never ask). Approvals do not persist across sessions — each new session starts with an empty allow-list.

View context

When the floating chat window is open, the session sticks to the Odoo view the user is looking at (form record, list, kanban, pivot, graph). A header pill shows the pinned context (e.g. sale.order · SO-00042) and opens that view on click. Navigation fired by the agent (open_record, open_view, open_action) updates the pin automatically. The context is injected at request time as a short <ui_ctx> tag at the tail of the conversation, so the model can resolve references like "this order" or "the current list" without an extra tool call. Type /unpin to clear it.

Reshape views from chat

Ask the assistant to change the list, kanban, pivot or graph you are looking at — "group these orders by salesperson", "only show drafts", "switch to a bar chart" — and it reshapes that view in place rather than opening a new one. The adjust_search tool is a client tool: instead of running on the server it runs in your browser tab and drives the live search view — activating filters and group-bys (with date_order:month-style intervals), applying field searches and custom-domain facets, removing facets, switching view type, and setting pivot/graph measures, chart mode, ordering, stacking and cumulation. It reports back exactly what it changed, and the available filter/group-by names when you ask for one it doesn't recognise.

Attachments

Drop a file onto the composer, paste a screenshot, or click the clip icon. Images render inline, PDFs and text files show as pills. On send, every attachment is streamed to the active provider as a native content block — input_image / input_file for OpenAI Responses, image / document blocks for Anthropic Messages, inline base64 for Gemini, inline text for small .txt / .csv / .md files. Accepted types: PNG, JPEG, WebP, GIF, PDF, plain text, CSV, Markdown. Capped at 128 MiB per file with oversize and unknown-type uploads rejected server-side. Text files are inlined and truncated past 256 KiB.

Human-in-the-loop

When the LLM calls the ask_user tool, the session pauses in waiting state and surfaces the question in the chat. Your answer is fed back as a function_call_output so the model resumes the turn exactly where it left off.

Context-window meter

The chat header shows a colour-coded pill with the share of the current model's context window consumed by the last turn's input. Below 85 % is idle, 85–95 % flags a warning and offers to auto- compact, 95 %+ triggers auto-compaction silently. Context sizes come from the muk_ai.model record for the agent's active model.

Slash commands

Start a message with / to open a pop-up of available commands:

  • /help — inline cheat sheet.
  • /clear — confirm and wipe the current conversation and tool log, keeping the session record and agent.
  • /compact — ask the provider for a ≤500-token summary and replace the conversation with it, freeing context without losing continuity.
  • /unpin — clear the view-context pin.
  • /agent — switch the active agent for this session.
  • /handover — transfer this chat to another user.

Agents

Open MuK AI > Agents. An agent is a named preset:

  • System Prompt — rendered with inline-template placeholders ({{ user.name }}, {{ company.name }}, {{ today }}, {{ approval_mode }}) at session start and on /compact.
  • Model — optional override; blank falls back to the provider default.
  • Reasoning Effort — how hard the model thinks before answering: Minimal, Low, Medium, High, Extra High or Maximum; blank uses the model's default. Only the tiers the model supports are offered, and the field disappears for models without a thinking knob. A requested tier above what the model allows is clamped to the nearest supported one, and a provider that still rejects it is retried without the effort so the answer is always served.
  • Provider-native toggles — enable the active provider's web search, image generation and code interpreter tools when the provider supports them.
  • Read-only — enforced server-side through the MCP scope check, not just a prompt instruction.
  • Tool Filter — whitelist of MCP tool names the agent may call (empty = all tools allowed).
  • Essential Tools — names that ship with full schemas at session start. Empty falls back to a sensible default (read-side primitives + UI helpers + ask_user) and turns lazy loading on; populate it to opt into a custom essentials set, or set it to every catalog name to ship the full eager-mode tool array. Names outside the tool filter are silently dropped.
  • Approval Mode — Ask on writes (default) or Never ask for unattended agents.
  • Allow Handoff — expose this agent as a delegation target so the Router (and other agents) can hand a conversation to it mid-session (see Agent handoff below).
  • Suggestions — starter prompts shown in the empty chat, editable as a one2many kanban inside the agent form.

Every system-prompt edit snapshots the prior value into the agent's prompt_history JSON column (via the reusable muk_ai.revision.mixin). The Prompt History stat button on the agent form opens a side-by-side dialog that lists all prior revisions with author + timestamp and lets you restore any of them.

Agent handoff (Router)

A single chat can be served by more than one agent. Turn on Allow Handoff to make an agent a delegation target; the built-in Router agent then reads the opening request, calls list_agents, and hands the conversation to the best specialist with switch_agent. From the next turn that agent's prompt, tools and model take over the same session, and a specialist can hand back or across later on its own. The switch is recorded inline in the transcript as an A → B marker. Use /agent to switch the active agent yourself at any time.

Session handover

Hand a live chat to a colleague. The share icon in the chat header (or /handover) opens a user picker — each internal user shown with avatar, name and email, searchable — and reassigns the session to them. The recipient gets the session marked unread, an inbox notification and a systray badge. Only the session owner or an administrator can hand over, and not while the session is running.

Tool vision

Tools that return images — a screenshot grabber, a chart generator — feed those images straight back to the model when the active provider supports vision. Providers without vision get a note that images were produced but cannot be shown, so the turn still completes cleanly.

Lazy tool loading

Shipping every MCP tool's JSON schema in the tools array of every turn is expensive on context. MuK AI lets each agent declare a small Essential Tools set that is loaded eagerly; every other catalog tool is advertised by name only inside an <available_tools> block appended to the system prompt. The model fetches full schemas on demand through a built-in meta-tool:

  • tool_load(names=[...]) — pulls one or more schemas from the catalog. The names are appended to the session's expanded_tool_names list and stay loaded for the rest of the session.
  • tool_load(names=[...], call={name, arguments}) — load and execute one of the just-loaded tools in the same round-trip; the schemas plus the inline tool result come back in a single function_call_output, no follow-up turn needed. This is the preferred shape for one-shot lookups. The inline call passes through the same write-approval gate as any other call — a risky write pauses for approval instead of running.

Names are resolved tolerating a namespace prefix (functions.foo → foo). A load with some misses succeeds and returns the misses under an unknown key so the model can recover; a load where every name is unknown comes back as an explicit error. ask_user is auto-injected when approvals are enabled, regardless of the essentials list. Leaving Essential Tools empty enables the default lazy mode (read-side primitives + UI helpers + ask_user); populate it to override.

Runtime context block

Alongside the agent's system prompt and <available_tools> list, each session injects a short <runtime> block stating the current Odoo version, today's date, the user (id, timezone), the company (id), the active approval mode, and — when relevant — the list of companies the user can access (with a hint to pass allowed_company_ids for cross-company searches). This means the model never has to spend a turn calling whoami or today to ground its first reply.

Providers

The provider layer is a Python registry (providers/__init__.py) plus stored configuration records (muk_ai.provider). Each provider class declares name / label / default_model / default_url / supports_*, implements headers() and request(), and inherits shared HTTP + SSE streaming plumbing from ProviderBase. A client is constructed from the provider record itself — API key, timeouts, max tokens, environment and default model are all read off the record — so there is one source of truth and no config drift.

Provider Streaming Notes
openai SSE OpenAI Responses API; skips temperature for reasoning models
anthropic SSE Messages API; in-dispatcher adapter for tool_use / tool_result
google SSE Gemini streamGenerateContent; native image generation and grounding

All three providers emit the same on-delta events (text, tool_start, tool_args), so the chat UI feels identical regardless of which provider is active.

Performance. Long conversations exploit provider prompt caching — Anthropic cache_control breakpoints on the stable prompt prefix (system block, tools, and a conversation anchor placed before the per-round volatile trailers) and OpenAI's prompt_cache_key keyed on the session — so the reused prefix is billed at the much cheaper cache-read rate instead of full price each round. Outbound calls run over a pooled keep-alive connection shared across rounds (with connect-only retry, so a tool-calling POST is never replayed), cutting per-round latency. Requested reasoning effort is clamped to each model's supported tiers, with a transparent retry-without-effort backstop if a provider still refuses.

Tool Dispatch via muk_mcp

Agents call exactly the same tool surface as your external MCP clients — no duplicate catalog, no divergence. The MuK AI agent pulls tools from muk_mcp filtered by the odoo registry, and a handful of UI-specific tools are registered there for the in-Odoo agent only:

  • open_record — navigate the user to a specific record.
  • open_view — open a filtered list/kanban/pivot view of a model.
  • open_action — launch an existing Odoo action by xmlid or id (honouring the action's groups_id).
  • show_notification — toast a message in the Odoo web client.
  • ask_user — pause the session for clarification.
  • adjust_search — reshape the list/kanban/pivot/graph the user is currently looking at (see Reshape views from chat). This is a client tool: it runs in the user's browser tab, not on the server.
  • web_fetch — fetch a public web page and return its main content as clean Markdown (or plain text / raw HTML), with an SSRF guard that re-validates every redirect. The fetched page is added to the reply's Sources as a citable web link.

The chat UI auto-dispatches any returned ir.actions.* descriptor, so the model can navigate the user through the UI as part of a reply.

Extending the Provider Set

Create a new addon (do not modify muk_ai). Subclass ProviderBase in your addon:

# muk_ai_mistral/providers/mistral.py
from odoo.addons.muk_ai.providers.base import ProviderBase


class MistralProvider(ProviderBase):
    name = 'mistral'
    label = "Mistral"
    default_model = 'mistral-large-latest'
    default_url = 'https://api.mistral.ai/v1'

    def headers(self):
        return {
            'Authorization': f'Bearer {self.api_key}',
            'Content-Type': 'application/json',
        }

    def request(
        self,
        inputs,
        tools_schema=None,
        text_schema=None,
        on_delta=None,
        model=None,
        enable_web_search=False,
        enable_image_generation=False,
        enable_code_interpreter=False,
        extra=None,
    ):
        ...

Register it by mutating the imported REGISTRY from your addon's __init__.py chain (runs at import time, before any session needs it):

# muk_ai_mistral/providers/__init__.py
from odoo.addons.muk_ai.providers import REGISTRY

from .mistral import MistralProvider

REGISTRY[MistralProvider.name] = MistralProvider

Add <record id="provider_mistral" model="muk_ai.provider"> to data/provider.xml and matching muk_ai.model seeds in data/model.xml. Depend on muk_ai in your __manifest__.py. Selection, default-model lookup, capability probes, and dispatch all pick it up automatically.

Extending the Tool Set

Agents inherit every tool registered via the muk_mcp pattern (see muk_mcp's index for the full guide). To scope a tool to the in-Odoo agent only, set the decorator's registry='odoo'; external MCP clients keep seeing the default mcp surface only.

Security & Audit

Every session carries a JSON-serialised tool log covering user messages, tool calls, tool results, assistant text, ask_user prompts, and answers. Combined with muk_mcp's own audit log, every AI-driven read or write on your data is traceable end-to-end.

The per-provider idle watchdog aborts dead connections. Runaway loops are capped by MAX_ITERATIONS (default 20) per slice and MAX_TOOL_CALLS_PER_ROUND = 10; an ask_user-at-cap edge is handled gracefully so resumed sessions do not get stuck.

Long turns are sliced across cron ticks instead of dying. Each worker run gets a wallclock budget bounded below the cron process limit (limit_time_real_cron, falling back to limit_time_real) so it yields before Odoo kills the worker; at the boundary the session stays running and re-triggers a worker, resuming from its persisted conversation on the next tick. A per-turn wallclock budget and an optional per-turn cost limit bound total work. All four caps are set from Settings > General Settings > MuK AI (Iteration Limit, Turn Runtime, Slice Runtime, Cost Limit) and stored as the muk_ai.max_iterations, muk_ai.turn_wallclock_seconds, muk_ai.slice_wallclock_seconds and muk_ai.turn_cost_limit system parameters.

Turn dispatch is automatic: a turn queued during a web request starts as soon as that request's response is sent, instead of waiting for the next AI session worker cron. It falls back to the cron whenever the server runs its own cron threads (they pick the turn up immediately anyway) and never runs in-request on multi-worker (prefork) servers. The muk_ai.dispatch_mode system parameter overrides that detection: inline forces in-request dispatch, cron forces the worker crons. Leave it unset unless you are diagnosing a dispatch problem.

Sessions inherit bus.listener.mixin and route streaming events through the owner's partner channel — not a guessable string — so one user cannot eavesdrop on another.

Credits

Contributors

  • Mathias Markl <mathias.markl@mukit.at>
  • Kerrim Abd E-Hamed <kerrim.adbelhamed@mukit.at>

Author & Maintainer

This module is maintained by the MuK IT GmbH.

MuK IT is an Austrian company specialized in customizing and extending Odoo. We develop custom solutions for your individual needs to help you focus on your strength and expertise to grow your business.

If you want to get in touch please contact us via mail (sale@mukit.at) or visit our website (https://mukit.at).

Please log in to comment on this module

  • The author can leave a single reply to each comment.
  • This section is meant to ask simple questions or leave a rating. Every report of a problem experienced while using the module should be addressed to the author directly (refer to the following point).
  • If you want to start a discussion with the author, please use the developer contact information. They can usually be found in the description.
  • Ratings
  • Discuss
Error when using
by
Đào Thắng
on 4/29/26, 2:40 AM

Hi , i got JS error when click open ai provider record "Odoo Client Error

UncaughtPromiseError > OwlError

Uncaught Promise > An error occured in the owl lifecycle (see this Error's "cause" property)

Occured on odoo19.local on 2026-04-29 06:34:58 GMT".

And have an other error:, when open ai Chat, it load too slow, i check muk_ai.session/get_snapshot take 40s to load ?

Error when using
by
Mathias Markl
on 6/13/26, 7:07 AM Author

Thank you for the feedback. The slow loading is fixed by 19.0.1.6.14

Take a look at https://github.com/muk-it/odoo-modules/commit/b3f7cfe23a17d835ce8ec66b98b60ae2c96e9ff7


There are no comments yet!
Community
  • Tutorials
  • Documentation
  • Forum
Open Source
  • Download
  • Github
  • Runbot
  • Translations
Services
  • Odoo.sh Hosting
  • Support
  • Upgrade
  • Custom Developments
  • Education
  • Find an Accountant
  • Find a Partner
  • Become a Partner
About us
  • Our company
  • Brand Assets
  • Contact us
  • Jobs
  • Events
  • Podcast
  • Blog
  • Customers
  • Legal • Privacy
  • Security

Odoo is a suite of open source business apps that cover all your company needs: CRM, eCommerce, accounting, inventory, point of sale, project management, etc.

Odoo's unique value proposition is to be at the same time very easy to use and fully integrated.

Website made with