models: add synthetic provider
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
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[] = [];
|
||||
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[] = [];
|
||||
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']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user