docs align memory and audio backup behavior
This commit is contained in:
parent
4a020fb7b0
commit
19c9e8ba1e
8 changed files with 46 additions and 67 deletions
|
|
@ -124,9 +124,11 @@ Applied to: `soap.js`, `hpi.js`, `refine.js`, `sickVisit.js`, `wellVisit.js`,
|
|||
|
||||
### Physician memories
|
||||
|
||||
Saved corrections are injected into prompts as `[STYLE HINTS (low priority)]`
|
||||
with 200-character snippets. The low-priority wording prevents smaller models
|
||||
from hallucinating content from the correction examples into the current note.
|
||||
Saved templates and prompt preferences are injected into prompts as
|
||||
`[STYLE HINTS (low priority)]` when they belong to AI-context categories. The
|
||||
low-priority wording prevents smaller models from hallucinating content from a
|
||||
stored template into the current note. `custom` memories and legacy
|
||||
`correction_*` rows are not prompt context.
|
||||
|
||||
## API call logging
|
||||
|
||||
|
|
|
|||
|
|
@ -844,36 +844,15 @@ Delete a memory.
|
|||
|
||||
### GET /api/memories/context
|
||||
|
||||
Retrieve all memories formatted for injection into AI generation prompts.
|
||||
Retrieve AI-context template/preference rows formatted for injection into AI
|
||||
generation prompts. `custom` rows and legacy `correction_*` rows are excluded.
|
||||
|
||||
- **Auth required:** Yes
|
||||
- **Response:**
|
||||
```json
|
||||
{
|
||||
"context": "string"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### POST /api/memories/correction
|
||||
|
||||
Automatically save a style correction as a memory. Used when the physician corrects AI output.
|
||||
|
||||
- **Auth required:** Yes
|
||||
- **Request body:**
|
||||
```json
|
||||
{
|
||||
"section": "string",
|
||||
"original_snippet": "string",
|
||||
"corrected_snippet": "string"
|
||||
}
|
||||
```
|
||||
- **Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"id": "number"
|
||||
"success": true,
|
||||
"context": "string"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -138,20 +138,23 @@ Draft/complete encounter workspace. Auto-expires (default 7 d,
|
|||
|
||||
### `user_memories`
|
||||
|
||||
Per-user clinical-style hints injected into AI prompts.
|
||||
Per-user template and preference rows. Only selected categories are injected
|
||||
into AI generation through `/api/memories/context`; `custom` rows are stored
|
||||
for the user but not included in prompt context.
|
||||
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
| id | SERIAL PK | |
|
||||
| user_id | INTEGER FK users.id ON DELETE CASCADE | |
|
||||
| category | TEXT NOT NULL DEFAULT 'custom' | `physical_exam`, `ros`, `encounter_format`, `custom`, `template_*`, `correction_*` |
|
||||
| name | TEXT NOT NULL | |
|
||||
| content | TEXT NOT NULL | |
|
||||
| category | TEXT NOT NULL DEFAULT 'custom' | Valid categories: `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `custom`, `template_soap`, `template_hpi`, `template_wellvisit`, `template_sickvisit`, `template_ed`. Legacy `correction_*` rows may exist but are filtered out. |
|
||||
| name | TEXT NOT NULL | Encrypted with `enc1:` for new rows |
|
||||
| content | TEXT NOT NULL | Encrypted with `enc1:` for new rows |
|
||||
| created_at, updated_at | TIMESTAMPTZ DEFAULT NOW() | |
|
||||
|
||||
### `audio_backups`
|
||||
|
||||
Retry store for failed-transcription audio.
|
||||
Optional 24-hour encrypted recovery store for recordings when transcription
|
||||
fails, so users can retry without re-recording.
|
||||
|
||||
| Column | Type | Notes |
|
||||
|---|---|---|
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ Important keys:
|
|||
Draft encounters (7-day auto-expiry). Columns: `label`, `enc_type`, `transcript`, `generated_note`, `partial_data` (JSON), `status`, `expires_at`.
|
||||
|
||||
#### `user_memories`
|
||||
User templates fed into AI generation. `category` is one of: `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `custom`.
|
||||
User templates and preferences. `/api/memories/context` injects only AI-context categories: `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `template_soap`, `template_hpi`, `template_wellvisit`, `template_sickvisit`, `template_ed`. `custom` rows are user-visible storage but are not prompt context. Legacy `correction_*` rows may exist but are filtered out.
|
||||
|
||||
### Learning Hub Tables
|
||||
|
||||
|
|
|
|||
|
|
@ -243,24 +243,19 @@ docker exec -w /app pediatric-ai-scribe npm run migrate:new -- add_my_table
|
|||
3. Admin-editable automatically through `PUT /api/admin/config` which accepts
|
||||
arbitrary keys.
|
||||
|
||||
## Physician memory / correction tracker
|
||||
## Physician Templates And Preferences
|
||||
|
||||
1. On note generation, `trackAIOutput(elementId, text)` captures the original
|
||||
output in memory.
|
||||
2. User edits the note in a contenteditable field.
|
||||
3. On Save, `saveCorrection(elementId, section)` diffs current vs. original.
|
||||
4. If changed by > 2 words or > 20 characters, `POST /api/memories/correction`
|
||||
stores the before/after in `user_memories` with category
|
||||
`correction_{section}`.
|
||||
5. Next generation: `GET /api/memories/context` fetches the 10 most recent per
|
||||
category and `src/utils/prompts.js` injects them as
|
||||
`[STYLE HINTS (low priority)]` 200-character snippets.
|
||||
|
||||
Tabs with correction capture: Live Encounter, SOAP, Dictation, Sick Visit,
|
||||
Well Visit (Hospital Course and Chart Review save corrections when available
|
||||
but don't always have a trackable single output element).
|
||||
|
||||
Maximum 20 corrections retained per category (oldest deleted).
|
||||
1. Settings saves user templates/preferences through `/api/memories` into
|
||||
`user_memories`.
|
||||
2. New rows encrypt `name` and `content` with the shared `enc1:` string format.
|
||||
3. `GET /api/memories/context` decrypts rows and returns only AI-context
|
||||
categories: `physical_exam`, `ros`, `encounter_format`, `family_history`,
|
||||
`assessment_plan`, `template_soap`, `template_hpi`, `template_wellvisit`,
|
||||
`template_sickvisit`, and `template_ed`.
|
||||
4. `custom` rows remain visible in settings but are not included in prompt
|
||||
context.
|
||||
5. Legacy `correction_*` rows from the removed correction-learning feature are
|
||||
filtered out rather than deleted.
|
||||
|
||||
## Route reference
|
||||
|
||||
|
|
|
|||
|
|
@ -916,16 +916,15 @@ signatures are simple and the provider branches are well-isolated.
|
|||
A worked example of how the layers compose. Tab: Sick Visit.
|
||||
|
||||
1. **Frontend collects inputs.** `sickVisit.js` reads:
|
||||
- The transcript area (which holds either browser-whisper output or
|
||||
the result of `transcribeAudio` after recording stop).
|
||||
- The transcript area, populated by the configured transcription API or
|
||||
the explicit opt-in browser speech-recognition fallback.
|
||||
- The structured ROS / PE radio buttons (NORMAL / ABNORMAL / NOT
|
||||
REVIEWED + free-text per-system notes).
|
||||
- Patient age and chief complaint.
|
||||
- The selected model (`getSelectedModel()` — tab-level dropdown wins
|
||||
over global).
|
||||
2. **Optional memory injection.** If user memories are enabled,
|
||||
`getUserMemoryContext()` pulls saved style hints (with the
|
||||
`[STYLE HINTS (low priority)]` framing — see `docs/ai-providers.md`).
|
||||
2. **Optional template injection.** `getUserMemoryContext()` pulls saved
|
||||
AI-context templates and preferences from `/api/memories/context`.
|
||||
3. **POST to /api/sick-visit.** The route:
|
||||
- Wraps every user-derived chunk in `<UNTRUSTED_*>` blocks via
|
||||
`wrapUserText`.
|
||||
|
|
|
|||
|
|
@ -744,7 +744,7 @@ From `server.js:229–303`:
|
|||
| `routes/refine.js` | `/api` | Take a draft note + correction prompt, return refined note |
|
||||
| `routes/logs.js` | `/api` | Client-side error log ingest (`/api/logs/client-error`) |
|
||||
| `routes/encounters.js` | `/api` | **Sacred.** Save / load / list / delete `saved_encounters`. Optimistic lock + idempotency. See section 13 |
|
||||
| `routes/memories.js` | `/api` | CRUD on `user_memories` (style hints, templates) |
|
||||
| `routes/memories.js` | `/api` | CRUD on `user_memories` (templates and prompt preferences) |
|
||||
| `routes/notes.js` | `/api` | CRUD on `personal_notes` + voice-to-AI-note + trash/restore |
|
||||
| `routes/documents.js` | `/api` | S3 doc upload / list / download / delete (metadata in `user_documents`) |
|
||||
| `routes/audioBackups.js` | `/api` | Server-side audio retry store (encrypted gzip, 24h TTL) |
|
||||
|
|
@ -979,9 +979,10 @@ Nextcloud or are exported.
|
|||
Created via migration `1777003849000_add-personal-notes.js`, soft-delete
|
||||
added via `1777090000000_notes-trash.js`.
|
||||
|
||||
**Distinct from `user_memories`.** Memories are AI prompt fuel
|
||||
(templates / style hints) — they get injected into LLM calls. Notes
|
||||
are pure clinician text that never goes to an AI. Both are encrypted.
|
||||
**Distinct from `user_memories`.** Memories store user templates and
|
||||
preferences. Only the AI-context categories are injected into LLM calls;
|
||||
`custom` rows are stored but excluded from prompt context. Notes are pure
|
||||
clinician text that never goes to an AI. Both are encrypted.
|
||||
|
||||
### `user_memories` — AI prompt fuel
|
||||
|
||||
|
|
@ -989,7 +990,7 @@ are pure clinician text that never goes to an AI. Both are encrypted.
|
|||
| ------ | ---- | ----- |
|
||||
| `id` | SERIAL PK | |
|
||||
| `user_id` | INTEGER FK (CASCADE) | |
|
||||
| `category` | TEXT NOT NULL DEFAULT 'custom' | `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `custom`, `template_soap`, `template_hpi`, `template_wellvisit`, `template_sickvisit`, `template_ed`, legacy `correction_*` (filtered out) |
|
||||
| `category` | TEXT NOT NULL DEFAULT 'custom' | `physical_exam`, `ros`, `encounter_format`, `family_history`, `assessment_plan`, `custom`, `template_soap`, `template_hpi`, `template_wellvisit`, `template_sickvisit`, `template_ed`. Legacy `correction_*` rows may exist but are filtered out. |
|
||||
| `name` | TEXT NOT NULL | **Encrypted** |
|
||||
| `content` | TEXT NOT NULL | **Encrypted** |
|
||||
| `created_at`, `updated_at` | TIMESTAMPTZ | |
|
||||
|
|
@ -1030,7 +1031,7 @@ guardrail.
|
|||
**Retention.** None — explicit. These tables grow forever. Disk
|
||||
should be sized accordingly. A future migration is on the roadmap.
|
||||
|
||||
### `audio_backups` — failed-transcription retry store
|
||||
### `audio_backups` — 24-hour transcription recovery store
|
||||
|
||||
| Column | Type | Notes |
|
||||
| ------ | ---- | ----- |
|
||||
|
|
@ -1043,9 +1044,9 @@ should be sized accordingly. A future migration is on the roadmap.
|
|||
| `created_at`, `expires_at` | TIMESTAMPTZ | 24h default |
|
||||
|
||||
**Who writes.** `routes/audioBackups.js` from the frontend
|
||||
`audioBackup.js` lifecycle when a transcription call fails — the
|
||||
client uploads the gzipped audio so the user can retry without
|
||||
re-recording.
|
||||
`audioBackup.js` lifecycle when a transcription call fails. The client
|
||||
uploads encrypted gzipped audio so the user can retry without re-recording;
|
||||
expired rows are deleted by the database cleanup job.
|
||||
|
||||
**Retention.** 24 hours via hourly cleanup. Audio is the most sensitive
|
||||
PHI in the system; short retention is intentional.
|
||||
|
|
|
|||
|
|
@ -1404,8 +1404,8 @@ reference shape.
|
|||
router.post('/<your-endpoint>', authMiddleware, async function(req, res) {
|
||||
try {
|
||||
var { ..., physicianMemories, model } = req.body;
|
||||
// Validate inputs, build context with wrapUserText() per field.
|
||||
// Append style hints if physicianMemories.
|
||||
// Validate inputs, build context with wrapUserText() per field.
|
||||
// Append template preferences if physicianMemories.
|
||||
var result = await callAI([
|
||||
{ role: 'system', content: PROMPTS.<yourPromptKey> + INJECTION_GUARD },
|
||||
{ role: 'user', content: context }
|
||||
|
|
|
|||
Loading…
Reference in a new issue