Remove clinical assistant source lock
All checks were successful
Forgejo Android APK / Build signed APK (push) Successful in 1m54s

This commit is contained in:
Daniel 2026-08-27 21:33:58 +02:00
parent 018913a845
commit 604f6abb49
4 changed files with 4 additions and 36 deletions

View file

@ -8,7 +8,6 @@ services:
- .env
environment:
CLINICAL_ASSISTANT_MCP_URL: http://mcp:8000/mcp
CLINICAL_ASSISTANT_SOURCE_FILE_PATH: Medical Library/Pediatrics/Kliegman%20R.%20Nelson%20Textbook%20of%20Pediatrics%20%202-Volume%20Set%2022ed%202024.pdf
REDIS_URL: redis://ped-ai-redis:6379
LOKI_URL: http://monitoring-loki:3100
LITELLM_API_BASE: http://litellm:4000

View file

@ -28,7 +28,6 @@ var {
var {
normalizeMcpSearchResponse,
normalizeMcpMultimodalResponse,
filterSourcesByFilePath,
dedupeSources,
isVisualSourceQuery,
buildMultimodalSearchQuery,
@ -49,7 +48,6 @@ var MAX_SAVED_CHATS_PER_USER = 100;
var MAX_SAVED_CHAT_PAYLOAD = 250000;
var MAX_SAVED_CHAT_TITLE = 160;
var IMAGE_JOB_TTL_SECONDS = 15 * 60;
var SOURCE_LOCK_SEARCH_LIMIT = 50;
var imageJobs = new Map();
var promptPool = createClinicalPromptPool({
redisCache: redisCache,
@ -377,7 +375,6 @@ async function prepareAssistantChat(body) {
var contextChars = clampInt(await getSetting('clinical_assistant.context_chars', '1400'), 300, 4000, 1400);
var behavior = await getSetting('clinical_assistant.system_behavior', DEFAULT_BEHAVIOR) || DEFAULT_BEHAVIOR;
var includeContext = body.includeContext !== false;
var sourceFilePath = String(process.env.CLINICAL_ASSISTANT_SOURCE_FILE_PATH || '').trim();
if (GREETING_RE.test(message)) {
return { direct: {
@ -396,8 +393,7 @@ async function prepareAssistantChat(body) {
return message;
});
var searchResponse = await semanticSearch(searchQuery, {
// MCP has no source-path filter. Retrieve a larger candidate set, then enforce the lock locally.
limit: sourceFilePath ? SOURCE_LOCK_SEARCH_LIMIT : searchLimit,
limit: searchLimit,
includeContext: includeContext,
contextChars: contextChars
});
@ -406,10 +402,10 @@ async function prepareAssistantChat(body) {
console.warn('[clinical-assistant] multimodal search skipped:', e.message);
return null;
}) : null;
var rawTextResults = filterSourcesByFilePath(normalizeMcpSearchResponse(searchResponse), sourceFilePath);
var rawTextResults = normalizeMcpSearchResponse(searchResponse);
var rawMultimodalResults = await classifyAndRerankMultimodalResults(
message + ' ' + searchQuery,
filterSourcesByFilePath(normalizeMcpMultimodalResponse(multimodalResponse), sourceFilePath)
normalizeMcpMultimodalResponse(multimodalResponse)
);
var rawResults = rawTextResults.concat(rawMultimodalResults);
console.info('[clinical-assistant] retrieval counts:', {
@ -450,8 +446,7 @@ async function prepareAssistantChat(body) {
query: searchQuery,
rewritten: searchQuery !== message,
verifiedChunkCount: searchResponse.verified_chunk_count || searchResponse.verifiedChunkCount || 0,
droppedDocumentCount: searchResponse.dropped_document_count || searchResponse.droppedDocumentCount || 0,
sourceLocked: Boolean(sourceFilePath)
droppedDocumentCount: searchResponse.dropped_document_count || searchResponse.droppedDocumentCount || 0
}
};
}

View file

@ -89,18 +89,6 @@ function normalizeMcpMultimodalResponse(result) {
}).filter(function(r) { return r.page; });
}
function filterSourcesByFilePath(results, filePath) {
if (!filePath) return results;
var wanted = normalizeFilePath(filePath);
return results.filter(function(result) {
return normalizeFilePath(result && result.file_path) === wanted;
});
}
function normalizeFilePath(filePath) {
try { return decodeURIComponent(String(filePath || '')).replace(/^\/+/, ''); } catch (e) { return String(filePath || '').replace(/^\/+/, ''); }
}
function dedupeSources(results) {
var seen = new Map();
var out = [];
@ -283,7 +271,6 @@ function cleanSourceExcerpt(text) {
module.exports = {
normalizeMcpSearchResponse: normalizeMcpSearchResponse,
normalizeMcpMultimodalResponse: normalizeMcpMultimodalResponse,
filterSourcesByFilePath: filterSourcesByFilePath,
dedupeSources: dedupeSources,
isVisualSourceQuery: isVisualSourceQuery,
buildMultimodalSearchQuery: buildMultimodalSearchQuery,

View file

@ -1,13 +0,0 @@
const test = require('node:test');
const assert = require('node:assert/strict');
const { filterSourcesByFilePath } = require('../src/utils/clinicalRetrieval');
test('source lock keeps only the selected book regardless of URL encoding', () => {
const path = 'Medical Library/Pediatrics/Kliegman R. Nelson Textbook of Pediatrics 2-Volume Set 22ed 2024.pdf';
const sources = [
{ title: 'Nelson', file_path: 'Medical Library/Pediatrics/Kliegman%20R.%20Nelson%20Textbook%20of%20Pediatrics%20%202-Volume%20Set%2022ed%202024.pdf' },
{ title: 'Other book', file_path: 'Medical Library/Pediatrics/Other.pdf' }
];
assert.deepEqual(filterSourcesByFilePath(sources, path), [sources[0]]);
});