Repository navigation
Description
TanStack AI version
@tanstack/ai 0.71.0, @tanstack/ai-ollama 0.12.2 (ollama 0.6.4)
Framework/Library version
Node.js 22, chat() on the server, no framework
Describe the bug and the steps to reproduce it
When Ollama stops at the token limit (options.num_predict), its last stream line has done: true and
done_reason: "length". The streamed chat() path still ends with RUN_FINISHED and finishReason: "stop", so a
cut-off answer looks complete.
The adapter sets the finish from whether tool calls were emitted and never reads done_reason
(packages/ai-ollama/src/adapters/text.ts#L440).
structuredOutput() already checks done_reason === 'length' (L263, from #1548), so only the streamed path is
affected.
Expected: finishReason: "length", as the Chat Completions adapter reports for finish_reason: "length".
Steps: save the script below as repro.mjs, then
npm init -y && npm pkg set type=module
npm install @tanstack/ai@0.71.0 @tanstack/ai-ollama@0.12.2
node repro.mjsOutput:
RUN_FINISHED stop
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
No Ollama server is needed: a custom fetch returns the NDJSON stream.
import { chat } from '@tanstack/ai';
import { createOllamaChat } from '@tanstack/ai-ollama';
// The last line is what Ollama sends when options.num_predict cuts the answer off.
const lines = [
{ model: 'qwen3.5:0.8b', created_at: '2026-10-21T09:00:00Z', message: { role: 'assistant', content: 'Saturn has more than' }, done: false },
{ model: 'qwen3.5:0.8b', created_at: '2026-10-21T09:00:01Z', message: { role: 'assistant', content: '' },
done: true, done_reason: 'length', prompt_eval_count: 14, eval_count: 5 },
];
globalThis.fetch = async () => new Response(lines.map(line => JSON.stringify(line) + '\n').join(''),
{ headers: { 'content-type': 'application/x-ndjson' } });
for await (const event of chat({
adapter: createOllamaChat('qwen3.5:0.8b'),
messages: [{ role: 'user', content: 'How many moons does Saturn have?' }],
modelOptions: { options: { num_predict: 5 } },
debug: false,
})) {
if (event.type === 'RUN_FINISHED') console.log('RUN_FINISHED', event.metadata?.tanstack?.finishReason);
if (event.type === 'RUN_ERROR') console.log('RUN_ERROR', event.code);
}Terms & Code of Conduct
- I agree to follow this project's Code of Conduct
- I understand that if my bug cannot be reliably reproduced in a debuggable environment, it will probably not be
fixed and this issue may even be closed.
Activity
feat(shims): tanstack-ai (#75)