const { test } = require('node:test'); const assert = require('node:assert/strict'); const path = require('node:path'); const { pathToFileURL } = require('node:url'); async function imagesModule() { return import(pathToFileURL(path.join(__dirname, '..', 'public/js/assistant/images.js')).href); } test('assistant image intent does not intercept table retrieval requests', async () => { const { isImageRequest } = await imagesModule(); assert.equal(isImageRequest('can you show me the table?'), false); assert.equal(isImageRequest('show me Table 13.1'), false); }); test('assistant image intent still handles explicit visual requests', async () => { const { isImageRequest } = await imagesModule(); assert.equal(isImageRequest('show me the diagram'), true); assert.equal(isImageRequest('create an infographic for asthma'), true); }); // A run of image turns used to make every acknowledgement produce another image: // the model saw its own "I'll generate an educational image…" in the history and // replayed it verbatim for "Окей" and "Nice". The fix is not a word list in the // route — the model already has the tool, the prompt and the conversation, so the // policy lives where the model reads it. test('the system prompt tells the model to decide, in the user\'s own language', () => { const { DEFAULT_BEHAVIOR } = require('../src/utils/clinicalPrompts'); assert.match(DEFAULT_BEHAVIOR, /in any language/i, 'acknowledgements are recognised by the model, not by a list'); assert.match(DEFAULT_BEHAVIOR, /ONLY when the user's latest message itself asks for a picture/); assert.match(DEFAULT_BEHAVIOR, /never repeat a previous turn's answer/); assert.match(DEFAULT_BEHAVIOR, /ask what they would like you to look up|asking what they would like you to look up/i); }); test('the tool description itself says when not to call it', () => { const { tools } = require('../src/utils/imageTool'); const description = tools[0].function.description; assert.match(description, /ONLY when the user's latest message itself asks for a picture/); assert.match(description, /is not a request for another one/); assert.match(description, /any other language/); }); test('no hand-maintained acknowledgement or language list is left in the route', () => { const fs = require('node:fs'); const src = fs.readFileSync(path.join(__dirname, '..', 'src/routes/clinicalAssistant.js'), 'utf8'); assert.doesNotMatch(src, /GREETING_RE/, 'greeting word list removed — the model decides'); assert.doesNotMatch(src, /IMAGE_NOUN_NON_LATIN|IMAGE_REPEAT_NON_LATIN/, 'no multilingual vocabulary lists'); assert.doesNotMatch(src, /suppressRepeatedImage/, 'no answer-inspection backstop'); // The one surviving pattern is the compatibility path for models that write // the prompt as text; it reads the USER's message only. const fallback = src.slice(src.indexOf('async function dispatchImageRequestFallback')); assert.match(fallback, /isExplicitImageRequest\(prepared\.message\)/, 'gated on the user, never on the answer'); });