4.7 KiB
Global prompt administration and conversation budget
CLINICAL_ASSISTANT_CONVERSATION_CHARS is the sole conversation budget source.
Missing/empty uses 120000; nonempty values must validate as an integer from 1000
through 1000000. Invalid configuration returns 503 before query rewrite,
retrieval, handoff generation or chat provider calls. Counting is exactly
JavaScript string length (UTF-16 code units), including all history plus draft,
not model tokens. The old clinical_assistant.conversation_chars database value
is ignored and its generic config PUT is rejected. Status retains
conversationChars/conversationUnit and adds conversationEnv,
conversationSource, conversationMeasure. Admin config exposes the same
metadata as top-level conversationBudget: {limit,unit,measure,env,source}.
Full-history storage, 8 MiB saves and explicit successful-only handoffs are unchanged.
Catalogue and runtime use
Authenticated admins can use /api/admin/config/prompts. Its finite catalogue
contains 29 AI Scribe strings, clinical_assistant.system_behavior for clinical
text answers, and clinical_assistant.image_behavior for both existing image
routes. Each entry includes key, dbKey, value, family, purpose, usedBy,
revision, and editable. Scribe defaults remain in utils/prompts.js; clinical
defaults and image assembly are in utils/clinicalPrompts.js. All shipped default
text is unchanged. The poster instruction follows the input and precedes the
existing conditional portrait/landscape suffixes. Fixed clinical citation
safeguards, retrieval and generation settings are unchanged. Memories and private
user templates are not part of this catalogue.
Revision API
All endpoints below are under /api/admin/config and require the existing admin
gate. Prompt keys for history/reset/restore accept canonical dbKey or a bare
Scribe key.
PUT /:dbKeywith{value, expectedRevision?}saves nonempty string text.POST /prompts/:key/resetwith{expectedRevision?}removes the override and records the current shipped default.GET /prompts/:key/history?limit=20returns{success,revisions,revision}; newest first, at most 100. Metadata hasid,createdAt,createdBy,restoredFrom,wasDefault, never prompt text.GET /prompts/:key/revisions/:idreturns{success,revision}with the recordedvalueand metadata, checking key/id association.POST /prompts/:key/restorewith{revisionId,expectedRevision?}restores the recorded effective text as an explicit override, even when the historical revision used a different shipped default. The new revision haswasDefault:falseandrestoredFrompointing to the original. Reset again to follow shipped defaults.
Mutations return {success:true,value,revision}. Revision is the latest numeric
row id for that key, not a contiguous per-key counter; 0 means no history yet.
First mutation records the previous effective baseline plus the edit. Its baseline
actor is null (unknown), with capture time rather than an invented original edit
time. Provided stale expectedRevision returns 409 without changes; legacy callers
may omit it. Reload a conflicted editor before explicitly retrying. Other settings
retain their existing API contracts.
Persistence and verification
Apply 1777700000000_add-prompt-revisions.js through the existing migration runner
before edits. Missing schema fails prompt operations safely, without unversioned
fallback. The migration count increases from six to seven; old frozen checks that
assert six need a separate reviewed update, not changes to their evidence.
prompt_revisions stores global administrative text, not credentials or private
content, matching plaintext global app_settings storage. A finite-key constraint,
append-only update/delete trigger and same-key restore FK protect history. Actor
ids are historical integers, not cascading foreign keys. One db.pool.connect()
client holds a per-key transaction advisory lock for baseline, revision append and
setting upsert/delete. Rollbacks do not publish memory changes; only committed
values mutate the original shared Scribe object. Scribe's existing process-local
cache model remains; this slice does not introduce multi-process invalidation.
Run node --test test/prompt-administration.test.js test/clinical-conversation.test.js
with synthetic service boundaries, and the complete npm test suite. Tests include
actual admin middleware/routes, rollback/concurrency, missing schema, old-default
restore, default byte hashes, object identity and startup races, exact UTF-16
boundaries, legacy DB ignoring, and both image routes. Migration SQL is dry-run
through the installed node-pg-migrate engine, not applied to a live database.