DEV Community

Thomas Virdis
Thomas Virdis

Posted on Edited on

DILIGENT: A Local Workspace for Structured Drug-Induced Liver Injury Review

Drug-induced liver injury is a hard call, and the difficulty is rarely about spotting a signal. A clinician looking at a rising ALT already knows something is happening. The hard part is the reasoning that has to follow: which of the patient's medications is a plausible cause, how the injury pattern reads on the lab values and the timeline, whether a competing explanation fits better, and whether the label of "causality" is defensible enough to act on.

That reasoning is structured. Causality assessment frameworks such as RUCAM and the DILIN expert-consensus categories, the Hy's Law thresholds, and the LiverTox monographs all exist precisely because the argument has to be laid out in a consistent, inspectable way. A lot of the work of a DILI review is therefore assembly and consistency rather than insight: collecting the right inputs, resolving the liver chemistry pattern, checking the same boxes every time, and keeping the evidence visible next to whatever conclusion gets written.

DILIGENT is an application for that part of the job. It is a local, single-user decision-support tool for structured DILI review: it collects the case, runs a deterministic pipeline over it, assembles an evidence bundle, and produces a reviewable draft assessment that a clinician can edit, approve, or reject. The draft is not an answer. It is the assembled case, written down in a form that can be checked.

DILI Agent with a structured fictional case ready for review

What a review looks like

The workflow is one screen at a time, and each step has a defined output.

Configure. The application needs several models, and it treats them as roles rather than as a single chatbot: a clinical model for the consultation step, a text extraction model for structured extraction, a revision model for editing passes, and a timeline model for chronological reconstruction. Each role can point at a local Ollama model or at a cloud provider. Where a provider needs a key, the key is stored by the backend and shown back only as a fingerprint, and it stays inactive until it is explicitly activated, so a rejected key cannot replace the one that works.

Enter the case. The DILI Agent form asks for the things the frameworks need: patient and case identifiers, demographics, the suspected drug with dose and timing, symptom onset and history, laboratory values with units and reference limits, concomitant medications, competing causes, dechallenge and rechallenge status, and the clinical question being asked. Where the deployment enables it, files can be attached.

Pre-flight checks. Before any model is called, rule-based checks run over the input. Blocking issues have to be fixed. Warnings can be acknowledged and carried forward. Section extraction confidence is enforced here too: an aggregate below 0.65 blocks the run, and between 0.65 and 0.85 the operator has to acknowledge the weakness. This is the first place where the design chooses to stop rather than guess.

The pipeline. The assessment runs as a background job, so a long consultation does not hold the browser. The stages are concrete: normalization, deterministic section extraction, structured LLM extraction of drugs, diseases and labs with bounded retries and a deterministic fallback, presentation hepatic pattern resolution, case qualification kept deliberately separate from drug attribution, conservative drug identity resolution, per-drug RUCAM evidence, an internal structured causality synthesis, Hy's Law status, an explicit severity grade, a mandatory competing-cause checklist, optional retrieval, a bounded clinical consultation, and finally the evidence bundle and the report with a faithfulness audit.

The R ratio is computed from paired ALT and ALP values at the presentation episode, each divided by its own laboratory upper limit of normal rather than by a shared reference: R at or above 5 reads hepatocellular, at or below 2 cholestatic, between 2 and 5 mixed, and the pattern stays indeterminate when the inputs cannot support the calculation. Case qualification is its own answer, too. Whether the labs meet the application's typical liver-injury detection criteria is recorded separately from which drug, if any, is implicated, and a qualifying episode is not treated as a diagnosis.

Review. The result lands in Clinical Sessions as two things side by side: the narrative report and the structured dossier behind it, including twelve acceptance questions answered with quotes and a fourteen-section dossier in the shape clinicians already expect from an FDA-style review. Drug matching is exposed rather than hidden, with per-drug flags distinguishing accepted matches from ambiguous ones that need a human decision and from missing ones. From there the report can be edited by hand, put through an LLM revision that becomes a new official version, compared against the previous version, saved, copied, or exported. A separate tab reconstructs the patient timeline, and Data Inspection shows the local catalogs the matching ran against.

Saved report showing detected drugs and the hepatotoxicity summary

The report is built from the evidence, not from the model

The design decision that shapes everything else is the order of operations. The final report is generated from a persisted evidence bundle that exists before any LLM summary is written. The narrative is then checked against that bundle by a faithfulness audit, and blocking faithfulness issues are finalization blockers: a session with an unresolved one is forced into "requires human review" and can never be marked successful.

Revisions get the same treatment rather than a lighter one. A revised report is audited again against the structured evidence before it can be persisted as a successful revision, so an editing pass cannot talk its way past a competing-cause, Hy's Law, causality or rechallenge safeguard that the deterministic layer already enforced.

The same instinct shows up in the extraction layer. When a model-based extraction fails, the pipeline falls back to deterministic rule-based parsers and records a fallback warning instead of failing the run or inventing content. Degradation is visible in the session rather than silent.

Causality stays conservative

Scoring a drug as a cause is where clinical software is most likely to overreach, so the causal semantics here are deliberately narrow. If the patient's own record already documents a RUCAM score, that score is preserved and mapped to its category. If it does not, the pipeline does not manufacture a numeric pseudo-score: it keeps a criterion-level evidence checklist, with its limitations stated, instead of a number nobody computed. RUCAM output is supportive rather than dispositive in either case.

The same line is drawn around drug-level knowledge. A LiverTox likelihood and an FDA DILIrank concern class are prior opinions about a drug, not patient-level causality, and neither is converted into a weight on this patient's case. A rechallenge is never recommended. A missing follow-up laboratory value is recorded as missing, not as negative, and a general laboratory improvement is not attributed to every medication in a polypharmacy case. Competing causes are checked against a mandatory list and carry four explicit states, excluded, not excluded, unknown and missing data, so an unresolved differential stays unresolved in writing.

None of this makes the tool cautious in a vague way. It makes each statement in the report traceable to either a computed value or an explicit absence, which is what an audit of the case would need.

Retrieval that runs on the machine

The RAG layer is optional per assessment, and its embedding stack is local by construction: the pinned IBM Granite multilingual embedding model, 384 dimensions, run through ONNX Runtime on CPU with a quantized artifact whose SHA-256 is checked against a pinned value. Retrieval itself is hybrid over LanceDB, combining vector similarity with text search, weighted so that vector evidence dominates while exact terms still matter.

The corpora come from updaters built into the application: LiverTox monographs retrieved through NCBI's machine services, the RxNorm-backed RxNav drug catalog, the FDA DILIrank workbook, and a documents folder you point the app at, which the desktop build selects through the native operating system picker. DILIrank is deliberately read-only and row-level: a record that cannot be linked deterministically to the canonical drug catalog stays inspectable but never feeds the clinical consultation. A retrieval run does not need a cloud embedding service, and it does not need to send the case anywhere to find the relevant monograph.

Models are a configuration choice

The four roles can run entirely on Ollama, drawing from a local catalog that includes general and medical models, or they can point at cloud providers. Switching is configuration rather than architecture. That matters for two audiences at once: a hospital-adjacent user who needs the case to stay on the workstation, and a researcher who wants to compare how different models handle the structured extraction and consultation steps over the same evidence bundle.

Patient timeline overview with review controls and chronology

Running it, and where the data lives

On Windows the application ships as a packaged desktop build: a portable executable and an MSI installer, a Tauri 2 shell using the system WebView2 runtime, and the Python backend frozen with PyInstaller into its own binary. Release artifacts carry SHA-256 manifests, and the published binaries are unsigned under a policy the release notes state plainly rather than leaving you to discover it at launch. Application data lives under the user's local application data directory, beside a hash-addressed runtime directory, so installing a new version does not touch the data the previous one wrote. A source mode is also available for anyone who would rather build from the tree; it pins the exact Python, Node, uv and Rust versions it expects.

macOS and Linux are supported in source mode only, with no one-step launcher, and containers are explicitly not supported: there is no Dockerfile in the repository and no official container path. Storage is a relational database, either embedded SQLite or an external PostgreSQL instance, and the API surface is described by a checked-in OpenAPI document so the client and backend cannot drift apart silently.

One caveat belongs in the first paragraph of any deployment discussion rather than the last: if the model roles are pointed at a cloud provider, the clinical text of the case leaves the machine. The local configuration exists, and the choice is the user's.

Timeline event inspector for a selected laboratory value

What it deliberately is not

DILIGENT is not a diagnostic device and does not replace clinical judgment. Every input, generated statement, conclusion and piece of exported text is the responsibility of the qualified clinician using it. It is a single-user tool: there is no account system, no multi-user deployment, no mobile client and no hosted service, and network deployment behind a reverse proxy is explicitly unsupported. The packaged build does add a loopback guard, a bootstrap token exchanged for a session cookie plus host and origin checks, but that is protection for one user on one machine, not a login system. It does not train or fine-tune models, and it does not publish accuracy numbers, because none have been measured. The repository ships user documentation, architecture documentation and runtime documentation instead, which is the honest artifact for software at this stage.

The licence is the GNU General Public License, version 3 or any later version, so it is free software in the full sense: inspectable, modifiable, and redistributable under the same terms.

Data Inspection view filtered to public drug catalog records

Who this is for

If you work with drug-induced liver injury and you have ever wanted the case assembled the way the frameworks actually specify it, with the scoring visible and the report traceable line by line to the evidence behind it, this is worth an afternoon. It runs on a workstation, it takes a fictional case in minutes, and it will show you exactly how it reached whatever it says.

The repository, documentation and packaged Windows builds are at github.com/CTCycle/DILIGENT-Clinical-Copilot.


Top comments (0)