Files
flynn/src/models/synthetic.test.ts
T
2026-02-15 23:14:21 -08:00

68 lines
2.4 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { SyntheticClient } from './synthetic.js';
import type { ChatRequest } from './types.js';
function makeRequest(text: string): ChatRequest {
return {
messages: [{ role: 'user', content: text }],
};
}
describe('SyntheticClient', () => {
it('echoes the last user message by default', async () => {
const client = new SyntheticClient({ model: 'echo' });
const res = await client.chat(makeRequest('hello'));
expect(res.content).toBe('hello');
expect(res.stopReason).toBe('end_turn');
expect(res.toolCalls).toBeUndefined();
expect(res.usage.inputTokens).toBeGreaterThan(0);
expect(res.usage.outputTokens).toBeGreaterThan(0);
});
it('supports fixed responses via model=fixed:<text>', async () => {
const client = new SyntheticClient({ model: 'fixed:ok' });
const res = await client.chat(makeRequest('ignored'));
expect(res.content).toBe('ok');
expect(res.stopReason).toBe('end_turn');
});
it('supports tool calls via @tool directive', async () => {
const client = new SyntheticClient({ model: 'echo' });
const res = await client.chat(makeRequest('@tool memory.read {"namespace":"global"}'));
expect(res.stopReason).toBe('tool_use');
expect(res.content).toBe('');
expect(res.toolCalls?.length).toBe(1);
expect(res.toolCalls?.[0]?.name).toBe('memory.read');
expect(res.toolCalls?.[0]?.args).toEqual({ namespace: 'global' });
});
it('streams content + done', async () => {
const client = new SyntheticClient({ model: 'fixed:stream-me' });
const events: string[] = [];
if (!client.chatStream) {
throw new Error('Expected streaming support');
}
for await (const ev of client.chatStream(makeRequest('x'))) {
events.push(ev.type);
}
expect(events).toEqual(['content', 'done']);
});
it('streams tool_use + done for @tool directives', async () => {
const client = new SyntheticClient({ model: 'echo' });
const types: string[] = [];
const toolNames: string[] = [];
if (!client.chatStream) {
throw new Error('Expected streaming support');
}
for await (const ev of client.chatStream(makeRequest('@tool file.read {"path":"README.md"}'))) {
types.push(ev.type);
if (ev.type === 'tool_use' && ev.toolCall) {
toolNames.push(ev.toolCall.name);
}
}
expect(types).toEqual(['tool_use', 'done']);
expect(toolNames).toEqual(['file.read']);
});
});