import { describe, expect, it, vi } from 'vitest'; const createMock = vi.fn(); vi.mock('openai', () => ({ default: vi.fn().mockImplementation(() => ({ chat: { completions: { create: createMock } }, })), })); import { LlmClient } from '../../../src/core/llm/LlmClient'; describe('LlmClient', () => { it('sends messages/options to the OpenAI-compatible endpoint and returns content + usage', async () => { createMock.mockResolvedValue({ choices: [{ message: { content: 'hello' } }], usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 }, }); const client = new LlmClient({ baseUrl: 'http://localhost:11434/v1', apiKey: 'key' }); const result = await client.chat([{ role: 'user', content: 'hi' }], { model: 'llama3', temperature: 0.7 }); expect(result).toEqual({ content: 'hello', usage: { promptTokens: 10, completionTokens: 5, totalTokens: 15 }, }); expect(createMock).toHaveBeenCalledWith({ model: 'llama3', temperature: 0.7, max_tokens: undefined, messages: [{ role: 'user', content: 'hi' }], }); }); it('throws when the response has no choices', async () => { createMock.mockResolvedValue({ choices: [] }); const client = new LlmClient({ baseUrl: 'http://localhost:11434/v1' }); await expect(client.chat([{ role: 'user', content: 'hi' }], { model: 'llama3' })).rejects.toThrow( /no choices/ ); }); });