Professional pack for turning long, technical reports (medical, vehicle roadworthiness inspection, real-estate DPE energy diagnosis) into structured, actionable summaries. Designed for medical practices, vehicle inspection centers, real-estate diagnosticians and any A2A agent that needs to digest a raw document.
Table of contents
- Overview
- Architecture
- OODA diagram
- Quick Start
- Pack structure
- Supported report types
- Roadmap
- License
Overview
report-summarizer-v2 provides a summarization pipeline specific to structured
reports, with six dedicated OODA states:
- INGESTING: acquisition of the raw document.
- PARSING: text cleanup and extraction.
- EXTRACTING: identification of facts, risks and deadlines.
- SYNTHESIZING: production of a faithful, prioritized summary.
- FORMATTING: Markdown or JSON rendering depending on the consumer.
- DELIVERING: output to the A2A pipeline, a file or an API.
The pack guarantees fidelity, risk prioritization, actionability, neutrality and confidentiality.
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ REPORT SUMMARIZER v2.0 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Raw report (PDF / TXT / MD) │
│ │ │
│ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ INGESTING │───→│ PARSING │───→│ EXTRACTING │ │
│ └────────────┘ └────────────┘ └─────┬──────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ DELIVERING │←───│ FORMATTING │←───│ SYNTHESIZING│ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
Data flow
PDF/TXT/MD → pdftotext/pypdf → raw text → INGESTING → PARSING
│
▼
EXTRACTING → SYNTHESIZING → FORMATTING → DELIVERING
│
↓
points_cles[], risques[], recommandations[], echeances[]
OODA diagram
┌─────────────────────────────────────┐
│ IDLE / READY │
└──────────────┬──────────────────────┘
│ receive(report)
▼
┌─────────────────────────────────────┐
│ INGESTING │
│ Receive the raw document from a │
│ file, stdin or an API. │
└──────────────┬──────────────────────┘
│ ingest_complete()
▼
┌─────────────────────────────────────┐
│ PARSING │
│ Convert PDF→text, clean up, │
│ normalize the encoding. │
└──────────────┬──────────────────────┘
│ parse_complete()
▼
┌─────────────────────────────────────┐
│ EXTRACTING │
│ Identify key points, risks, │
│ recommendations and deadlines. │
└──────────────┬──────────────────────┘
│ extract_complete()
▼
┌─────────────────────────────────────┐
│ SYNTHESIZING │
│ Produce a concise, prioritized │
│ summary grounded in the │
│ source report. │
└──────────────┬──────────────────────┘
│ synthesize_complete()
▼
┌─────────────────────────────────────┐
│ FORMATTING │
│ Render the summary as Markdown │
│ or JSON per the --format option. │
└──────────────┬──────────────────────┘
│ format_complete()
▼
┌─────────────────────────────────────┐
│ DELIVERING │
│ Emit to a file, stdout, │
│ a webhook or an A2A queue. │
└──────────────┬──────────────────────┘
│ deliver_complete()
▼
┌─────────────────────────────────────┐
│ FEEDBACK LOOP │
│ Quality metrics → iteration │
└─────────────────────────────────────┘
Quick Start
1. Installation
cd scripts/
chmod +x install.sh
./install.sh
2. Configuration
cp templates/summary_config.yaml ./summary.yaml
cp templates/risk_thresholds.yaml ./risks.yaml
# Edit summary.yaml and risks.yaml
3. Testing a prompt
python3 scripts/test_prompt.py --prompt medical --input templates/sample_medical.txt
python3 scripts/test_prompt.py --prompt dpe --input templates/sample_dpe.txt
4. Running the pipeline
python3 scripts/run_agent.py --type dpe --input templates/sample_dpe.txt --format json
python3 scripts/run_agent.py --type controle_technique --input templates/sample_ct.txt --format md
Pack structure
report-summarizer-v2/
├── README.md <- This file
├── SOUL.md <- Summarization-specific OODA states
├── PROMPTS.md <- 5 named prompts
├── CHECKLIST.md <- 35 steps with commands
├── SPEC.md <- Configurable parameters
├── CHANGELOG.md <- v1.0.0 and v2.0.0 history
├── report-summarizer-v2.json <- Manifest and stats
├── scripts/
│ ├── install.sh <- Installs Python, dependencies and checks
│ ├── config.yaml <- Commented configuration template
│ ├── test_prompt.py <- Tests a prompt with Ollama or a stub
│ └── run_agent.py <- Minimal summarization pipeline
└── templates/
├── summary_config.yaml
├── risk_thresholds.yaml
├── sample_medical.txt
├── sample_dpe.txt
└── sample_ct.txt
Supported report types
| Type | Input examples | Main output |
|---|---|---|
medical |
Clinical report, labs, imaging | Key points, risks, deadlines |
controle_technique |
Vehicle inspection (CT) report | Failures, re-inspection |
dpe |
Energy performance diagnosis (DPE) | Energy class, works, deadline |
Roadmap
- v2.1: Native PDF support (pypdf + OCR fallback).
- v2.2: Multi-document summaries and comparison over time.
- v2.3: Native A2A integration with consensus between summarizers.
Use a local model (Ollama)
The optional LLM step can also run on your own machine through Ollama, so no text leaves your server. No account and no API key.
ollama pull <model> # any chat model you like
export PACK_LLM=ollama # prefer Ollama even if a coding-agent CLI is installed
export PACK_OLLAMA_MODEL=<model> # optional: default is the first chat model the server lists
python3 -c "import llm_adapter; print(llm_adapter.detect())" # prints: ollama
PACK_OLLAMA_HOSTpoints to another server (defaulthttp://127.0.0.1:11434);OLLAMA_HOSTis also read whenPACK_LLM=ollama.PACK_OLLAMA_NUM_CTXsets the context size if your reports or prompts are long.- Without
PACK_LLM, a local Ollama server is used only when no Claude Code, Kimi Code or Codex CLI is found. - If the server is down or the model is missing, the pack keeps working in its deterministic mode.
- With
PACK_LLM=ollama(orPACK_LLM=off), the summarizer never falls back to a hosted API, even ifANTHROPIC_API_KEYis set.
Learning memory (local and private)
Every LLM call this pack makes is journaled in ./.pack_memory/ next to the code, so the pack can improve for you. Nothing is ever sent anywhere.
- What is kept: the task name, the masked input, the masked answer, status and latency. Keys, tokens, e-mails, phone numbers, IP addresses, card and IBAN numbers and personal paths are masked before writing; the system prompt is never stored.
- Teach it:
python3 pack_memory.py feedback last okconfirms a result,python3 pack_memory.py feedback last bad --fix "the right answer"corrects it. Confirmed and corrected runs are reused as validated examples when a similar input comes in. Unrated runs are never injected into a prompt. - Find similar cases:
python3 pack_memory.py similar "some text"andpython3 pack_memory.py clusters(groups of near-identical failures) work in plain Python, no model needed. Optional meaning-based matching uses an embedding model you already run locally:python3 pack_memory.py enable-semantic(Ollama on this machine only). - Share, only if you want:
python3 pack_memory.py exportwrites an anonymised summary (counts, statuses, size buckets, no text) for you to review. - Control:
PACK_MEMORY=0turns it off,PACK_MEMORY_STORE_TEXT=0keeps fingerprints only,python3 pack_memory.py purge --yeswipes it.
License
Proprietary — internal use only. Do not redistribute.
Last updated: 2026-06-18
