The feature was removed; the docs still described it as live. Worst of it was api-reference.md, which documented nine /api/learning endpoints and fourteen /api/admin/learning CMS endpoints — routes that answer 404 — plus POST /api/user/webdav-path, whose column was dropped by migration. Anyone reading them was reading fiction. Checked against the running system rather than assumed: no learning table exists, users.webdav_learning_path is gone, generated_image_links is gone, and no route mounts /api/learning or /api/admin/learning. Two things that look like Learning Hub and are not, so they stay: - learningRetrieval.js is live — My Resources uses it. Its settings keep the learning.* names because renaming them would orphan whatever an administrator has already set. retrieval-tuning.md now says so instead of listing the rows under two different feature names. - the moderator role is still assignable. It gated the CMS and now grants nothing; authentication.md says that rather than implying powers it does not have. moderatorMiddleware has no callers left, which is worth removing on its own. auth-admin-learning.md is now auth-admin.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
5.2 KiB
Ped AI And Milvus
Last updated: 2026-09-11
What Ped-AI is, which Milvus is which, and where each kind of data lives. Written for the operator handbook, so it says where things are rather than how they are coded.
What Ped-AI is
A clinical documentation assistant. Two halves:
- Workspace — encounter notes, dictation, SOAP, well and sick visits, ED, hospital course, calculators, My Resources. Each generates text with an LLM through the LiteLLM gateway.
- Clinical Assistant — a chat that answers only from an indexed medical library, with numbered citations back to the source documents.
It runs as one container, pediatric-ai-scribe, on 127.0.0.1:3552 behind
Caddy. Postgres and Redis are its own; everything else it talks to belongs to
another stack.
The two Milvus servers
They are easy to confuse, and both listen on 19530. Connecting to the wrong one succeeds at the network level and then fails authentication, because each has its own users — so a mistake here looks like a password problem.
| Which | Container | Database | Collection | Holds |
|---|---|---|---|---|
| Clinical | nextcloud-mcp-server-milvus-1 |
default |
mcp_bge_m3_1024 |
The medical library Ped-AI answers from. ~1.8M chunks. |
| Personal assistant | personal-assistant-storage-milvus-basic-milvus-1 |
basic |
personal_assistant_bge_m3_1024 |
Your Nextcloud mail, notes, tables and files. |
Both embed with bge-m3 at 1024 dimensions, which is what the collection names
now say. Neither is reachable from the internet: the personal one publishes no
ports at all, the clinical one is bound to 127.0.0.1.
Repositories, renamed 2026-09-11 to match what they hold:
personal-assistant-storage-milvus— wasped-ai-storageclinical-storage-milvus— wasnextcloud-mcp-server, and runs no MCP server, only etcd, MinIO and Milvus
Container and volume prefixes still read ped-ai-storage_* on anything not yet
migrated; the project name is pinned deliberately, because changing it makes
Compose create empty volumes instead of finding the existing ones.
How Milvus stores its data
Milvus keeps segment files in MinIO, not on a local disk, and its metadata in
etcd. That matters: COMMON_STORAGETYPE=local writes segments relative to the
working directory, so recreating the container destroys them while etcd still
references them, and the collection then hangs at Loading forever. Each Milvus
has its own MinIO and its own etcd container.
Access is per-database and per-collection. Renaming a collection revokes its grants, because a grant names the collection — after any rename, re-run the bootstrap that provisions the roles.
Where each kind of data lives
| Data | Where |
|---|---|
| Accounts, notes, encounters, saved resources | Postgres (pedscribe) |
| Generated images | MinIO bucket generated-images |
| Voice recordings, kept 24 hours | MinIO bucket audio-backups |
| Medical library chunks | Clinical Milvus |
| Nextcloud mail, notes, tables, files | Personal assistant Milvus |
Quizzes are ordinary relational tables and use no vectors at all.
How a question is answered
- The browser posts to
/api/clinical-assistant/chat/stream. - Ped-AI calls the MCP tool
clinical_semantic_searchonmcp-server-mcp-1. - That searches the clinical Milvus and returns passages with scores.
- Ped-AI sends those passages to the chat model as the only permitted source.
- The answer streams back with numbered citations; the Sources panel shows the passages behind them.
If retrieval returns nothing, the assistant says so rather than answering from the model's own knowledge.
Recordings
Every recording is kept for 24 hours, whether or not its transcription succeeded, gzipped and encrypted before storage. A recording holds a screen wake lock while it runs, survives moving around the app, and is saved with the module it came from if the session ends. Recordings can be downloaded from Settings → Audio backups.
Transcription is a gateway model — currently mistral-voxtral-mini-transcribe.
The browser's own speech recognition is a separate, off-by-default setting; it
sends audio to the browser vendor and is not HIPAA-compliant.
Indexing
| Index | Written by | Source |
|---|---|---|
| Clinical | mcp-server-mcp-indexer-1 |
The medical library. Text extraction via unstructured, PyMuPDF4LLM and Tesseract. |
| Personal assistant | personal-assistant-storage-milvus-basic-indexer-1 |
Nextcloud. Mail first, then notes, deck, tables, calendar, todos, collectives, cookbook, talk, contacts, and files. PDF text via PyMuPDF4LLM. |
The folder the personal indexer walks is BASIC_INDEXING_DOCUMENTS_FOLDER. It
takes one folder or several separated by commas, each walked recursively:
BASIC_INDEXING_DOCUMENTS_FOLDER=Personal assistant,Clinical Notes
A complete listing is the authority for deletion, so moving that setting to a different folder removes the chunks of everything no longer under an indexed root.
Quick checks
curl -fsS -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3552/api/health
docker ps --format '{{.Names}} {{.Status}}' | grep -E 'pediatric-ai-scribe|milvus|indexer'
docker logs --since 10m personal-assistant-storage-milvus-basic-indexer-1 | grep -c Indexed