Prompt-injection wrap: remaining AI routes
Applied the <UNTRUSTED_*> delimiter + INJECTION_GUARD pattern to:
- src/routes/sickVisit.js (chief complaint, transcript, dictation,
ROS, physical exam, diagnoses, style hints)
- src/routes/wellVisit.js (SSHADESS answers + full well-visit context)
- src/routes/chartReview.js (PMH + all visit content + labs)
- src/routes/hospitalCourse.js (all notes/H&P/ED + clarification
& update endpoints)
- src/routes/milestones.js (narrative + summary)
Each wraps patient-derived text in <UNTRUSTED_*>…</UNTRUSTED_*>
tags and appends the INJECTION_GUARD system instruction that tells
the model to treat wrapped content strictly as data. Operator-
supplied `additionalInstructions` stays unwrapped (trusted).
This commit is contained in:
parent
63f77aa9cf
commit
ea03db3d45
5 changed files with 60 additions and 90 deletions
|
|
@ -4,6 +4,7 @@ const { callAI } = require('../utils/ai');
|
||||||
const PROMPTS = require('../utils/prompts');
|
const PROMPTS = require('../utils/prompts');
|
||||||
const { authMiddleware } = require('../middleware/auth');
|
const { authMiddleware } = require('../middleware/auth');
|
||||||
var logger = require('../utils/logger');
|
var logger = require('../utils/logger');
|
||||||
|
var { wrapUserText, INJECTION_GUARD } = require('../utils/promptSafe');
|
||||||
|
|
||||||
// Generate chart review
|
// Generate chart review
|
||||||
router.post('/generate-chart-review', authMiddleware, async (req, res) => {
|
router.post('/generate-chart-review', authMiddleware, async (req, res) => {
|
||||||
|
|
@ -21,7 +22,7 @@ router.post('/generate-chart-review', authMiddleware, async (req, res) => {
|
||||||
|
|
||||||
const today = new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
|
const today = new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
|
||||||
let clinicalData = `Today's date: ${today}\nPatient: ${patientAge || 'Unknown'}, ${patientGender || 'Unknown'}`;
|
let clinicalData = `Today's date: ${today}\nPatient: ${patientAge || 'Unknown'}, ${patientGender || 'Unknown'}`;
|
||||||
if (pmh) clinicalData += `\nPMH: ${pmh}`;
|
if (pmh) clinicalData += `\nPMH: ${wrapUserText('pmh', pmh)}`;
|
||||||
|
|
||||||
// Use the top-level review type to select the prompt —
|
// Use the top-level review type to select the prompt —
|
||||||
// the per-visit types only control data formatting, not the prompt.
|
// the per-visit types only control data formatting, not the prompt.
|
||||||
|
|
@ -37,29 +38,29 @@ router.post('/generate-chart-review', authMiddleware, async (req, res) => {
|
||||||
// Include ALL visit data regardless of per-visit type —
|
// Include ALL visit data regardless of per-visit type —
|
||||||
// an outpatient chart review should include subspecialty consults too
|
// an outpatient chart review should include subspecialty consults too
|
||||||
(visits || []).forEach(v => {
|
(visits || []).forEach(v => {
|
||||||
clinicalData += `\n\n=== OUTPATIENT VISIT (${v.date}) ===\n${v.content}`;
|
clinicalData += `\n\n=== OUTPATIENT VISIT (${v.date}) ===\n` + wrapUserText('visit', v.content || '');
|
||||||
if (v.labs && v.labs.trim()) clinicalData += `\n--- Labs from this visit (${v.date}) ---\n${v.labs}`;
|
if (v.labs && v.labs.trim()) clinicalData += `\n--- Labs from this visit (${v.date}) ---\n` + wrapUserText('labs', v.labs);
|
||||||
});
|
});
|
||||||
(subspecialty || []).forEach(s => {
|
(subspecialty || []).forEach(s => {
|
||||||
clinicalData += `\n\n=== SUBSPECIALTY: ${(s.specialty || 'Subspecialty').toUpperCase()} — ${s.specialistName || 'Unknown'} (${s.date}) ===\n${s.content}`;
|
clinicalData += `\n\n=== SUBSPECIALTY: ${(s.specialty || 'Subspecialty').toUpperCase()} — ${s.specialistName || 'Unknown'} (${s.date}) ===\n` + wrapUserText('consult', s.content || '');
|
||||||
if (s.labs && s.labs.trim()) clinicalData += `\n--- Labs from this visit (${s.date}) ---\n${s.labs}`;
|
if (s.labs && s.labs.trim()) clinicalData += `\n--- Labs from this visit (${s.date}) ---\n` + wrapUserText('labs', s.labs);
|
||||||
});
|
});
|
||||||
(edVisits || []).forEach(v => {
|
(edVisits || []).forEach(v => {
|
||||||
clinicalData += `\n\n=== ED VISIT (${v.date}) ===\n${v.content}`;
|
clinicalData += `\n\n=== ED VISIT (${v.date}) ===\n` + wrapUserText('ed_visit', v.content || '');
|
||||||
if (v.labs && v.labs.trim()) clinicalData += `\n--- Labs from this visit (${v.date}) ---\n${v.labs}`;
|
if (v.labs && v.labs.trim()) clinicalData += `\n--- Labs from this visit (${v.date}) ---\n` + wrapUserText('labs', v.labs);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (labs && labs.length > 0) {
|
if (labs && labs.length > 0) {
|
||||||
clinicalData += '\n\n=== ADDITIONAL LABS (not tied to a specific visit) ===';
|
clinicalData += '\n\n=== ADDITIONAL LABS (not tied to a specific visit) ===';
|
||||||
labs.forEach(l => { clinicalData += `\n${l.date ? l.date + ': ' : ''}${l.values}`; });
|
labs.forEach(l => { clinicalData += `\n${l.date ? l.date + ': ' : ''}` + wrapUserText('labs', l.values || ''); });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (additionalInstructions) {
|
if (additionalInstructions) {
|
||||||
prompt += `\n\nADDITIONAL INSTRUCTIONS:\n${additionalInstructions}`;
|
prompt += `\n\nADDITIONAL INSTRUCTIONS (operator-supplied, trusted):\n${additionalInstructions}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await callAI([
|
const result = await callAI([
|
||||||
{ role: 'system', content: prompt },
|
{ role: 'system', content: prompt + INJECTION_GUARD },
|
||||||
{ role: 'user', content: clinicalData }
|
{ role: 'user', content: clinicalData }
|
||||||
], { model, maxTokens: 4000 });
|
], { model, maxTokens: 4000 });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ const { callAI } = require('../utils/ai');
|
||||||
const PROMPTS = require('../utils/prompts');
|
const PROMPTS = require('../utils/prompts');
|
||||||
const { authMiddleware } = require('../middleware/auth');
|
const { authMiddleware } = require('../middleware/auth');
|
||||||
var logger = require('../utils/logger');
|
var logger = require('../utils/logger');
|
||||||
|
var { wrapUserText, INJECTION_GUARD } = require('../utils/promptSafe');
|
||||||
|
|
||||||
// Generate hospital course
|
// Generate hospital course
|
||||||
router.post('/generate-hospital-course', authMiddleware, async (req, res) => {
|
router.post('/generate-hospital-course', authMiddleware, async (req, res) => {
|
||||||
|
|
@ -51,41 +52,35 @@ router.post('/generate-hospital-course', authMiddleware, async (req, res) => {
|
||||||
|
|
||||||
// Build the complete clinical data
|
// Build the complete clinical data
|
||||||
let clinicalData = `Patient: ${patientAge || 'Unknown'}, ${patientGender || 'Unknown'}`;
|
let clinicalData = `Patient: ${patientAge || 'Unknown'}, ${patientGender || 'Unknown'}`;
|
||||||
if (pmh) clinicalData += `\nPMH: ${pmh}`;
|
if (pmh) clinicalData += `\nPMH: ` + wrapUserText('pmh', pmh);
|
||||||
if (setting) clinicalData += `\nSetting: ${setting}`;
|
if (setting) clinicalData += `\nSetting: ${setting}`;
|
||||||
if (los) clinicalData += `\nLength of Stay: ${los} days`;
|
if (los) clinicalData += `\nLength of Stay: ${los} days`;
|
||||||
clinicalData += `\nFormat: ${format}`;
|
clinicalData += `\nFormat: ${format}`;
|
||||||
|
|
||||||
if (edNote) {
|
if (edNote) {
|
||||||
clinicalData += `\n\n=== ED NOTE (${edNote.date || 'date unknown'}) ===\n${edNote.content}`;
|
clinicalData += `\n\n=== ED NOTE (${edNote.date || 'date unknown'}) ===\n` + wrapUserText('ed_note', edNote.content || '');
|
||||||
if (edNote.labs) clinicalData += `\nED Labs: ${edNote.labs}`;
|
if (edNote.labs) clinicalData += `\nED Labs: ` + wrapUserText('labs', edNote.labs);
|
||||||
}
|
}
|
||||||
|
if (hAndP) clinicalData += `\n\n=== H&P (${hAndP.date || 'date unknown'}) ===\n` + wrapUserText('h_and_p', hAndP.content || '');
|
||||||
|
|
||||||
if (hAndP) {
|
|
||||||
clinicalData += `\n\n=== H&P (${hAndP.date || 'date unknown'}) ===\n${hAndP.content}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort notes by date
|
|
||||||
const sortedNotes = [...notes].sort((a, b) => new Date(a.date) - new Date(b.date));
|
const sortedNotes = [...notes].sort((a, b) => new Date(a.date) - new Date(b.date));
|
||||||
sortedNotes.forEach((note, i) => {
|
sortedNotes.forEach((note, i) => {
|
||||||
clinicalData += `\n\n=== ${(note.type || 'Progress Note').toUpperCase()} - ${note.date || `Note ${i + 1}`} ===\n${note.content}`;
|
clinicalData += `\n\n=== ${(note.type || 'Progress Note').toUpperCase()} - ${note.date || `Note ${i + 1}`} ===\n` + wrapUserText('note', note.content || '');
|
||||||
});
|
});
|
||||||
|
|
||||||
if (labs && labs.length > 0) {
|
if (labs && labs.length > 0) {
|
||||||
clinicalData += '\n\n=== LABS ===';
|
clinicalData += '\n\n=== LABS ===';
|
||||||
labs.forEach(lab => {
|
labs.forEach(lab => { clinicalData += `\n${lab.date}: ` + wrapUserText('labs', lab.values || ''); });
|
||||||
clinicalData += `\n${lab.date}: ${lab.values}`;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (additionalInstructions) {
|
if (additionalInstructions) {
|
||||||
prompt += `\n\nADDITIONAL INSTRUCTIONS FROM PHYSICIAN:\n${additionalInstructions}`;
|
prompt += `\n\nADDITIONAL INSTRUCTIONS FROM PHYSICIAN (operator-supplied, trusted):\n${additionalInstructions}`;
|
||||||
}
|
}
|
||||||
|
if (physicianMemories) clinicalData += '\n\n[STYLE HINTS (low priority — only apply if relevant to the current note, never copy content from these examples)]\n'
|
||||||
if (physicianMemories) clinicalData += '\n\n[STYLE HINTS (low priority — only apply if relevant to the current note, never copy content from these examples)]\n' + physicianMemories + '\n[END STYLE HINTS]';
|
+ wrapUserText('style_hints', physicianMemories) + '\n[END STYLE HINTS]';
|
||||||
|
|
||||||
const result = await callAI([
|
const result = await callAI([
|
||||||
{ role: 'system', content: prompt },
|
{ role: 'system', content: prompt + INJECTION_GUARD },
|
||||||
{ role: 'user', content: clinicalData }
|
{ role: 'user', content: clinicalData }
|
||||||
], { model, maxTokens: 6000 });
|
], { model, maxTokens: 6000 });
|
||||||
|
|
||||||
|
|
@ -107,8 +102,8 @@ router.post('/hospital-course-clarify', authMiddleware, async (req, res) => {
|
||||||
const { currentDraft, notes } = req.body;
|
const { currentDraft, notes } = req.body;
|
||||||
|
|
||||||
const result = await callAI([
|
const result = await callAI([
|
||||||
{ role: 'system', content: PROMPTS.askClarification },
|
{ role: 'system', content: PROMPTS.askClarification + INJECTION_GUARD },
|
||||||
{ role: 'user', content: `Current draft:\n${currentDraft}\n\nSource notes:\n${JSON.stringify(notes)}` }
|
{ role: 'user', content: `Current draft:\n` + wrapUserText('draft', currentDraft || '') + `\n\nSource notes:\n` + wrapUserText('notes', JSON.stringify(notes || [])) }
|
||||||
], { model: req.body.model });
|
], { model: req.body.model });
|
||||||
|
|
||||||
res.json({ success: true, questions: result.content, model: result.model });
|
res.json({ success: true, questions: result.content, model: result.model });
|
||||||
|
|
@ -123,15 +118,15 @@ router.post('/hospital-course-update', authMiddleware, async (req, res) => {
|
||||||
const { currentCourse, updates, model, instructions } = req.body;
|
const { currentCourse, updates, model, instructions } = req.body;
|
||||||
if (!currentCourse) return res.status(400).json({ error: 'No current course' });
|
if (!currentCourse) return res.status(400).json({ error: 'No current course' });
|
||||||
|
|
||||||
let userMsg = `CURRENT HOSPITAL COURSE:\n${currentCourse}\n\n`;
|
let userMsg = `CURRENT HOSPITAL COURSE:\n` + wrapUserText('course', currentCourse) + `\n\n`;
|
||||||
if (updates) userMsg += `NEW UPDATES TO ADD:\n${updates}\n\n`;
|
if (updates) userMsg += `NEW UPDATES TO ADD:\n` + wrapUserText('updates', updates) + `\n\n`;
|
||||||
if (instructions) userMsg += `INSTRUCTIONS:\n${instructions}`;
|
if (instructions) userMsg += `INSTRUCTIONS:\n` + wrapUserText('instructions', instructions);
|
||||||
|
|
||||||
const result = await callAI([
|
const result = await callAI([
|
||||||
{ role: 'system', content: `You are updating a hospital course document with new information.
|
{ role: 'system', content: `You are updating a hospital course document with new information.
|
||||||
Add the new information in the appropriate place. Maintain the same format and style.
|
Add the new information in the appropriate place. Maintain the same format and style.
|
||||||
If adding discharge day information, add it at the end.
|
If adding discharge day information, add it at the end.
|
||||||
${PROMPTS.refine.split('\n').slice(0, -1).join('\n')}` },
|
${PROMPTS.refine.split('\n').slice(0, -1).join('\n')}` + INJECTION_GUARD },
|
||||||
{ role: 'user', content: userMsg }
|
{ role: 'user', content: userMsg }
|
||||||
], { model, maxTokens: 6000 });
|
], { model, maxTokens: 6000 });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ const PROMPTS = require('../utils/prompts');
|
||||||
const { authMiddleware } = require('../middleware/auth');
|
const { authMiddleware } = require('../middleware/auth');
|
||||||
const db = require('../db/database');
|
const db = require('../db/database');
|
||||||
var logger = require('../utils/logger');
|
var logger = require('../utils/logger');
|
||||||
|
var { wrapUserText, INJECTION_GUARD } = require('../utils/promptSafe');
|
||||||
|
|
||||||
// Get all milestones for client (authenticated users)
|
// Get all milestones for client (authenticated users)
|
||||||
router.get('/milestones-data', authMiddleware, async (req, res) => {
|
router.get('/milestones-data', authMiddleware, async (req, res) => {
|
||||||
|
|
@ -59,8 +60,8 @@ router.post('/generate-milestone-narrative', authMiddleware, async (req, res) =>
|
||||||
const prompt = (format === 'list') ? PROMPTS.milestoneList : PROMPTS.milestoneNarrative;
|
const prompt = (format === 'list') ? PROMPTS.milestoneList : PROMPTS.milestoneNarrative;
|
||||||
|
|
||||||
const result = await callAI([
|
const result = await callAI([
|
||||||
{ role: 'system', content: prompt },
|
{ role: 'system', content: prompt + INJECTION_GUARD },
|
||||||
{ role: 'user', content: `Patient: ${patientAge || 'Unknown'}, ${patientGender || 'Unknown'}\nAge Group: ${ageGroup}\n\n${milestoneText}\n\nAssessed: ${achieved.length + notAchieved.length} | Achieved: ${achieved.length} | Not achieved: ${notAchieved.length} | Not assessed (OMIT): ${notAssessed.length}` }
|
{ role: 'user', content: `Patient: ${patientAge || 'Unknown'}, ${patientGender || 'Unknown'}\nAge Group: ${ageGroup}\n\n` + wrapUserText('milestones', milestoneText) + `\n\nAssessed: ${achieved.length + notAchieved.length} | Achieved: ${achieved.length} | Not achieved: ${notAchieved.length} | Not assessed (OMIT): ${notAssessed.length}` }
|
||||||
], { model });
|
], { model });
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
|
|
@ -82,8 +83,8 @@ router.post('/generate-milestone-summary', authMiddleware, async (req, res) => {
|
||||||
if (!narrative) return res.status(400).json({ error: 'No narrative' });
|
if (!narrative) return res.status(400).json({ error: 'No narrative' });
|
||||||
|
|
||||||
const result = await callAI([
|
const result = await callAI([
|
||||||
{ role: 'system', content: PROMPTS.milestoneSummary },
|
{ role: 'system', content: PROMPTS.milestoneSummary + INJECTION_GUARD },
|
||||||
{ role: 'user', content: `Patient: ${patientAge || 'Unknown'}, ${patientGender || 'Unknown'}\nAge Group: ${ageGroup}\n\nNARRATIVE:\n${narrative}` }
|
{ role: 'user', content: `Patient: ${patientAge || 'Unknown'}, ${patientGender || 'Unknown'}\nAge Group: ${ageGroup}\n\nNARRATIVE:\n` + wrapUserText('narrative', narrative) }
|
||||||
], { model, maxTokens: 500 });
|
], { model, maxTokens: 500 });
|
||||||
|
|
||||||
res.json({ success: true, summary: result.content, model: result.model });
|
res.json({ success: true, summary: result.content, model: result.model });
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ var { callAI } = require('../utils/ai');
|
||||||
var PROMPTS = require('../utils/prompts');
|
var PROMPTS = require('../utils/prompts');
|
||||||
var { authMiddleware } = require('../middleware/auth');
|
var { authMiddleware } = require('../middleware/auth');
|
||||||
var logger = require('../utils/logger');
|
var logger = require('../utils/logger');
|
||||||
|
var { wrapUserText, INJECTION_GUARD } = require('../utils/promptSafe');
|
||||||
|
|
||||||
// ── POST generate sick visit note ────────────────────────────────────────
|
// ── POST generate sick visit note ────────────────────────────────────────
|
||||||
router.post('/sick-visit/note', authMiddleware, async function(req, res) {
|
router.post('/sick-visit/note', authMiddleware, async function(req, res) {
|
||||||
|
|
@ -28,32 +29,23 @@ router.post('/sick-visit/note', authMiddleware, async function(req, res) {
|
||||||
// Assemble context
|
// Assemble context
|
||||||
var context = 'SICK VISIT\n';
|
var context = 'SICK VISIT\n';
|
||||||
context += 'Patient: ' + (patientAge || 'Unknown age') + ', ' + (patientGender || 'Unknown gender') + '\n';
|
context += 'Patient: ' + (patientAge || 'Unknown age') + ', ' + (patientGender || 'Unknown gender') + '\n';
|
||||||
context += 'Chief Complaint: ' + chiefComplaint + '\n\n';
|
context += 'Chief Complaint: ' + wrapUserText('chief_complaint', chiefComplaint) + '\n\n';
|
||||||
|
|
||||||
if (transcript) {
|
if (transcript) {
|
||||||
context += 'ENCOUNTER TRANSCRIPT/DICTATION:\n' + transcript + '\n\n';
|
context += 'ENCOUNTER TRANSCRIPT/DICTATION:\n' + wrapUserText('transcript', transcript) + '\n\n';
|
||||||
} else if (dictation) {
|
} else if (dictation) {
|
||||||
context += 'PHYSICIAN DICTATION:\n' + dictation + '\n\n';
|
context += 'PHYSICIAN DICTATION:\n' + wrapUserText('dictation', dictation) + '\n\n';
|
||||||
}
|
}
|
||||||
|
if (ros) context += wrapUserText('ros', ros) + '\n\n';
|
||||||
if (ros) {
|
if (physicalExam) context += wrapUserText('physical_exam', physicalExam) + '\n\n';
|
||||||
context += ros + '\n\n';
|
if (diagnoses) context += wrapUserText('diagnoses', diagnoses) + '\n\n';
|
||||||
}
|
|
||||||
|
|
||||||
if (physicalExam) {
|
|
||||||
context += physicalExam + '\n\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (diagnoses) {
|
|
||||||
context += diagnoses + '\n\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (physicianMemories) {
|
if (physicianMemories) {
|
||||||
context += '[STYLE HINTS (low priority — only apply if relevant to the current note, never copy content from these examples)]\n' + physicianMemories + '\n[END STYLE HINTS]\n\n';
|
context += '[STYLE HINTS (low priority — only apply if relevant to the current note, never copy content from these examples)]\n'
|
||||||
|
+ wrapUserText('style_hints', physicianMemories) + '\n[END STYLE HINTS]\n\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await callAI([
|
var result = await callAI([
|
||||||
{ role: 'system', content: PROMPTS.sickVisitNote },
|
{ role: 'system', content: PROMPTS.sickVisitNote + INJECTION_GUARD },
|
||||||
{ role: 'user', content: context }
|
{ role: 'user', content: context }
|
||||||
], { model });
|
], { model });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ var { callAI } = require('../utils/ai');
|
||||||
var PROMPTS = require('../utils/prompts');
|
var PROMPTS = require('../utils/prompts');
|
||||||
var { authMiddleware } = require('../middleware/auth');
|
var { authMiddleware } = require('../middleware/auth');
|
||||||
var logger = require('../utils/logger');
|
var logger = require('../utils/logger');
|
||||||
|
var { wrapUserText, INJECTION_GUARD } = require('../utils/promptSafe');
|
||||||
|
|
||||||
// Load growth reference and BMI classification data
|
// Load growth reference and BMI classification data
|
||||||
var scheduleData;
|
var scheduleData;
|
||||||
|
|
@ -112,8 +113,8 @@ router.post('/well-visit/shadess', authMiddleware, async function(req, res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = await callAI([
|
var result = await callAI([
|
||||||
{ role: 'system', content: PROMPTS.shadessAssessment },
|
{ role: 'system', content: PROMPTS.shadessAssessment + INJECTION_GUARD },
|
||||||
{ role: 'user', content: inputText }
|
{ role: 'user', content: wrapUserText('sshadess_answers', inputText) }
|
||||||
], { model });
|
], { model });
|
||||||
|
|
||||||
var dur = Date.now() - start;
|
var dur = Date.now() - start;
|
||||||
|
|
@ -155,40 +156,20 @@ router.post('/well-visit/note', authMiddleware, async function(req, res) {
|
||||||
var context = 'WELL CHILD VISIT\n';
|
var context = 'WELL CHILD VISIT\n';
|
||||||
context += 'Patient: ' + (patientAge || visitAge) + ', ' + (patientGender || 'Unknown') + '\n\n';
|
context += 'Patient: ' + (patientAge || visitAge) + ', ' + (patientGender || 'Unknown') + '\n\n';
|
||||||
|
|
||||||
if (vitals) {
|
if (vitals) context += 'VITAL SIGNS:\n' + wrapUserText('vitals', vitals) + '\n\n';
|
||||||
context += 'VITAL SIGNS:\n' + vitals + '\n\n';
|
if (measurements) context += 'MEASUREMENTS/GROWTH:\n' + wrapUserText('measurements', measurements) + '\n\n';
|
||||||
}
|
if (parentConcerns) context += 'PARENT/PATIENT CONCERNS:\n' + wrapUserText('concerns', parentConcerns) + '\n\n';
|
||||||
if (measurements) {
|
if (transcript) context += 'ENCOUNTER TRANSCRIPT/DICTATION:\n' + wrapUserText('transcript', transcript) + '\n\n';
|
||||||
context += 'MEASUREMENTS/GROWTH:\n' + measurements + '\n\n';
|
else if (dictation) context += 'PHYSICIAN DICTATION:\n' + wrapUserText('dictation', dictation) + '\n\n';
|
||||||
}
|
if (screenings) context += 'SCREENINGS COMPLETED:\n' + wrapUserText('screenings', screenings) + '\n\n';
|
||||||
if (parentConcerns) {
|
if (vaccines) context += 'IMMUNIZATIONS TODAY:\n' + wrapUserText('vaccines', vaccines) + '\n\n';
|
||||||
context += 'PARENT/PATIENT CONCERNS:\n' + parentConcerns + '\n\n';
|
if (shadessAssessment) context += 'SSHADESS PSYCHOSOCIAL ASSESSMENT:\n' + wrapUserText('sshadess', shadessAssessment) + '\n\n';
|
||||||
}
|
if (ros) context += wrapUserText('ros', ros) + '\n\n';
|
||||||
if (transcript) {
|
if (physicalExam) context += wrapUserText('physical_exam', physicalExam) + '\n\n';
|
||||||
context += 'ENCOUNTER TRANSCRIPT/DICTATION:\n' + transcript + '\n\n';
|
if (diagnoses) context += wrapUserText('diagnoses', diagnoses) + '\n\n';
|
||||||
} else if (dictation) {
|
|
||||||
context += 'PHYSICIAN DICTATION:\n' + dictation + '\n\n';
|
|
||||||
}
|
|
||||||
if (screenings) {
|
|
||||||
context += 'SCREENINGS COMPLETED:\n' + screenings + '\n\n';
|
|
||||||
}
|
|
||||||
if (vaccines) {
|
|
||||||
context += 'IMMUNIZATIONS TODAY:\n' + vaccines + '\n\n';
|
|
||||||
}
|
|
||||||
if (shadessAssessment) {
|
|
||||||
context += 'SSHADESS PSYCHOSOCIAL ASSESSMENT:\n' + shadessAssessment + '\n\n';
|
|
||||||
}
|
|
||||||
if (ros) {
|
|
||||||
context += ros + '\n\n';
|
|
||||||
}
|
|
||||||
if (physicalExam) {
|
|
||||||
context += physicalExam + '\n\n';
|
|
||||||
}
|
|
||||||
if (diagnoses) {
|
|
||||||
context += diagnoses + '\n\n';
|
|
||||||
}
|
|
||||||
if (physicianMemories) {
|
if (physicianMemories) {
|
||||||
context += '[STYLE HINTS (low priority — only apply if relevant to the current note, never copy content from these examples)]\n' + physicianMemories + '\n[END STYLE HINTS]\n\n';
|
context += '[STYLE HINTS (low priority — only apply if relevant to the current note, never copy content from these examples)]\n'
|
||||||
|
+ wrapUserText('style_hints', physicianMemories) + '\n[END STYLE HINTS]\n\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add growth reference and feeding guidance for this age
|
// Add growth reference and feeding guidance for this age
|
||||||
|
|
@ -214,7 +195,7 @@ router.post('/well-visit/note', authMiddleware, async function(req, res) {
|
||||||
var prompt = (noteStyle === 'short') ? PROMPTS.wellVisitShort : PROMPTS.wellVisitNote;
|
var prompt = (noteStyle === 'short') ? PROMPTS.wellVisitShort : PROMPTS.wellVisitNote;
|
||||||
|
|
||||||
var result = await callAI([
|
var result = await callAI([
|
||||||
{ role: 'system', content: prompt },
|
{ role: 'system', content: prompt + INJECTION_GUARD },
|
||||||
{ role: 'user', content: context }
|
{ role: 'user', content: context }
|
||||||
], { model });
|
], { model });
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue