Bonsai-Chat-WebGPU / src /lib /agent-parsers.test.ts
Valeriy Selitskiy
Release v1.2.2 interactive chat workspace
21ad36a
Raw
History Blame Contribute Delete
2.63 kB
import { describe, expect, it } from 'vitest';
import { parseThoughtStream } from './think-parser';
import { parseToolCalls, renderToolResponse } from './tool-protocol';
describe('parseThoughtStream', () => {
it('separates complete reasoning from visible content', () => {
expect(parseThoughtStream('<think>check evidence</think>final answer')).toEqual({
content: 'final answer',
reasoning: 'check evidence',
isThinking: false,
hasReasoning: true,
});
});
it('handles a closing-only marker emitted after a template-opened thought', () => {
expect(parseThoughtStream('private chain\n</think>\npublic answer').content).toBe('public answer');
});
it('buffers a partial opening marker', () => {
expect(parseThoughtStream('answer<thi').content).toBe('answer');
});
});
describe('parseToolCalls', () => {
it('extracts multiple strict tool envelopes', () => {
const result = parseToolCalls(
'note<tool_call>{"name":"memory","arguments":{"key":"x"}}</tool_call>' +
'<tool_call>{"name":"js_eval","arguments":{"source":"return 2"}}</tool_call>',
);
expect(result.content).toBe('note');
expect(result.calls.map((call) => call.name)).toEqual(['memory', 'js_eval']);
expect(result.errors).toEqual([]);
});
it('reports incomplete streams without executing them', () => {
expect(parseToolCalls('<tool_call>{"name":"memory"').incomplete).toBe(true);
});
it('parses the Qwen3.5 function and parameter format from the 27B chat template', () => {
const result = parseToolCalls(`before
<tool_call>
<function=html_artifact>
<parameter=html>
<!doctype html><html><body><h1>Tool proof</h1></body></html>
</parameter>
<parameter=title>
Tool proof
</parameter>
</function>
</tool_call>`);
expect(result.content).toBe('before');
expect(result.errors).toEqual([]);
expect(result.calls).toEqual([expect.objectContaining({
name: 'html_artifact',
arguments: {
html: '<!doctype html><html><body><h1>Tool proof</h1></body></html>',
title: 'Tool proof',
},
})]);
});
it('rejects malformed or duplicate Qwen3.5 parameters', () => {
const malformed = parseToolCalls(
'<tool_call><function=memory><parameter=action>get</parameter><parameter=action>list</parameter></function></tool_call>',
);
expect(malformed.calls).toEqual([]);
expect(malformed.errors).toEqual(['function tool call repeats parameter action']);
});
it('wraps deterministic tool responses', () => {
expect(renderToolResponse({ ok: true })).toBe('<tool_response>\n{"ok":true}\n</tool_response>');
});
});