AI Agent Layer for Accounting
Deterministic accounting AI that works the day you install it, with a provider hook ready for live LLM upgrades later.
Why this module
AI Agent Layer for Accounting
Useful with zero configuration
Four anomaly rules, a variance template, and an eight-branch dunning ladder all run deterministically with no API key and no network. A site that never wants an LLM dependency gets real behaviour out of the box, and tests run end to end on the deterministic path.
Guards on every rule
The round-outlier rule self-suppresses below three positive amounts, variance handles zero-budget lines without divide-by-zero, the empty period still emits a placeholder line, and a threshold of zero deliberately disables the structuring rule. These are the small correctness cases cheaper helpers skip.
A hook, not a lock-in
A per-company provider key selects manual, claude, openai, or local. The variance hook already returns a live provider's paragraph when one is configured. Any provider failure falls back to the deterministic result, so the suite never breaks on a missing or misconfigured key.
Day in the life
Month-end close: 4,000 posted entries to review by tomorrow.
The reviewer runs the anomaly detector over all 4,000 posted entries. It scores them against four deterministic rules and returns a short candidate list: round-number outliers above 3x the period median, weekend posts, just-under-threshold amounts sitting inside 5 percent below the approval limit, and reversal-pair candidates where the same user posted the same amount on the same accounts on the same day. The reviewer drills into the handful of flags instead of every line. The variance helper then produces a one-paragraph budget headline naming the largest movers by direction, and the collections helper picks tomorrow's calls from the dunning ladder, holding back any partner with an active promise-to-pay. All three run on deterministic rules with no LLM bill. The helpers return their results to the caller; this module does not render them in a screen or persist them.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
An approval threshold of zero deliberately disables the just-under-threshold rule, so the structuring control is opt-in rather than firing on every entry when no limit is set. The guard is covered by a test.
An active promise-to-pay suppresses dunning escalation ahead of the days-overdue ladder, so a partner who committed to a payment date is not chased past it, even at day 90, 120, or 180.
Reversal-pair grouping sorts account codes before keying, so a pair on accounts (1100, 5200) matches regardless of which way round the entries reference them. Same-user, same-amount, same-day duplicates surface as candidates.
The round-outlier rule returns nothing when there are fewer than three positive amounts, instead of computing a meaningless median on one or two entries and raising a false flag.
Variance lines never divide by zero: the percentage returns 0 when budget and actual are both zero and 100 when an actual exists against a zero budget. An empty or all-zero period still emits an explicit placeholder line so the close pack is never blank.
The local provider accepts endpoint-only or model-only config because on-prem runtimes (Ollama, vLLM, llama.cpp) usually need no API key, unlike hosted providers which require both key and model. Malformed config raises a field-named error rather than failing silently.
When a provider is configured, the augmentation payload is capped at the first 50 findings or lines, so a very large period cannot build an unbounded prompt.
What is inside
Built to do the job, end to end.
- Round-number anomaly rule. Flags entries that are exact thousand multiples and exceed 3x the period median, the placeholder values auditors investigate first. Self-suppresses below three positive amounts.
- Weekend-post rule. Surfaces entries dated Saturday or Sunday so reviewers can confirm out-of-hours posts match policy.
- Just-under-threshold rule. Flags amounts within 5 percent below the configured approval threshold, a standard structuring control. A threshold of zero disables it as an opt-in switch.
- Reversal-pair rule. Groups same-user, same-account, same-amount, same-day entries as candidate wash or duplicate pairs. Confirming debit-versus-credit direction is left to the reviewer or the calling module.
- Variance commentary. Produces a direction-aware budget-vs-actual headline highlighting the top-N largest movers. With a live provider configured, the hook returns the provider's natural-language paragraph in place of the template.
- Collections next-action ladder. Eight-branch deterministic dunning ladder from broken-promise escalation through demand letter, agency referral, and write-off candidate, with active promise-to-pay taking precedence over days-overdue.
- Pluggable provider registry. Per-company provider key (default manual) selecting manual, claude, openai, or local. Stubs self-register, validate credentials, and refuse live calls until a separate paid extension re-registers under the same key.
- Provider-failure fallback. Every capability catches a provider error and returns its deterministic result, regression-tested, so a missing or bad key never breaks the call site.
Honest about the edges
What this does not do, so nothing surprises you.
- This module ships the helper engine only. It includes no user views, no settings-screen widget, no stored outputs, and no consuming wiring in the budget, collections, or close modules. The capabilities return results to the caller and render nowhere on their own.
- The provider key is set on the company record through the ORM or by a provider extension module, not through a configuration screen in this package.
- Provider stubs for Claude, OpenAI, and local endpoints validate credentials but refuse live calls. Enabling real chat completion needs a separate paid provider extension that re-registers under the same key. No such extension ships in this package yet.
- Only the variance hook merges a live provider's reply today. The collections next-action and anomaly hooks call the provider but return the deterministic result; merging those replies is the paid provider extension's job.
- The reversal-pair rule flags same-user, same-amount, same-day, same-account duplicates as candidates. It does not itself confirm a matching debit-and-credit wash direction; that is left to the reviewer or the calling module.
- Results are not logged, persisted, or overridable by this module. There is no stored finding, suggestion, or audit record.
Odoo journal entry anomaly detection, Odoo 19 accounting AI, budget vs actual variance commentary Odoo, collections dunning next action Odoo, just-under-threshold structuring detection accounting, weekend posting journal entry control, pluggable LLM provider Odoo accounting, deterministic AI no API key accounting, local LLM Ollama Odoo accounting, rule-based fraud heuristics journal entries
Please log in to comment on this module