diff --git a/docs/configuration.md b/docs/configuration.md index 91c682c6..e309bc07 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -57,6 +57,11 @@ keys): | `LITELLM_TTS_MODEL`, `LITELLM_TTS_VOICE` | LiteLLM-routed TTS model and default voice. | | `LITELLM_TTS_VOICES` | The voices of `LITELLM_TTS_MODEL` only; other models use the built-in table in `src/utils/ttsProvider.js`. The roster itself is `tts.roster` in `app_settings`. | +### Starter questions +| Setting | Meaning | +|---|---| +| `clinical_assistant.prompt_model` | The model that writes the starter-question pool. Use a **non-reasoning** model (`openrouter-gpt-4.1-mini` in production): a reasoning model spends the whole completion budget thinking about a 20-question JSON list and returns nothing. Falls back to `clinical_assistant.chat_model`, then `models.default`. | + ### Embeddings | Variable | Purpose | diff --git a/src/utils/clinicalPromptPool.js b/src/utils/clinicalPromptPool.js index dcb468e9..63f2bfb8 100644 --- a/src/utils/clinicalPromptPool.js +++ b/src/utils/clinicalPromptPool.js @@ -340,8 +340,11 @@ function createClinicalPromptPool(opts) { if (!snippets.length) continue; var categoryExamples = []; var batches = Math.max(1, Math.min(6, Math.ceil(item.quota / 18))); + var retries = 0; for (var i = 0; i < batches && categoryExamples.length < item.quota; i++) { - var batchSnippets = rotateExamples(snippets, i * 18).slice(0, 18); + // A retry gets different snippets: the same ones produced the same + // runaway reasoning and the same empty reply, three times in a row. + var batchSnippets = rotateExamples(snippets, i * 18 + retries * 7).slice(0, 18); var sourceText = batchSnippets.map(function(s, idx) { return '[' + (idx + 1) + '] ' + s.title + (s.page ? ', page ' + s.page : '') + '\n' + clip(s.excerpt, 700); }).join('\n\n'); @@ -364,8 +367,9 @@ function createClinicalPromptPool(opts) { // The model answers a JSON task with an empty message now and then — // two batches in five came back with nothing. One more try with the // same snippets is cheap and usually enough. - console.warn('[clinical-assistant] prompt pool ' + item.category + ' batch ' + (i + 1) + ': nothing parseable in ' + String(ai.content || '').length + ' chars (finish ' + (ai.finishReason || '?') + '); retrying once'); - i--; batches++; if (batches > 12) break; + console.warn('[clinical-assistant] prompt pool ' + item.category + ' batch ' + (i + 1) + ': nothing parseable in ' + String(ai.content || '').length + ' chars (finish ' + (ai.finishReason || '?') + '); retrying with other snippets'); + if (++retries > 3) break; + i--; continue; } else if (parsed.truncated) console.warn('[clinical-assistant] prompt pool ' + item.category + ' batch ' + (i + 1) + ': reply was cut off; ' + offered + ' questions salvaged');