@node-llm/testing 0.1.0

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +541 -0
  3. package/dist/Mocker.d.ts +58 -0
  4. package/dist/Mocker.d.ts.map +1 -0
  5. package/dist/Mocker.js +247 -0
  6. package/dist/Scrubber.d.ts +18 -0
  7. package/dist/Scrubber.d.ts.map +1 -0
  8. package/dist/Scrubber.js +68 -0
  9. package/dist/index.d.ts +3 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +2 -0
  12. package/dist/vcr.d.ts +57 -0
  13. package/dist/vcr.d.ts.map +1 -0
  14. package/dist/vcr.js +291 -0
  15. package/package.json +19 -0
  16. package/src/Mocker.ts +311 -0
  17. package/src/Scrubber.ts +85 -0
  18. package/src/index.ts +2 -0
  19. package/src/vcr.ts +377 -0
  20. package/test/cassettes/custom-scrub-config.json +33 -0
  21. package/test/cassettes/defaults-plus-custom.json +33 -0
  22. package/test/cassettes/explicit-sugar-test.json +33 -0
  23. package/test/cassettes/feature-1-vcr.json +33 -0
  24. package/test/cassettes/global-config-keys.json +33 -0
  25. package/test/cassettes/global-config-merge.json +33 -0
  26. package/test/cassettes/global-config-patterns.json +33 -0
  27. package/test/cassettes/global-config-reset.json +33 -0
  28. package/test/cassettes/global-config-test.json +33 -0
  29. package/test/cassettes/streaming-chunks.json +18 -0
  30. package/test/cassettes/testunitdxtestts-vcr-feature-5-6-dx-sugar-auto-naming-automatically-names-and-records-cassettes.json +33 -0
  31. package/test/cassettes/vcr-feature-5-6-dx-sugar-auto-naming-automatically-names-and-records-cassettes.json +28 -0
  32. package/test/cassettes/vcr-streaming.json +17 -0
  33. package/test/helpers/MockProvider.ts +75 -0
  34. package/test/unit/ci.test.ts +36 -0
  35. package/test/unit/dx.test.ts +86 -0
  36. package/test/unit/mocker-debug.test.ts +68 -0
  37. package/test/unit/mocker.test.ts +46 -0
  38. package/test/unit/multimodal.test.ts +46 -0
  39. package/test/unit/scoping.test.ts +54 -0
  40. package/test/unit/scrubbing.test.ts +110 -0
  41. package/test/unit/streaming.test.ts +51 -0
  42. package/test/unit/strict-mode.test.ts +112 -0
  43. package/test/unit/tools.test.ts +58 -0
  44. package/test/unit/vcr-global-config.test.ts +87 -0
  45. package/test/unit/vcr-mismatch.test.ts +172 -0
  46. package/test/unit/vcr-passthrough.test.ts +68 -0
  47. package/test/unit/vcr-streaming.test.ts +86 -0
  48. package/test/unit/vcr.test.ts +34 -0
  49. package/tsconfig.json +9 -0
  50. package/vitest.config.ts +12 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Initial release
6
+ - VCR record/replay
7
+ - Fluent mocking
8
+ - CI-safe defaults
package/README.md ADDED
@@ -0,0 +1,541 @@
1
+ # @node-llm/testing ๐ŸŒ‘๐ŸŸข๐Ÿงช
2
+
3
+ Deterministic testing infrastructure for NodeLLM-powered AI systems. Built for engineers who prioritize **Boring Solutions**, **Security**, and **High-Fidelity Feedback Loops**.
4
+
5
+ > ๐Ÿ’ก **What is High-Fidelity?**
6
+ > Your tests exercise the same execution path, provider behavior, and tool orchestration as production โ€” without live network calls.
7
+
8
+ **Framework Support**: โœ… Vitest (native) | โœ… Jest (compatible) | โœ… Any test framework (core APIs)
9
+
10
+ ---
11
+
12
+ ## ๐Ÿงญ The Philosophy: Two-Tier Testing
13
+
14
+ We believe AI testing should never be flaky or expensive. We provide two distinct strategies:
15
+
16
+ ### 1. VCR (Integration Testing) ๐Ÿ“ผ
17
+
18
+ **When to use**: To verify your system works with real LLM responses without paying for every test run.
19
+
20
+ - **High Fidelity**: Captures the exact raw response from the provider.
21
+ - **Security First**: Automatically scrubs API Keys and sensitive PII from "cassettes".
22
+ - **CI Safe**: Fails-fast in CI if a cassette is missing, preventing accidental live API calls.
23
+
24
+ ### 2. Mocker (Unit Testing) ๐ŸŽญ
25
+
26
+ **When to use**: To test application logic, edge cases (errors, rate limits), and rare tool-calling paths.
27
+
28
+ - **Declarative**: Fluent API to define expected prompts and responses.
29
+ - **Multimodal**: Native support for `chat`, `embed`, `paint`, `transcribe`, and `moderate`.
30
+ - **Streaming**: Simulate token-by-token delivery to test real-time UI logic.
31
+
32
+ ---
33
+
34
+ ## ๐Ÿ“ผ VCR Usage
35
+
36
+ ### Basic Interaction
37
+
38
+ Wrap your tests in `withVCR` to automatically record interactions the first time they run.
39
+
40
+ ```typescript
41
+ import { withVCR } from "@node-llm/testing";
42
+
43
+ it(
44
+ "calculates sentiment correctly",
45
+ withVCR(async () => {
46
+ const result = await mySentimentAgent.run("I love NodeLLM!");
47
+ expect(result.sentiment).toBe("positive");
48
+ })
49
+ );
50
+ ```
51
+
52
+ ### Hierarchical Organization (Rails Mode) ๐Ÿ“‚
53
+
54
+ Organize your cassettes into nested subfolders to match your test suite structure.
55
+
56
+ ```typescript
57
+ import { describeVCR, withVCR } from "@node-llm/testing";
58
+
59
+ describeVCR("Authentication", () => {
60
+ describeVCR("Login", () => {
61
+ it(
62
+ "logs in successfully",
63
+ withVCR(async () => {
64
+ // Cassette saved to: .llm-cassettes/authentication/login/logs-in-successfully.json
65
+ })
66
+ );
67
+ });
68
+ });
69
+ ```
70
+
71
+ ### Security & Scrubbing ๐Ÿ›ก๏ธ
72
+
73
+ The VCR automatically redacts `api_key`, `authorization`, and other sensitive headers. You can add custom redaction:
74
+
75
+ ```typescript
76
+ withVCR({
77
+ scrub: (data) => data.replace(/SSN: \d+/g, "[REDACTED_SSN]")
78
+ }, async () => { ... });
79
+ ```
80
+
81
+ ---
82
+
83
+ ## ๐ŸŽญ Mocker Usage
84
+
85
+ ### Fluent, Explicit Mocking
86
+
87
+ Define lightning-fast, zero-network tests for your agents.
88
+
89
+ ```typescript
90
+ import { mockLLM } from "@node-llm/testing";
91
+
92
+ const mocker = mockLLM();
93
+
94
+ // Exact match
95
+ mocker.chat("Ping").respond("Pong");
96
+
97
+ // Regex match
98
+ mocker.chat(/hello/i).respond("Greetings!");
99
+
100
+ // Simulate a Tool Call
101
+ mocker.chat("What's the weather?").callsTool("get_weather", { city: "London" });
102
+ ```
103
+
104
+ ### Streaming Mocks ๐ŸŒŠ
105
+
106
+ Test your streaming logic by simulating token delivery.
107
+
108
+ ```typescript
109
+ mocker.chat("Tell a story").stream(["Once ", "upon ", "a ", "time."]);
110
+ ```
111
+
112
+ ### Multimodal Mocks ๐ŸŽจ
113
+
114
+ ```typescript
115
+ mocker.paint(/a cat/i).respond({ url: "https://mock.com/cat.png" });
116
+ mocker.embed("text").respond({ vectors: [[0.1, 0.2, 0.3]] });
117
+ ```
118
+
119
+ ---
120
+
121
+ ## ๐Ÿ›ฃ๏ธ Decision Tree: VCR vs Mocker
122
+
123
+ Choose the right tool for your test:
124
+
125
+ ```
126
+ Does your test need to verify behavior against REAL LLM responses?
127
+ โ”œโ”€ YES โ†’ Use VCR (integration testing)
128
+ โ”‚ โ”œโ”€ Do you need to record the first time and replay afterward?
129
+ โ”‚ โ”‚ โ””โ”€ YES โ†’ Use VCR in "record" or "auto" mode
130
+ โ”‚ โ”œโ”€ Are you testing in CI/CD? (No live API calls allowed)
131
+ โ”‚ โ”‚ โ””โ”€ YES โ†’ Set VCR_MODE=replay in CI
132
+ โ”‚ โ””โ”€ Need custom scrubbing for sensitive data?
133
+ โ”‚ โ””โ”€ YES โ†’ Use withVCR({ scrub: ... })
134
+ โ”‚
135
+ โ””โ”€ NO โ†’ Use Mocker (unit testing)
136
+ โ”œโ”€ Testing error handling, edge cases, or rare paths?
137
+ โ”‚ โ””โ”€ YES โ†’ Mock the error with mocker.chat(...).respond({ error: ... })
138
+ โ”œโ”€ Testing streaming token delivery?
139
+ โ”‚ โ””โ”€ YES โ†’ Use mocker.chat(...).stream([...])
140
+ โ””โ”€ Testing tool-calling paths without real tools?
141
+ โ””โ”€ YES โ†’ Use mocker.chat(...).callsTool(name, params)
142
+ ```
143
+
144
+ **Quick Reference**:
145
+
146
+ - **VCR**: Database queries, API calls, real provider behavior, network latency
147
+ - **Mocker**: Business logic, UI interactions, error scenarios, tool orchestration
148
+
149
+ ### At-a-Glance Comparison
150
+
151
+ | Use Case | VCR | Mocker |
152
+ | ----------------------- | ----------------- | ------ |
153
+ | Real provider behavior | โœ… | โŒ |
154
+ | CI-safe (no live calls) | โœ… (after record) | โœ… |
155
+ | Zero network overhead | โŒ (first run) | โœ… |
156
+ | Error simulation | โš ๏ธ (record real) | โœ… |
157
+ | Tool orchestration | โœ… | โœ… |
158
+ | Streaming tokens | โœ… | โœ… |
159
+
160
+ ---
161
+
162
+ ## โš™๏ธ Configuration
163
+
164
+ ### Environment Variables
165
+
166
+ | Env Variable | Description | Default |
167
+ | ------------------ | ---------------------------------------------------------- | ---------------- |
168
+ | `VCR_MODE` | `record`, `replay`, `auto`, or `passthrough` | `auto` |
169
+ | `VCR_CASSETTE_DIR` | Base directory for cassettes | `test/cassettes` |
170
+ | `CI` | When true, VCR prevents recording and forces exact matches | (Auto-detected) |
171
+
172
+ ### Programmatic Configuration
173
+
174
+ Configure VCR globally for all instances in your test suite:
175
+
176
+ ```typescript
177
+ import { configureVCR, resetVCRConfig } from "@node-llm/testing";
178
+
179
+ // Before all tests
180
+ beforeAll(() => {
181
+ configureVCR({
182
+ // Custom keys to redact in cassettes
183
+ sensitiveKeys: ["api_key", "bearer_token", "custom_secret"],
184
+
185
+ // Custom regex patterns to redact
186
+ sensitivePatterns: [/api_key=[\w]+/g, /Bearer ([\w.-]+)/g]
187
+ });
188
+ });
189
+
190
+ // After all tests
191
+ afterAll(() => {
192
+ resetVCRConfig();
193
+ });
194
+ ```
195
+
196
+ ### Per-Instance Configuration
197
+
198
+ Override global settings for a specific VCR instance:
199
+
200
+ ```typescript
201
+ withVCR(
202
+ {
203
+ mode: "replay",
204
+ cassettesDir: "./test/fixtures",
205
+ scrub: (data) => data.replace(/email=\S+@/, "email=[REDACTED]@"),
206
+ sensitiveKeys: ["session_token"]
207
+ },
208
+ async () => {
209
+ // Test runs here
210
+ }
211
+ );
212
+ ```
213
+
214
+ });
215
+
216
+ ````
217
+
218
+ ---
219
+
220
+ ## ๐Ÿงช Framework Integration
221
+
222
+ ### Vitest (Native Support)
223
+
224
+ Vitest is the primary test framework with optimized helpers:
225
+
226
+ ```typescript
227
+ import { it, describe } from "vitest";
228
+ import { mockLLM, withVCR, describeVCR } from "@node-llm/testing";
229
+
230
+ describeVCR("Payments", () => {
231
+ it(
232
+ "processes successfully",
233
+ withVCR(async () => {
234
+ // โœจ withVCR auto-detects test name ("processes successfully")
235
+ // โœจ describeVCR auto-manages scopes
236
+ })
237
+ );
238
+ });
239
+ ```
240
+
241
+ ### Jest Compatibility
242
+
243
+ All core APIs work with Jest. The only difference: `withVCR()` can't auto-detect test names, so provide it manually:
244
+
245
+ ```typescript
246
+ import { describe, it } from "@jest/globals";
247
+ import { mockLLM, setupVCR, describeVCR } from "@node-llm/testing";
248
+
249
+ describeVCR("Payments", () => {
250
+ it("processes successfully", async () => {
251
+ // โœ… describeVCR works with Jest (framework-agnostic)
252
+ // โš ๏ธ withVCR doesn't work here (needs Vitest's expect.getState())
253
+ // โœ… Use setupVCR instead:
254
+ const vcr = setupVCR("processes", { mode: "record" });
255
+
256
+ const mocker = mockLLM(); // โœ… works with Jest
257
+ mocker.chat("pay").respond("done");
258
+
259
+ // Test logic here
260
+
261
+ await vcr.stop();
262
+ });
263
+ });
264
+ ```
265
+
266
+ ### Framework Support Matrix
267
+
268
+ | API | Vitest | Jest | Any Framework |
269
+ |-----|--------|------|---------------|
270
+ | `mockLLM()` | โœ… | โœ… | โœ… |
271
+ | `describeVCR()` | โœ… | โœ… | โœ… |
272
+ | `setupVCR()` | โœ… | โœ… | โœ… |
273
+ | `withVCR()` | โœ… (auto name) | โš ๏ธ (manual name) | โš ๏ธ (manual name) |
274
+ | Mocker class | โœ… | โœ… | โœ… |
275
+ | VCR class | โœ… | โœ… | โœ… |
276
+
277
+ **Only `withVCR()` is Vitest-specific** because it auto-detects test names. All other APIs are framework-agnostic.
278
+
279
+ ### Any Test Framework
280
+
281
+ Using raw classes for maximum portability:
282
+
283
+ ```typescript
284
+ import { Mocker, VCR } from "@node-llm/testing";
285
+
286
+ // Mocker - works everywhere
287
+ const mocker = new Mocker();
288
+ mocker.chat("hello").respond("hi");
289
+
290
+ // VCR - works everywhere
291
+ const vcr = new VCR("test-name", { mode: "record" });
292
+ // ... run test ...
293
+ await vcr.stop();
294
+ ```
295
+
296
+ ---
297
+
298
+ ## ๐Ÿšจ Error Handling & Debugging
299
+
300
+ ### VCR Common Issues
301
+
302
+ #### Missing Cassette Error
303
+
304
+ **Error**: `Error: Cassette file not found`
305
+
306
+ **Cause**: VCR is in `replay` mode but the cassette doesn't exist yet.
307
+
308
+ **Solution**:
309
+ ```typescript
310
+ // Either: Record it first
311
+ VCR_MODE=record npm test
312
+
313
+ // Or: Use auto mode (records if missing, replays if exists)
314
+ VCR_MODE=auto npm test
315
+
316
+ // Or: Explicitly set mode
317
+ withVCR({ mode: "record" }, async () => { ... });
318
+ ````
319
+
320
+ #### Cassette Mismatch Error
321
+
322
+ **Error**: `AssertionError: No interaction matched the request`
323
+
324
+ **Cause**: Your code is making a request that doesn't match any recorded interaction.
325
+
326
+ **Solution**:
327
+
328
+ ```typescript
329
+ // 1. Debug what request was made
330
+ const mocker = mockLLM();
331
+ mocker.onAnyRequest((req) => {
332
+ console.log("Unexpected request:", req.prompt);
333
+ });
334
+
335
+ // 2. Re-record the cassette
336
+ rm -rf .llm-cassettes/your-test
337
+ VCR_MODE=record npm test -- your-test
338
+
339
+ // 3. Commit the updated cassette to git
340
+ ```
341
+
342
+ #### Sensitive Data Not Scrubbed
343
+
344
+ **Error**: API keys appear in cassette JSON
345
+
346
+ **Solution**: Add custom scrubbing rules
347
+
348
+ ```typescript
349
+ import { configureVCR } from "@node-llm/testing";
350
+
351
+ configureVCR({
352
+ sensitiveKeys: ["x-api-key", "authorization", "custom_token"],
353
+ sensitivePatterns: [/Bearer ([\w.-]+)/g]
354
+ });
355
+ ```
356
+
357
+ ### Mocker Common Issues
358
+
359
+ #### Strict Mode Enforcement
360
+
361
+ **Error**: `Error: No mock defined for prompt: "unexpected question"`
362
+
363
+ **Cause**: Your code asked a question you didn't mock in strict mode.
364
+
365
+ **Solution**:
366
+
367
+ ```typescript
368
+ // Either: Add the missing mock
369
+ mocker.chat("unexpected question").respond("mocked response");
370
+
371
+ // Or: Disable strict mode
372
+ const mocker = mockLLM({ strict: false });
373
+ // Now unmocked requests return generic "I don't have a response" message
374
+
375
+ // Or: Debug what's being asked
376
+ mocker.onAnyRequest((req) => {
377
+ console.error("Unmatched request:", req.prompt);
378
+ throw new Error(`Add mock for: mocker.chat("${req.prompt}").respond(...)`);
379
+ });
380
+ ```
381
+
382
+ #### Stream Simulation Issues
383
+
384
+ **Error**: `TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined`
385
+
386
+ **Cause**: Stream mock not properly yielding tokens.
387
+
388
+ **Solution**:
389
+
390
+ ```typescript
391
+ // Correct: Array of tokens
392
+ mocker.chat("story").stream(["Once ", "upon ", "a ", "time."]);
393
+
394
+ // Incorrect: String instead of array
395
+ mocker.chat("story").stream("Once upon a time."); // โŒ Wrong!
396
+ ```
397
+
398
+ ### Debug Information
399
+
400
+ Get detailed insight into what mocks are registered:
401
+
402
+ ```typescript
403
+ const mocker = mockLLM();
404
+ mocker.chat("hello").respond("hi");
405
+ mocker.embed("text").respond({ vectors: [[0.1, 0.2]] });
406
+
407
+ const debug = mocker.getDebugInfo();
408
+ console.log(debug);
409
+ // Output:
410
+ // {
411
+ // totalMocks: 2,
412
+ // methods: ["chat", "embed"]
413
+ // }
414
+ ```
415
+
416
+ ---
417
+
418
+ ## ๐Ÿ“š Type Documentation
419
+
420
+ ### VCROptions
421
+
422
+ ```typescript
423
+ interface VCROptions {
424
+ // Recording/Replay behavior
425
+ mode?: "record" | "replay" | "auto" | "passthrough";
426
+ cassettesDir?: string;
427
+
428
+ // Security & Scrubbing
429
+ sensitiveKeys?: string[];
430
+ sensitivePatterns?: RegExp[];
431
+ scrub?: (data: string) => string;
432
+ }
433
+ ```
434
+
435
+ ### MockerOptions
436
+
437
+ ```typescript
438
+ interface MockerOptions {
439
+ // Enforce exact matching
440
+ strict?: boolean;
441
+
442
+ // Enable verbose logging
443
+ debug?: boolean;
444
+ }
445
+ ```
446
+
447
+ ### MockResponse
448
+
449
+ ```typescript
450
+ interface MockResponse {
451
+ // Simple text response
452
+ content?: string;
453
+
454
+ // Tool calling
455
+ toolName?: string;
456
+ toolParams?: Record<string, unknown>;
457
+
458
+ // Error simulation
459
+ error?: Error | string;
460
+
461
+ // Streaming tokens
462
+ tokens?: string[];
463
+
464
+ // Generation metadata
465
+ metadata?: {
466
+ tokensUsed?: number;
467
+ model?: string;
468
+ };
469
+ }
470
+ ```
471
+
472
+ ### MockerDebugInfo
473
+
474
+ ```typescript
475
+ interface MockerDebugInfo {
476
+ // Total number of mocks defined
477
+ totalMocks: number;
478
+
479
+ // Array of unique method names used ("chat", "embed", etc.)
480
+ methods: string[];
481
+ }
482
+ ```
483
+
484
+ ---
485
+
486
+ ## ๐Ÿ›๏ธ Integration with @node-llm/orm
487
+
488
+ The testing tools operate at the `providerRegistry` level. This means they **automatically** intercept LLM calls made by the ORM layer.
489
+
490
+ ### Pattern: Testing Database Persistence
491
+
492
+ When using `@node-llm/orm`, you can verify both the database state and the LLM response in a single test.
493
+
494
+ ```typescript
495
+ import { withVCR } from "@node-llm/testing";
496
+ import { createChat } from "@node-llm/orm/prisma";
497
+
498
+ it(
499
+ "saves the LLM response to the database",
500
+ withVCR(async () => {
501
+ // 1. Setup ORM Chat
502
+ const chat = await createChat(prisma, llm, { model: "gpt-4" });
503
+
504
+ // 2. Interaction (VCR intercepts the LLM call)
505
+ await chat.ask("Hello ORM!");
506
+
507
+ // 3. Verify DB state (standard Prisma/ORM assertions)
508
+ const messages = await prisma.assistantMessage.findMany({
509
+ where: { chatId: chat.id }
510
+ });
511
+
512
+ expect(messages).toHaveLength(2); // User + Assistant
513
+ expect(messages[1].content).toBeDefined();
514
+ })
515
+ );
516
+ ```
517
+
518
+ ### Pattern: Mocking Rare Logic
519
+
520
+ Use the `Mocker` to test how your application handles complex tool results or errors without setting up a real LLM.
521
+
522
+ ```typescript
523
+ import { mockLLM } from "@node-llm/testing";
524
+
525
+ it("handles tool errors in ORM sessions", async () => {
526
+ const mocker = mockLLM();
527
+ mocker.chat("Search docs").respond({ error: new Error("DB Timeout") });
528
+
529
+ const chat = await loadChat(prisma, llm, "existing-id");
530
+
531
+ await expect(chat.ask("Search docs")).rejects.toThrow("DB Timeout");
532
+ });
533
+ ```
534
+
535
+ ---
536
+
537
+ ## ๐Ÿ›๏ธ Architecture Contract
538
+
539
+ - **No Side Effects**: Mocks and VCR interceptors are automatically cleared after each test turn.
540
+ - **Deterministic**: The same input MUST always yield the same output in Replay mode.
541
+ - **Explicit > Implicit**: We prefer explicit mock definitions over complex global state.
@@ -0,0 +1,58 @@
1
+ import { ChatChunk, ToolCall, ModerationResult } from "@node-llm/core";
2
+ export interface MockResponse {
3
+ content?: string | null;
4
+ tool_calls?: ToolCall[];
5
+ usage?: {
6
+ input_tokens: number;
7
+ output_tokens: number;
8
+ total_tokens: number;
9
+ };
10
+ error?: Error;
11
+ finish_reason?: string | null;
12
+ chunks?: string[] | ChatChunk[];
13
+ vectors?: number[][];
14
+ url?: string;
15
+ data?: string;
16
+ text?: string;
17
+ results?: ModerationResult[];
18
+ revised_prompt?: string;
19
+ id?: string;
20
+ }
21
+ export type MockMatcher = (request: unknown) => boolean;
22
+ export interface MockDefinition {
23
+ method: string;
24
+ match: MockMatcher;
25
+ response: MockResponse | ((request: unknown) => MockResponse);
26
+ }
27
+ /**
28
+ * Debug information about defined mocks.
29
+ */
30
+ export interface MockerDebugInfo {
31
+ totalMocks: number;
32
+ methods: string[];
33
+ }
34
+ export declare class Mocker {
35
+ private mocks;
36
+ strict: boolean;
37
+ constructor();
38
+ chat(query?: string | RegExp): this;
39
+ stream(chunks: string[] | ChatChunk[]): this;
40
+ placeholder(query: string | RegExp): this;
41
+ callsTool(name: string, args?: Record<string, unknown>): this;
42
+ embed(input?: string | string[]): this;
43
+ paint(prompt?: string | RegExp): this;
44
+ transcribe(file?: string | RegExp): this;
45
+ moderate(input?: string | string[] | RegExp): this;
46
+ respond(response: string | MockResponse | ((req: unknown) => MockResponse)): this;
47
+ /**
48
+ * Returns debug information about defined mocks.
49
+ * Useful for troubleshooting what mocks are defined.
50
+ */
51
+ getDebugInfo(): MockerDebugInfo;
52
+ clear(): void;
53
+ private addMock;
54
+ private getContentString;
55
+ private setupInterceptor;
56
+ }
57
+ export declare function mockLLM(): Mocker;
58
+ //# sourceMappingURL=Mocker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Mocker.d.ts","sourceRoot":"","sources":["../src/Mocker.ts"],"names":[],"mappings":"AAAA,OAAO,EAaL,SAAS,EACT,QAAQ,EACR,gBAAgB,EAEjB,MAAM,gBAAgB,CAAC;AAExB,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE;QACN,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;AAExD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,YAAY,GAAG,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,YAAY,CAAC,CAAC;CAC/D;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAID,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAwB;IAC9B,MAAM,UAAS;;IAMf,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAcnC,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,GAAG,IAAI;IAU5C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAWzC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAmBjE,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI;IAQtC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASrC,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IASxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI;IAUlD,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,KAAK,YAAY,CAAC,GAAG,IAAI;IAWxF;;;OAGG;IACI,YAAY,IAAI,eAAe;IAQ/B,KAAK,IAAI,IAAI;IAKpB,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,gBAAgB;IASxB,OAAO,CAAC,gBAAgB;CA6GzB;AAED,wBAAgB,OAAO,WAEtB"}