Spaces:
Running
Running
File size: 2,631 Bytes
0ed8124 21ad36a 0ed8124 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 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>');
});
});
|