Build1 distinct publisher3 min readUpdated
A developer wired runtime schema introspection, vector field matching and a local LLM repair loop into Odoo 17, then published the failure list. The failures define the boundary.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
A developer published a build log for a middleware layer that reads an Odoo instance's live schema at runtime, semantically maps messy incoming keys to real fields, and when Odoo rejects a write, hands the actual error to a local LLM, takes a proposed fix and retries, capped at three attempts [s1c2][s1c3][s1c4]. It matters because the enumerated failures, not the headline success rate, are what tell you where such a layer can be trusted in production.
The premise is sound and familiar to anyone who has integrated against a customized ERP: businesses add their own fields, things like x_studio_client_tax_id or x_vendor_code_v2, and any integration with a hardcoded field list breaks the moment the schema diverges [s1c1]. The build avoids that by calling Odoo's fields_get() over XML-RPC rather than shipping a field map [s1c2]. Every field is embedded locally with sentence-transformers, indexed in Qdrant, and matched by cosine similarity against embedded incoming keys [s1c3]. The repair loop is a LangGraph state machine with distinct nodes for schema fetch, create attempt and repair [s1c4]. The whole thing runs on local models, with Ollama serving Qwen2.5 3B as the repair agent and no hosted API in the path [s1c6].
The eval is six labeled cases: five deliberately broken against different Odoo validation rules, one clean control [s1c7]. Reported results are 83.3 percent overall self-healing success, 33.3 percent first-try success, and 1.6 average attempts to success [s1c8][s1c9][s1c10]. At that sample size, 83.3 percent means five of six cases landed [1] and 33.3 percent means two [2]. Since one of the six was a clean control that needed no repair at all, at most one of the five broken payloads went in correctly on the first pass [2]. The author's own reading is that the first-try number is the real cost of a 3B local model versus a hosted one [s1c11].
Three failures are worth carrying into your own design. First, given an invalid selection value and the live schema in the prompt listing the valid options, the model proposed "Customer" and "Supplier", values that were valid in Odoo 8 [s1c12]; the author attributes this to smaller instruction-tuned models trusting pretraining priors over supplied context [s1c13]. Second, the query "notes" matched Odoo's built-in comment field at 0.4969 similarity, ahead of the custom x_studio_delivery_notes at 0.4707 [s1c14]. Neither cleared the 0.75 auto-apply threshold, so both were flagged for human review [s1c15]. The gap between the two candidates was 0.0262, and the winner sat 0.2531 below the threshold [4], which is what an honest ambiguous result looks like rather than a near miss. Third, an invalid country_id pointing at a nonexistent record failed all three attempts [s1c16]. Dropping or emptying a bad selection value is reasoning a model can do; fabricating a valid foreign key is not [s1c16].
The PDF path is the least resolved. An early version extracted text, pulled "Label: Value" pairs and fed them straight into the healing loop, and the model guessed blindly at field names until the author routed extraction through the same confidence guardrail as everything else [s1c17].
Watch the denominator. Six cases and one 3B model is a shape, not a benchmark, and the load-bearing constraints, the 0.75 gate, the three-attempt cap and the fact that referential fixes are out of scope, are the parts that would need to hold at volume [s1c7][s1c15][s1c4][s1c16].
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The author built a small labeled eval harness of 6 cases, 5 deliberately broken across different Odoo validation rules and 1 clean control.
Enterprise ERP platforms like Odoo are customized constantly, with businesses adding their own fields such as x_studio_client_tax_id or x_vendor_code_v2; hardcoded integrations break the instant a database schema diverges from what they expect, via a missing field, invalid selection value or type mismatch.
The middleware performs schema introspection via Odoo's fields_get() over XML-RPC, including custom fields, with no hardcoded field lists anywhere.
Every Odoo field is embedded locally using sentence-transformers and indexed in Qdrant; incoming messy keys are embedded the same way and matched by cosine similarity.
The self-healing loop is a LangGraph state machine with nodes for schema fetch, create attempt and repair, and a conditional edge routing to repair-and-retry on failure, capped at 3 attempts.
The stack is a Next.js dashboard connected by WebSocket to a FastAPI backend, which talks to Odoo 17 in Docker over XML-RPC, plus Qdrant for local embeddings and field search and Ollama for local LLM payload repair.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Specific but single-source and self-run
The account is unusually concrete for a build post — named components, exact similarity scores (0.4969 vs 0.4707), a stated 0.75 threshold, a 3-attempt cap and three headline metrics that are internally consistent with a six-case harness. But all of it is one first-party narrative with no referenced repository, harness code, logs or independent replication, and the sample is six cases against a local Docker Odoo 17 instance, so nothing is verifiable outside the author's own report.
No adoption evidence supplied
The supplied material documents a personal prototype running against a local Docker Odoo 17 instance. There is no release, package, repository, licence, production deployment, external user, customer or usage disclosure to measure, and no third-party has reported using it. Adoption cannot be scored without inventing facts.
Mildly understated relative to its own framing
The post's framing runs counter to the usual direction of overstatement: it leads with failures, publishes a 33.3 percent first-try rate, names a case that failed all three repair attempts, and declines to claim the foreign-key limitation is fixable. That disclosure sits below what the phrase 'self-healing AI layer' would normally imply, hence a slightly negative gap. It is not more negative because the headline 83.3 percent rests on six cases with no baseline, and the generalization about small models trusting priors over context comes from one observation — so the underlying claim of a working general capability remains thinly evidenced in either direction.
Personal portfolio incentive, no disclosed vendor stake
The author is publishing a self-built project on a developer platform, which carries a visible reputational and portfolio incentive to appear capable. Countervailing factors are that the stack is entirely local open components with zero API spend, no sponsor, vendor, employer or commercial offering is disclosed, nothing is being sold or funded, and the post spends most of its length on failures — an odd choice for a purely promotional piece.
Moderate confidence in a narrow, self-reported result
Confidence is supported by internal consistency: the three metrics reconcile arithmetically with the six-case harness, the failure modes are mechanically plausible for Odoo's validation behaviour, and the foreign-key limit follows from first principles rather than assertion. It is capped by the single-publisher, single-author basis, absent artifacts, unpublished per-case outcomes, an unverifiable eval, and the absence of any adoption signal, so the assessment covers what the author reports rather than how the system behaves at scale.
build
Semantic code search over a monorepo is now a plumbing job, and the plumbing is the hard part1 distinct publisher
build
DuckDB's vss extension removes a database from your RAG stack, then names the price1 distinct publisher
build
Qwen 3.8's Apache-licensed 27B is the one you can actually own, and its KV cache is why1 distinct publisher
build
The stopping problem: an LLM rewrite loop that converged on code javac rejected1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 18, 2026