Fix clinical prompt pool fallback seeding
All checks were successful
Forgejo Android APK / Build signed APK (push) Successful in 2m14s

This commit is contained in:
Daniel 2026-05-22 16:53:53 +02:00
parent c7921ab822
commit d02b9e2771
4 changed files with 6 additions and 75 deletions

View file

@ -9,8 +9,8 @@ android {
targetSdkVersion rootProject.ext.targetSdkVersion
// Version values below are overwritten by scripts/release.sh from
// the root package.json. versionCode auto-increments per release.
versionCode 714009
versionName "7.14.9"
versionCode 714010
versionName "7.14.10"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

View file

@ -1,6 +1,6 @@
{
"name": "pediatric-ai-scribe",
"version": "7.14.9",
"version": "7.14.10",
"description": "AI-powered pediatric clinical documentation platform",
"main": "server.js",
"scripts": {

View file

@ -322,11 +322,7 @@ function createClinicalPromptPool(opts) {
}
generated = normalizeGeneratedExamples(generated.concat(categoryExamples));
}
generated = normalizeGeneratedExamples(generated.concat(taxonomyFallbackExamples(taxonomy, generated.length)));
if (generated.length < target) {
generated = normalizeGeneratedExamples(generated.concat(taxonomySupplementExamples(taxonomy, target - generated.length)));
}
if (generated.length < 8) return fallbackIndexedExamples();
if (generated.length < 8) return [];
return generated.slice(0, target);
}
@ -475,73 +471,6 @@ function createClinicalPromptPool(opts) {
});
}
function taxonomyFallbackExamples(taxonomy, existingCount) {
var templates = [
'How should I evaluate a {age} with {seed}, focusing on {focus}?',
'What red flags change disposition for a {age} with {seed} and {focus}?',
'What pediatric differential fits {seed} in a {age} with {focus}?',
'What initial management is recommended for a {age} with {seed} and {focus}?',
'When should a {age} with {seed} be admitted because of {focus}?',
'What return precautions fit {seed} in a {age} with {focus}?'
];
var focusAreas = [
'severity assessment',
'diagnostic workup',
'age-specific risks',
'medication dosing',
'fluid management',
'family safety netting',
'follow-up timing',
'comorbid conditions',
'initial stabilization',
'consultation thresholds'
];
var examples = [];
taxonomy.forEach(function(item) {
var needed = Math.max(0, item.quota - Math.floor(existingCount / taxonomy.length));
var itemExamples = [];
var seen = new Set();
for (var i = 0; i < needed * 3 && itemExamples.length < needed; i++) {
var seed = item.seeds[i % item.seeds.length];
var seedPhrase = seed.split(/\s+/).slice(0, 5).join(' ');
var ageBand = item.ageBands[i % item.ageBands.length];
var template = templates[i % templates.length];
var focus = focusAreas[Math.floor(i / (templates.length * item.seeds.length)) % focusAreas.length];
var example = {
label: cleanExampleLabel(seedPhrase.split(/\s+/).slice(0, 4).join(' ')),
prompt: template.replace('{age}', ageBand.replace('_', ' ') + ' patient').replace('{seed}', seedPhrase).replace('{focus}', focus),
category: item.category,
age_band: ageBand,
intent: ['diagnosis', 'red_flags', 'differential', 'management', 'admission', 'counseling'][i % 6]
};
var key = example.prompt.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim();
if (seen.has(key)) continue;
seen.add(key);
itemExamples.push(example);
}
examples = examples.concat(itemExamples);
});
return examples;
}
function taxonomySupplementExamples(taxonomy, needed) {
var examples = [];
for (var i = 0; i < needed * 2 && examples.length < needed; i++) {
var item = taxonomy[i % taxonomy.length];
var seedPhrase = item.seeds[i % item.seeds.length].split(/\s+/).slice(0, 5).join(' ');
var ageBand = item.ageBands[i % item.ageBands.length];
var categoryLabel = item.category.replace(/_/g, ' ');
examples.push({
label: cleanExampleLabel(categoryLabel + ' review'),
prompt: 'For pediatric ' + categoryLabel + ' cases, how should I handle a ' + ageBand.replace('_', ' ') + ' patient with ' + seedPhrase + '?',
category: item.category,
age_band: ageBand,
intent: ['diagnosis', 'management', 'red_flags', 'differential', 'counseling', 'dosing', 'admission', 'review'][i % 8]
});
}
return examples;
}
function sanitizeCategory(category, defaultTaxonomy) {
category = String(category || '').trim().toLowerCase().replace(/[\s/-]+/g, '_');
category = CATEGORY_ALIASES[category] || CATEGORY_ALIASES[category.replace(/_/g, ' ')] || category;

View file

@ -25,6 +25,8 @@ test('clinical assistant starter prompts are Redis or indexed-source backed', ()
assert.match(pool, /age_band: ageBand/);
assert.match(pool, /function hasPediatricSignal\(prompt, item\)/);
assert.match(pool, /var examples = await fallbackIndexedExamples\(\)/);
assert.doesNotMatch(pool, /taxonomyFallbackExamples|taxonomySupplementExamples/);
assert.doesNotMatch(pool, /return fallbackIndexedExamples\(\)/);
});
test('clinical assistant prompt forbids relabeling other sources as named sources', () => {