Summary
Same defect as the three sibling adapters (llm-anthropic, llm-openai, llm-gemini, filed separately), present here too:
const contextLimit = getContextLimit(this.provider, this.model);
const { evidence: trimmedEvidence, trim } = trimEvidenceForContext(evidence, contextLimit);
const systemPrompt = buildSystemPrompt();
const userPrompt = buildUserPrompt(trimmedEvidence, question); // model sees trimmedEvidence
let payload = await callOllama({
...
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: userPrompt },
],
...
});
...
const grounding = validateEvidenceGrounding(evidence, evidenceRefs);
// ^^^^^^^^ should be trimmedEvidence
Why this matters
userPrompt is built from trimmedEvidence, which trimEvidenceForContext (packages/llm/llm-core/src/context.ts) can shrink by removing evidence items, what_changed entries, or similar-incident entries in order to fit the (often much smaller) context windows typical of locally-hosted Ollama models — this is actually the adapter most likely to trigger trimming in practice given PROVIDER_DEFAULT_CONTEXT_LIMITS.ollama = 8192 in packages/llm/llm-core/src/token-usage.ts. Despite that, validateEvidenceGrounding is called with the full, untrimmed evidence.
Since validateEvidenceGrounding (packages/llm/llm-core/src/grounding.ts) only checks evidence_refs for id membership in evidence.evidence, and trimmedEvidence.evidence ⊆ evidence.evidence, an evidence_refs id corresponding to an item that was trimmed out (and thus never appeared in userPrompt) can still be classified "grounded". Given local models are already the most failure-prone target for this adapter's forced-JSON retry path, this is exactly the adapter where an accurate hallucination signal matters most, and it's the one most likely to actually hit the trimming path in real usage.
Suggested fix
const grounding = validateEvidenceGrounding(trimmedEvidence, evidenceRefs);
File:
packages/llm/llm-ollama/src/ollama-adapter.ts
Summary
Same defect as the three sibling adapters (
llm-anthropic,llm-openai,llm-gemini, filed separately), present here too:Why this matters
userPromptis built fromtrimmedEvidence, whichtrimEvidenceForContext(packages/llm/llm-core/src/context.ts) can shrink by removing evidence items,what_changedentries, or similar-incident entries in order to fit the (often much smaller) context windows typical of locally-hosted Ollama models — this is actually the adapter most likely to trigger trimming in practice givenPROVIDER_DEFAULT_CONTEXT_LIMITS.ollama = 8192inpackages/llm/llm-core/src/token-usage.ts. Despite that,validateEvidenceGroundingis called with the full, untrimmedevidence.Since
validateEvidenceGrounding(packages/llm/llm-core/src/grounding.ts) only checksevidence_refsfor id membership inevidence.evidence, andtrimmedEvidence.evidence ⊆ evidence.evidence, anevidence_refsid corresponding to an item that was trimmed out (and thus never appeared inuserPrompt) can still be classified "grounded". Given local models are already the most failure-prone target for this adapter's forced-JSON retry path, this is exactly the adapter where an accurate hallucination signal matters most, and it's the one most likely to actually hit the trimming path in real usage.Suggested fix
File:
packages/llm/llm-ollama/src/ollama-adapter.ts