@cogitator-ai/test-utils 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +457 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
# @cogitator-ai/test-utils
|
|
2
|
+
|
|
3
|
+
Testing utilities for Cogitator to test your own agents, tools, workflows, and backends without calling real LLMs or databases.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add -D @cogitator-ai/test-utils
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
`@cogitator-ai/test-utils` gives you deterministic stand-ins and helpers to test your own agents and applications without network calls, paid API keys, or external databases. See [Test Utilities](https://cogitator.app/docs/testing/test-utils) on the website.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Mock LLM Backend** - Scriptable `MockLLMBackend` for deterministic `chat()` responses and `chatStream()` chunks with request recording and inspection
|
|
16
|
+
- **Mock Memory Adapter** - In-process `MockMemoryAdapter` recording method calls for threads and entries
|
|
17
|
+
- **Test Fixtures** - Preconfigured agents, messages, tool calls, tool results, JSON Schema tools, and run results
|
|
18
|
+
- **Stream Helpers** - Drain and collect stream content, chunks, and tool calls, or create mock byte streams
|
|
19
|
+
- **Async Utilities** - Polling (`waitFor`, `eventually`), delay, and promise timeout helpers
|
|
20
|
+
- **Backend Conformance Kit** - Test custom backends against wire protocols (OpenAI, Anthropic, Gemini, Ollama, Bedrock) with `startFakeProvider`
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### Testing with MockLLMBackend
|
|
27
|
+
|
|
28
|
+
A short, valid Vitest example using `MockLLMBackend`:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { describe, it, expect } from 'vitest';
|
|
32
|
+
import { MockLLMBackend, createToolCall } from '@cogitator-ai/test-utils';
|
|
33
|
+
|
|
34
|
+
describe('MockLLMBackend', () => {
|
|
35
|
+
it('returns scripted responses and inspects requests', async () => {
|
|
36
|
+
const backend = new MockLLMBackend();
|
|
37
|
+
backend.setResponses([
|
|
38
|
+
{ toolCalls: [createToolCall('get_weather', { city: 'Tokyo' })] },
|
|
39
|
+
{ content: 'The weather in Tokyo is sunny and 22°C.' },
|
|
40
|
+
]);
|
|
41
|
+
|
|
42
|
+
const first = await backend.chat({
|
|
43
|
+
model: 'test-model',
|
|
44
|
+
messages: [{ role: 'user', content: 'What is the weather in Tokyo?' }],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
expect(first.finishReason).toBe('tool_calls');
|
|
48
|
+
expect(first.toolCalls?.[0].name).toBe('get_weather');
|
|
49
|
+
|
|
50
|
+
const second = await backend.chat({
|
|
51
|
+
model: 'test-model',
|
|
52
|
+
messages: [
|
|
53
|
+
{ role: 'user', content: 'What is the weather in Tokyo?' },
|
|
54
|
+
{ role: 'assistant', content: 'Checking weather...' },
|
|
55
|
+
{
|
|
56
|
+
role: 'tool',
|
|
57
|
+
content: '{"temperature": 22}',
|
|
58
|
+
toolCallId: first.toolCalls![0].id,
|
|
59
|
+
name: 'get_weather',
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
expect(second.content).toBe('The weather in Tokyo is sunny and 22°C.');
|
|
65
|
+
expect(second.finishReason).toBe('stop');
|
|
66
|
+
|
|
67
|
+
expect(backend.getCallCount()).toBe(2);
|
|
68
|
+
expect(backend.wasCalledWith((req) => req.model === 'test-model')).toBe(true);
|
|
69
|
+
expect(backend.getLastCall()?.messages).toHaveLength(3);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Testing with MockMemoryAdapter
|
|
75
|
+
|
|
76
|
+
A short, valid Vitest example using `MockMemoryAdapter`:
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
import { describe, it, expect } from 'vitest';
|
|
80
|
+
import { MockMemoryAdapter, createUserMessage } from '@cogitator-ai/test-utils';
|
|
81
|
+
|
|
82
|
+
describe('MockMemoryAdapter', () => {
|
|
83
|
+
it('stores conversation history and records calls', async () => {
|
|
84
|
+
const memory = new MockMemoryAdapter();
|
|
85
|
+
await memory.connect();
|
|
86
|
+
expect(memory.isConnected()).toBe(true);
|
|
87
|
+
|
|
88
|
+
const threadResult = await memory.createThread('agent-1', { topic: 'testing' }, 'thread-123');
|
|
89
|
+
expect(threadResult.success).toBe(true);
|
|
90
|
+
|
|
91
|
+
const addResult = await memory.addEntry({
|
|
92
|
+
threadId: 'thread-123',
|
|
93
|
+
message: createUserMessage('Remember this note'),
|
|
94
|
+
tokenCount: 4,
|
|
95
|
+
});
|
|
96
|
+
expect(addResult.success).toBe(true);
|
|
97
|
+
|
|
98
|
+
const entriesResult = await memory.getEntries({ threadId: 'thread-123' });
|
|
99
|
+
expect(entriesResult.success).toBe(true);
|
|
100
|
+
if (entriesResult.success) {
|
|
101
|
+
expect(entriesResult.data).toHaveLength(1);
|
|
102
|
+
expect(entriesResult.data[0].message.content).toBe('Remember this note');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
expect(memory.getCallsFor('createThread')).toHaveLength(1);
|
|
106
|
+
expect(memory.getCallsFor('addEntry')).toHaveLength(1);
|
|
107
|
+
|
|
108
|
+
await memory.disconnect();
|
|
109
|
+
expect(memory.isConnected()).toBe(false);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Mocks
|
|
117
|
+
|
|
118
|
+
### MockLLMBackend
|
|
119
|
+
|
|
120
|
+
`MockLLMBackend` implements `LLMBackend` (`provider: 'openai'`) and answers calls with scripted responses or stream chunks while recording all incoming requests.
|
|
121
|
+
|
|
122
|
+
#### Scripting Chat Responses
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
import { MockLLMBackend, createMockLLMBackend, createToolCall } from '@cogitator-ai/test-utils';
|
|
126
|
+
|
|
127
|
+
const backend = createMockLLMBackend();
|
|
128
|
+
|
|
129
|
+
// Set a single response for all chat() calls
|
|
130
|
+
backend.setResponse({ content: 'Hello, world!' });
|
|
131
|
+
|
|
132
|
+
// Set multiple responses returned in sequence (the last response repeats)
|
|
133
|
+
backend.setResponses([{ content: 'First response' }, { content: 'Second response' }]);
|
|
134
|
+
|
|
135
|
+
// Shortcut for scripted tool call responses
|
|
136
|
+
backend.setToolCallResponse([createToolCall('calculator', { expression: '2 + 2' })]);
|
|
137
|
+
|
|
138
|
+
// Set default delay (in ms) before answering
|
|
139
|
+
backend.setDefaultDelay(50);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
#### Streaming
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { MockLLMBackend, collectStreamContent } from '@cogitator-ai/test-utils';
|
|
146
|
+
|
|
147
|
+
const backend = new MockLLMBackend();
|
|
148
|
+
|
|
149
|
+
// Script a stream for chatStream()
|
|
150
|
+
backend.setStreamChunks([{ content: 'Hello' }, { content: ' world' }, { content: '!' }]);
|
|
151
|
+
|
|
152
|
+
// Or script multiple distinct streams in sequence
|
|
153
|
+
backend.setMultipleStreamChunks([[{ content: 'First stream' }], [{ content: 'Second stream' }]]);
|
|
154
|
+
|
|
155
|
+
const stream = backend.chatStream({
|
|
156
|
+
model: 'test-model',
|
|
157
|
+
messages: [{ role: 'user', content: 'Hi' }],
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const text = await collectStreamContent(stream);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Request Inspection
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// Inspect recorded requests
|
|
167
|
+
const count = backend.getCallCount();
|
|
168
|
+
const allCalls = backend.getCalls();
|
|
169
|
+
const lastCall = backend.getLastCall();
|
|
170
|
+
|
|
171
|
+
// Predicate match
|
|
172
|
+
const wasCalled = backend.wasCalledWith((req) => req.model === 'test-model');
|
|
173
|
+
|
|
174
|
+
// Reset calls, responses, and stream chunks
|
|
175
|
+
backend.reset();
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### MockMemoryAdapter
|
|
179
|
+
|
|
180
|
+
`MockMemoryAdapter` implements `MemoryAdapter` (`provider: 'memory'`) in memory using native Maps and records every invocation.
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { MockMemoryAdapter, createMockMemoryAdapter } from '@cogitator-ai/test-utils';
|
|
184
|
+
|
|
185
|
+
const memory = createMockMemoryAdapter();
|
|
186
|
+
|
|
187
|
+
// Lifecycle
|
|
188
|
+
await memory.connect();
|
|
189
|
+
const connected = memory.isConnected(); // true
|
|
190
|
+
|
|
191
|
+
// Threads
|
|
192
|
+
const thread = await memory.createThread('agent-id', { tag: 'session' }, 'custom-id');
|
|
193
|
+
const fetchedThread = await memory.getThread('custom-id');
|
|
194
|
+
await memory.updateThread('custom-id', { tag: 'updated' });
|
|
195
|
+
|
|
196
|
+
// Entries
|
|
197
|
+
await memory.addEntry({
|
|
198
|
+
threadId: 'custom-id',
|
|
199
|
+
message: { role: 'user', content: 'Hello' },
|
|
200
|
+
tokenCount: 1,
|
|
201
|
+
});
|
|
202
|
+
const entries = await memory.getEntries({ threadId: 'custom-id', limit: 10 });
|
|
203
|
+
const singleEntry = await memory.getEntry(
|
|
204
|
+
entries.success && entries.data[0] ? entries.data[0].id : ''
|
|
205
|
+
);
|
|
206
|
+
await memory.deleteEntry('entry-id');
|
|
207
|
+
await memory.clearThread('custom-id');
|
|
208
|
+
await memory.deleteThread('custom-id');
|
|
209
|
+
|
|
210
|
+
// Inspection
|
|
211
|
+
const calls = memory.getCalls(); // Array<{ method: string; args: unknown[] }>
|
|
212
|
+
const threadCalls = memory.getCallsFor('createThread');
|
|
213
|
+
|
|
214
|
+
// Reset all internal state and calls
|
|
215
|
+
memory.reset();
|
|
216
|
+
await memory.disconnect();
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Fixtures
|
|
222
|
+
|
|
223
|
+
### Agents
|
|
224
|
+
|
|
225
|
+
Generate test agent configs or agent-shaped objects with test defaults:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
import { createTestAgentConfig, createTestAgent } from '@cogitator-ai/test-utils';
|
|
229
|
+
|
|
230
|
+
// AgentConfig with default name 'test-agent' and model 'mock/test-model'
|
|
231
|
+
const config = createTestAgentConfig({
|
|
232
|
+
name: 'custom-agent',
|
|
233
|
+
instructions: 'Custom instructions',
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
// Agent-shaped object implementing the Agent interface
|
|
237
|
+
const agent = createTestAgent({
|
|
238
|
+
name: 'test-agent',
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Messages and Tool Calls
|
|
243
|
+
|
|
244
|
+
Construct strongly typed conversation messages, tool calls, and tool results:
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
import {
|
|
248
|
+
createUserMessage,
|
|
249
|
+
createAssistantMessage,
|
|
250
|
+
createSystemMessage,
|
|
251
|
+
createToolMessage,
|
|
252
|
+
createMultimodalMessage,
|
|
253
|
+
createImageUrlMessage,
|
|
254
|
+
createToolCall,
|
|
255
|
+
createToolResult,
|
|
256
|
+
createConversation,
|
|
257
|
+
} from '@cogitator-ai/test-utils';
|
|
258
|
+
|
|
259
|
+
const userMsg = createUserMessage('Hello');
|
|
260
|
+
const assistantMsg = createAssistantMessage('Hi there');
|
|
261
|
+
const systemMsg = createSystemMessage('You are a test assistant');
|
|
262
|
+
const toolMsg = createToolMessage('call_1', '{"result": 42}', 'calculator');
|
|
263
|
+
|
|
264
|
+
const multimodalMsg = createMultimodalMessage([
|
|
265
|
+
{ type: 'text', text: 'Describe this' },
|
|
266
|
+
{ type: 'image_url', image_url: { url: 'https://example.com/image.png' } },
|
|
267
|
+
]);
|
|
268
|
+
const imgMsg = createImageUrlMessage('Look at this', 'https://example.com/image.png');
|
|
269
|
+
|
|
270
|
+
const call = createToolCall('calculator', { expression: '2 + 2' });
|
|
271
|
+
const result = createToolResult(call, { result: 4 });
|
|
272
|
+
|
|
273
|
+
const turns = createConversation(
|
|
274
|
+
{ role: 'user', content: 'Hello' },
|
|
275
|
+
{ role: 'assistant', content: 'Hi' }
|
|
276
|
+
);
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Tools
|
|
280
|
+
|
|
281
|
+
Predefined JSON Schema tool fixtures for testing tool execution and schema passing:
|
|
282
|
+
|
|
283
|
+
```typescript
|
|
284
|
+
import {
|
|
285
|
+
createTestTool,
|
|
286
|
+
createCalculatorTool,
|
|
287
|
+
createWeatherTool,
|
|
288
|
+
createFailingTool,
|
|
289
|
+
createSlowTool,
|
|
290
|
+
createToolSchema,
|
|
291
|
+
} from '@cogitator-ai/test-utils';
|
|
292
|
+
|
|
293
|
+
// Customizable SimpleTool
|
|
294
|
+
const customTool = createTestTool({
|
|
295
|
+
name: 'custom_tool',
|
|
296
|
+
description: 'A custom tool',
|
|
297
|
+
execute: async (args) => ({ echo: args }),
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
// Built-in tools
|
|
301
|
+
const calc = createCalculatorTool(); // evaluates arithmetic expressions ('2 + 2')
|
|
302
|
+
const weather = createWeatherTool(); // returns 22°C sunny weather for city
|
|
303
|
+
const failing = createFailingTool('Custom error'); // always throws
|
|
304
|
+
const slow = createSlowTool(50); // delays for specified ms before returning
|
|
305
|
+
|
|
306
|
+
// ToolSchema fixture
|
|
307
|
+
const schema = createToolSchema('my_tool', 'Tool description');
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Run Results
|
|
311
|
+
|
|
312
|
+
Mock `RunResult` structures for code consuming agent execution outcomes:
|
|
313
|
+
|
|
314
|
+
```typescript
|
|
315
|
+
import {
|
|
316
|
+
createMockRunResult,
|
|
317
|
+
createRunResultWithToolCalls,
|
|
318
|
+
createRunResultWithMessages,
|
|
319
|
+
} from '@cogitator-ai/test-utils';
|
|
320
|
+
|
|
321
|
+
const baseResult = createMockRunResult('Final answer');
|
|
322
|
+
const withTools = createRunResultWithToolCalls('Output', [call]);
|
|
323
|
+
const withHistory = createRunResultWithMessages('Output', [userMsg, assistantMsg]);
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Helpers
|
|
329
|
+
|
|
330
|
+
### Stream Helpers
|
|
331
|
+
|
|
332
|
+
Helpers to consume and test asynchronous generator streams (`AsyncGenerator<ChatStreamChunk>`):
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
import {
|
|
336
|
+
collectStreamContent,
|
|
337
|
+
collectStreamChunks,
|
|
338
|
+
collectStreamToolCalls,
|
|
339
|
+
createMockReadableStream,
|
|
340
|
+
} from '@cogitator-ai/test-utils';
|
|
341
|
+
|
|
342
|
+
// Drains stream and returns concatenated text
|
|
343
|
+
const content = await collectStreamContent(stream);
|
|
344
|
+
|
|
345
|
+
// Drains stream and returns all chunks as an array
|
|
346
|
+
const chunks = await collectStreamChunks(stream);
|
|
347
|
+
|
|
348
|
+
// Drains stream and returns parsed tool calls
|
|
349
|
+
const toolCalls = await collectStreamToolCalls(stream);
|
|
350
|
+
|
|
351
|
+
// Creates a ReadableStream<Uint8Array> from string chunks (e.g. for SSE testing)
|
|
352
|
+
const byteStream = createMockReadableStream(['data: {"text":"hello"}\n\n']);
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Async Helpers
|
|
356
|
+
|
|
357
|
+
Utilities for handling asynchronous timing, polling, and timeouts:
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
import { waitFor, eventually, delay, withTimeout } from '@cogitator-ai/test-utils';
|
|
361
|
+
|
|
362
|
+
// Sleep for ms
|
|
363
|
+
await delay(100);
|
|
364
|
+
|
|
365
|
+
// Poll condition until truthy or timeout (defaults: timeout 5000ms, interval 50ms)
|
|
366
|
+
const ready = await waitFor(() => checkReady(), { timeout: 2000, interval: 20 });
|
|
367
|
+
|
|
368
|
+
// Retry assertion until it passes or timeout
|
|
369
|
+
await eventually(() => expect(isDone()).toBe(true), { timeout: 3000, interval: 50 });
|
|
370
|
+
|
|
371
|
+
// Wrap promise with timeout
|
|
372
|
+
const value = await withTimeout(fetchData(), 1000);
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Conformance
|
|
378
|
+
|
|
379
|
+
A complete kit for verifying that custom or third-party `LLMBackend` implementations correctly adhere to provider protocols, error handling, cancellation, and streaming conventions.
|
|
380
|
+
|
|
381
|
+
### Backend Conformance Suite
|
|
382
|
+
|
|
383
|
+
Run the full suite of conformance test cases against an `LLMBackend`:
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
import { describe, it } from 'vitest';
|
|
387
|
+
import {
|
|
388
|
+
backendConformanceCases,
|
|
389
|
+
openAIChatWire,
|
|
390
|
+
type BackendConformanceTarget,
|
|
391
|
+
} from '@cogitator-ai/test-utils';
|
|
392
|
+
|
|
393
|
+
const target: BackendConformanceTarget = {
|
|
394
|
+
name: 'MyCustomBackend',
|
|
395
|
+
model: 'gpt-4o',
|
|
396
|
+
wire: openAIChatWire,
|
|
397
|
+
createBackend: (url) => new MyCustomBackend({ baseUrl: url }),
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
describe('MyCustomBackend conformance', () => {
|
|
401
|
+
for (const c of backendConformanceCases(target)) {
|
|
402
|
+
(c.skip ? it.skip : it)(c.name, () => c.run());
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Fake Provider Server
|
|
408
|
+
|
|
409
|
+
Run a lightweight HTTP server emulating provider APIs:
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
import { startFakeProvider, sse } from '@cogitator-ai/test-utils';
|
|
413
|
+
|
|
414
|
+
const server = await startFakeProvider();
|
|
415
|
+
|
|
416
|
+
server.reply((req) => {
|
|
417
|
+
if (req.path === '/v1/chat/completions') {
|
|
418
|
+
return {
|
|
419
|
+
type: 'stream',
|
|
420
|
+
contentType: 'text/event-stream',
|
|
421
|
+
chunks: [sse({ choices: [{ delta: { content: 'Hi' } }] })],
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
return { type: 'json', status: 404, body: { error: 'Not found' } };
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
console.log(`Fake provider listening at: ${server.url}`);
|
|
428
|
+
|
|
429
|
+
await server.close();
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Wire Protocols & Encodings
|
|
433
|
+
|
|
434
|
+
Wire specifications and formatting helpers for popular LLM provider protocols:
|
|
435
|
+
|
|
436
|
+
- **Wires**: `openAIChatWire`, `openAIResponsesWire`, `anthropicWire`, `geminiWire`, `ollamaWire`, `bedrockConverseWire`
|
|
437
|
+
- **Encodings**: `sse(data, event?)`, `ndjson(data)`, `awsEventStreamMessage(headers, payload)`
|
|
438
|
+
- **Fixture**: `conformanceRequest`, `CONFORMANCE_FIXTURE`
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Public Exports
|
|
443
|
+
|
|
444
|
+
Public exports are grouped in `src/index.ts` as:
|
|
445
|
+
|
|
446
|
+
| Group | Module | Description |
|
|
447
|
+
| --------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
448
|
+
| **Mocks** | `@cogitator-ai/test-utils` (`./mocks`) | `MockLLMBackend`, `createMockLLMBackend`, `MockMemoryAdapter`, `createMockMemoryAdapter`, `MockChatResponse`, `MockStreamChunk` |
|
|
449
|
+
| **Fixtures** | `@cogitator-ai/test-utils` (`./fixtures`) | `createTestAgent`, `createTestAgentConfig`, `TestAgentConfig`, `createUserMessage`, `createAssistantMessage`, `createSystemMessage`, `createToolMessage`, `createMultimodalMessage`, `createImageUrlMessage`, `createToolCall`, `createToolResult`, `createConversation`, `createTestTool`, `createCalculatorTool`, `createWeatherTool`, `createFailingTool`, `createSlowTool`, `createToolSchema`, `TestToolOptions`, `SimpleTool`, `createMockRunResult`, `createRunResultWithToolCalls`, `createRunResultWithMessages`, `TestRunResultOptions` |
|
|
450
|
+
| **Helpers** | `@cogitator-ai/test-utils` (`./helpers`) | `collectStreamContent`, `collectStreamChunks`, `collectStreamToolCalls`, `createMockReadableStream`, `waitFor`, `eventually`, `delay`, `withTimeout` |
|
|
451
|
+
| **Conformance** | `@cogitator-ai/test-utils` (`./conformance`) | `startFakeProvider`, `FakeProvider`, `FakeProviderHandler`, `FakeProviderOptions`, `FakeProviderReply`, `FakeProviderRequest`, `backendConformanceCases`, `conformanceRequest`, `CONFORMANCE_FIXTURE`, `BackendConformanceCase`, `BackendConformanceTarget`, `ConformanceMode`, `ConformanceScenario`, `ProviderWire`, `openAIChatWire`, `openAIResponsesWire`, `anthropicWire`, `geminiWire`, `ollamaWire`, `bedrockConverseWire`, `sse`, `ndjson`, `awsEventStreamMessage` |
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## License
|
|
456
|
+
|
|
457
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cogitator-ai/test-utils",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "Shared testing utilities for Cogitator packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cogitator",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"node": ">=22.12.0"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@cogitator-ai/types": "0.
|
|
31
|
+
"@cogitator-ai/types": "0.45.0",
|
|
32
32
|
"nanoid": "^6.0.1"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|