pediatric-ai-scribe-v3/public/components/my-resources.html
Daniel 055a86bbb1
Some checks failed
Forgejo Android APK / Root app tests (push) Successful in 55s
Forgejo Docker Build / Root app tests (push) Successful in 47s
Forgejo Android APK / Build signed APK (push) Successful in 1m59s
Forgejo Docker Build / Build Docker image (push) Successful in 18s
Forgejo Docker Build / Deploy to the host (push) Failing after 0s
feat: My Resources says what it is, offers its sources in one place, and Modify gets them too
The screen had been trimmed to controls with no explanation of what it was for;
"Private to you" said who could see it, not what it did. It now opens with a
sentence that says what you get and how you get it out, and the header reads
"Only you can see these".

The four choices — clinical library, PubMed, web, illustration — are one "Draw
on" group instead of four separate rows, with the library ticked by default.
Each option hides itself when an administrator has not enabled it, so nothing
appears that a person could tick and then be refused.

Modify offers exactly the same choices. It had none, so "add what the 2024 trial
showed" was answered from the model's memory rather than by looking anything up.
Generate and Modify now go through one gatherSources(), so they cannot drift
into offering different things or searching them differently.

Writing "include a diagram of the airway" in the instructions now switches the
illustration option on and says why, rather than the request being dropped in
silence. Switching it off by hand sticks — the hint then reminds instead of
fighting — and when no image model is configured it says so rather than
pretending. Both the generate and modify boxes behave this way.

Two things found by testing this rather than assuming it.

PubMed ANDs every mapped term, so one unrecognised word takes the query to zero.
"febrile seizures" returns six results and "febrile seizures in under-fives"
returns none; "the anatomy of croup: subglottic narrowing and the steeple sign"
returned none until it was narrowed to "anatomy croup", which returns six. A
query that finds nothing is now retried against progressively shorter versions
of itself, longest first, and the response says which query actually worked so
the screen cannot report one that found nothing. Those extra calls tripped
NCBI's three-a-second limit and produced a 429, so retries are spaced and the
first attempt waits for nothing. Separately, the searches run on the topic while
the library retrieval also gets the instruction: retrieval is semantic and
benefits from the context, but a keyword engine handed a whole sentence returns
nothing.

And when a search was asked for and came back empty, the prompt now says not to
invent a citation, a PMID or a URL to fill the gap. Without that the model
supplies them from memory, and a fabricated PMID looks exactly like a real one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
2026-09-11 18:54:17 +02:00

161 lines
9.1 KiB
HTML

<div class="card">
<div class="card-header">
<h3><i class="fas fa-folder-open"></i> My Resources</h3>
<span style="font-size:12px;color:var(--g500);">Only you can see these</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:14px;">
<p style="margin:0;font-size:13px;color:var(--g600);line-height:1.5;">
Build a teaching deck or handout on any topic &mdash; grounded in the clinical library,
the literature, or both &mdash; then revise it below and download it as PowerPoint,
Word or PDF.
</p>
<div class="admin-row">
<label for="mr-topic" class="admin-row-label">Topic</label>
<input id="mr-topic" type="text" class="admin-control" placeholder="e.g. febrile seizures in under-fives" maxlength="300">
</div>
<div class="admin-row">
<label for="mr-kind" class="admin-row-label">Format</label>
<div style="flex:1;display:flex;gap:10px;align-items:center;flex-wrap:wrap;min-width:0;">
<select id="mr-kind" class="admin-control" style="max-width:220px;">
<option value="presentation">Presentation (slides)</option>
<option value="article">Article (prose)</option>
</select>
<label style="font-size:12px;color:var(--g600);display:flex;align-items:center;gap:6px;">
Slides
<input id="mr-slide-count" type="number" min="3" max="30" value="8" style="width:70px;font-size:13px;padding:5px 8px;border:1px solid var(--g300);border-radius:6px;">
</label>
<label style="font-size:12px;color:var(--g600);display:flex;align-items:center;gap:6px;" id="mr-word-wrap" hidden>
Words
<input id="mr-word-count" type="number" min="200" max="3000" step="100" value="800" style="width:90px;font-size:13px;padding:5px 8px;border:1px solid var(--g300);border-radius:6px;">
</label>
</div>
</div>
<div class="admin-row" id="mr-model-row" hidden>
<label for="mr-model" class="admin-row-label">Model</label>
<div style="flex:1;display:flex;flex-direction:column;gap:4px;min-width:0;">
<select id="mr-model" class="admin-control" style="max-width:320px;"></select>
</div>
</div>
<!-- One group rather than four rows. Each option hides itself when an
administrator has not enabled it, so nothing appears that a person
could tick and then be refused. -->
<div class="admin-row" style="align-items:flex-start;">
<strong class="admin-row-label">Draw on</strong>
<div style="flex:1;display:flex;flex-direction:column;gap:8px;min-width:0;">
<label style="display:flex;align-items:center;gap:8px;font-size:13px;">
<input type="checkbox" id="mr-use-corpus" checked>
The clinical library
</label>
<label style="display:flex;align-items:center;gap:8px;font-size:13px;" id="mr-pubmed-row" hidden>
<input type="checkbox" id="mr-pubmed">
PubMed &mdash; cite published literature
<span style="font-size:12px;color:var(--g500);">The query goes to NCBI.</span>
</label>
<label style="display:flex;align-items:center;gap:8px;font-size:13px;flex-wrap:wrap;" id="mr-web-row" hidden>
<input type="checkbox" id="mr-web-search">
The web &mdash; for anything newer than the library
<span style="font-size:12px;color:var(--g500);">The query leaves this network; keep the topic non-identifying.</span>
</label>
<label style="display:flex;align-items:center;gap:8px;font-size:13px;" id="mr-images-row" hidden>
<input type="checkbox" id="mr-with-images">
Add one illustration
</label>
<!-- Filled in when the instructions ask for a figure the options do not
allow. Silence there is the failure worth avoiding. -->
<p id="mr-image-hint" style="margin:0;font-size:12px;color:#92400e;" hidden></p>
</div>
</div>
<div class="admin-row" style="align-items:flex-start;">
<label for="mr-refinement" class="admin-row-label">Instructions <span style="color:var(--g400);font-weight:400;">(optional)</span></label>
<textarea id="mr-refinement" class="admin-control" style="min-height:70px;resize:vertical;font-family:inherit;" placeholder="e.g. for FY1s, case-based, emphasise red flags, include a diagram of the airway"></textarea>
</div>
<div style="border-top:1px solid var(--g100);padding-top:12px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;">
<button id="btn-mr-generate" class="btn-sm btn-primary" type="button"><i class="fas fa-wand-magic-sparkles"></i> Generate</button>
<span id="mr-status" role="status" style="font-size:12px;color:var(--g600);"></span>
</div>
<!-- An illustration the model asked for. It renders here rather than in an
image history, because this feature does not have one and telling
someone to look somewhere that does not exist is worse than silence. -->
<div id="mr-images" style="display:flex;flex-direction:column;gap:10px;"></div>
</div>
</div>
<!-- Modify — change something already generated rather than starting again.
The markdown is what is stored, so "redo slide 4" is a text edit; the
resource keeps its id, its downloads and its place in the library. -->
<div class="card" style="margin-top:14px;">
<div class="card-header">
<h3><i class="fas fa-pen-to-square"></i> Modify</h3>
<span style="font-size:12px;color:var(--g500);">Revise one you already have</span>
</div>
<div style="padding:16px;display:flex;flex-direction:column;gap:14px;">
<div class="admin-row">
<label for="mr-modify-target" class="admin-row-label">Resource</label>
<select id="mr-modify-target" class="admin-control" style="max-width:420px;"></select>
</div>
<!-- The same choices as generating. A modification can need material the
original never had — "add what the 2024 trial showed" is a request for
sources, not a rewording — so the options are offered again rather
than inherited from whatever was ticked at the time. -->
<div class="admin-row" style="align-items:flex-start;">
<strong class="admin-row-label">Draw on</strong>
<div style="flex:1;display:flex;flex-direction:column;gap:8px;min-width:0;">
<label style="display:flex;align-items:center;gap:8px;font-size:13px;">
<input type="checkbox" id="mr-modify-corpus" checked>
The clinical library
</label>
<label style="display:flex;align-items:center;gap:8px;font-size:13px;" id="mr-modify-pubmed-row" hidden>
<input type="checkbox" id="mr-modify-pubmed">
PubMed &mdash; cite published literature
<span style="font-size:12px;color:var(--g500);">The query goes to NCBI.</span>
</label>
<label style="display:flex;align-items:center;gap:8px;font-size:13px;flex-wrap:wrap;" id="mr-modify-web-row" hidden>
<input type="checkbox" id="mr-modify-web-search">
The web &mdash; for anything newer than the library
<span style="font-size:12px;color:var(--g500);">The query leaves this network.</span>
</label>
<label style="display:flex;align-items:center;gap:8px;font-size:13px;" id="mr-modify-images-row" hidden>
<input type="checkbox" id="mr-modify-images">
Add one illustration
</label>
<p id="mr-modify-image-hint" style="margin:0;font-size:12px;color:#92400e;" hidden></p>
</div>
</div>
<div class="admin-row" style="align-items:flex-start;">
<label for="mr-modify-instructions" class="admin-row-label">What to change</label>
<div style="flex:1;display:flex;flex-direction:column;gap:4px;min-width:0;">
<textarea id="mr-modify-instructions" class="admin-control" style="min-height:70px;resize:vertical;font-family:inherit;" placeholder="e.g. split slide 4 into two, drop the pharmacology, add a summary slide at the end"></textarea>
<p style="margin:0;font-size:12px;color:var(--g500);">
The previous version is replaced.
</p>
</div>
</div>
<div style="border-top:1px solid var(--g100);padding-top:12px;display:flex;align-items:center;gap:10px;flex-wrap:wrap;">
<button id="btn-mr-modify" class="btn-sm btn-primary" type="button"><i class="fas fa-pen-to-square"></i> Apply changes</button>
<span id="mr-modify-status" role="status" style="font-size:12px;color:var(--g600);"></span>
</div>
</div>
</div>
<div class="card" style="margin-top:14px;">
<div class="card-header">
<h3><i class="fas fa-book"></i> Library</h3>
<button id="btn-mr-refresh" class="btn-sm btn-ghost" type="button"><i class="fas fa-rotate"></i> Refresh</button>
</div>
<div style="padding:12px 16px 0;">
<input id="mr-search" type="search" class="admin-control" placeholder="Search your resources by title or topic" autocomplete="off">
</div>
<!-- Bounded rather than unlimited: a long library otherwise pushes everything
else off the page. Tall enough to show several at a glance, and it
collapses to the content when there are only a few. -->
<div id="mr-list" style="padding:12px 16px;display:flex;flex-direction:column;gap:6px;max-height:360px;overflow-y:auto;"></div>
</div>