pediatric-ai-scribe-v3/src/utils/patientTakehome.js

43 lines
2.1 KiB
JavaScript

// Patient Take Home — a plain-language, citation-free summary of the latest
// clinical answer, generated on explicit user request only. This is a
// separate synchronous model call; it never touches conversation history,
// budgets, sources, or saved chats.
const { PATIENT_TAKEHOME_BEHAVIOR } = require('./clinicalPrompts');
const { assistantGenerationOptions } = require('./clinicalAnswer');
const MAX_ANSWER_CHARS = 20000;
const MAX_RESULT_CHARS = 12000;
function stripCitationTokens(text) {
// Defensive scrub: the prompt forbids citations, but never trust the model.
return String(text || '')
.replace(/\[(?:[0-9]+(?:\s*,\s*[0-9]+)*)\]|\[[0-9]+(?:\s*,\s*[0-9]+)*\]/g, '')
.replace(/\((?:source|ref)[^)]*\)/gi, '')
.replace(/\n\s*(#{1,3}\s*)?(sources?|references)\s*:?\s*$/im, '')
.replace(/ {2,}/g, ' ')
.trim();
}
async function generatePatientTakehome(opts) {
var answer = String(opts.answer || '').trim();
if (!answer) { var e = new Error('No answer to summarize'); e.statusCode = 400; throw e; }
if (answer.length > MAX_ANSWER_CHARS) { e = new Error('Answer too long for a take-home sheet'); e.statusCode = 413; throw e; }
var behavior = String(opts.behavior || '').trim() || PATIENT_TAKEHOME_BEHAVIOR;
var messages = [
{ role: 'system', content: behavior },
{ role: 'user', content: 'Clinical answer:\n' + answer + '\n\nWrite the patient take-home sheet now.' }
];
var ai;
try {
ai = await opts.callAI(messages, assistantGenerationOptions({ model: opts.model || undefined, temperature: 0.15, maxTokens: 1800 }));
} catch (err) {
err = err || new Error('Take-home generation failed');
if (!err.statusCode && !err.response) err.statusCode = 502;
throw err;
}
var text = stripCitationTokens(ai && ai.content || '').slice(0, MAX_RESULT_CHARS);
if (!text) { e = new Error('The model returned an empty take-home sheet'); e.statusCode = 502; throw e; }
return { text: text, model: ai.model || null, provider: ai.provider || null };
}
module.exports = { MAX_ANSWER_CHARS, MAX_RESULT_CHARS, generatePatientTakehome, stripCitationTokens };