llmist 0.8.0 → 1.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.
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  BaseGadget,
3
+ GADGET_ARG_PREFIX,
3
4
  GADGET_END_PREFIX,
4
5
  GADGET_START_PREFIX,
5
6
  LLMist,
@@ -8,7 +9,7 @@ import {
8
9
  init_constants,
9
10
  init_gadget,
10
11
  init_logger
11
- } from "./chunk-62M4TDAK.js";
12
+ } from "./chunk-VXPZQZF5.js";
12
13
 
13
14
  // src/gadgets/validation.ts
14
15
  function validateAndApplyDefaults(schema, params) {
@@ -270,17 +271,51 @@ function splitIntoChunks(text, minChunkSize = 5, maxChunkSize = 30) {
270
271
  }
271
272
  return chunks;
272
273
  }
274
+ function serializeToBlockFormat(obj, prefix = "") {
275
+ let result = "";
276
+ for (const [key, value] of Object.entries(obj)) {
277
+ const pointer = prefix ? `${prefix}/${key}` : key;
278
+ if (value === null || value === void 0) {
279
+ continue;
280
+ }
281
+ if (Array.isArray(value)) {
282
+ for (let i = 0; i < value.length; i++) {
283
+ const item = value[i];
284
+ const itemPointer = `${pointer}/${i}`;
285
+ if (typeof item === "object" && item !== null && !Array.isArray(item)) {
286
+ result += serializeToBlockFormat(item, itemPointer);
287
+ } else if (Array.isArray(item)) {
288
+ for (let j = 0; j < item.length; j++) {
289
+ result += `${GADGET_ARG_PREFIX}${itemPointer}/${j}
290
+ ${String(item[j])}
291
+ `;
292
+ }
293
+ } else {
294
+ result += `${GADGET_ARG_PREFIX}${itemPointer}
295
+ ${String(item)}
296
+ `;
297
+ }
298
+ }
299
+ } else if (typeof value === "object") {
300
+ result += serializeToBlockFormat(value, pointer);
301
+ } else {
302
+ result += `${GADGET_ARG_PREFIX}${pointer}
303
+ ${String(value)}
304
+ `;
305
+ }
306
+ }
307
+ return result;
308
+ }
273
309
  function formatGadgetCalls(gadgetCalls) {
274
310
  let text = "";
275
311
  const calls = [];
276
312
  for (const call of gadgetCalls) {
277
313
  const invocationId = call.invocationId ?? generateInvocationId();
278
314
  calls.push({ name: call.gadgetName, invocationId });
279
- const paramsJson = JSON.stringify(call.parameters);
315
+ const blockParams = serializeToBlockFormat(call.parameters);
280
316
  text += `
281
317
  ${GADGET_START_PREFIX}${call.gadgetName}
282
- ${paramsJson}
283
- ${GADGET_END_PREFIX}`;
318
+ ${blockParams}${GADGET_END_PREFIX}`;
284
319
  }
285
320
  return { text, calls };
286
321
  }
@@ -900,4 +935,4 @@ export {
900
935
  MockGadgetBuilder,
901
936
  mockGadget
902
937
  };
903
- //# sourceMappingURL=chunk-4IMGADVY.js.map
938
+ //# sourceMappingURL=chunk-OIPLYP7M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/gadgets/validation.ts","../src/testing/gadget-testing.ts","../src/testing/mock-manager.ts","../src/testing/mock-stream.ts","../src/testing/mock-adapter.ts","../src/testing/mock-builder.ts","../src/testing/mock-client.ts","../src/testing/mock-gadget.ts"],"sourcesContent":["/**\n * Validation utilities for gadget parameters.\n *\n * Provides standalone validation with Zod schema support, including\n * default application and formatted error output.\n *\n * @module gadgets/validation\n */\n\nimport type { ZodTypeAny } from \"zod\";\nimport type { BaseGadget } from \"./gadget.js\";\n\n/**\n * Individual validation issue with path and message.\n */\nexport interface ValidationIssue {\n /** Dot-separated path to the invalid field (e.g., \"user.email\") */\n path: string;\n /** Human-readable error message */\n message: string;\n}\n\n/**\n * Result of parameter validation.\n * Discriminated union based on `success` field.\n */\nexport type ValidationResult<T = Record<string, unknown>> =\n | {\n success: true;\n /** Validated and transformed data with defaults applied */\n data: T;\n }\n | {\n success: false;\n /** Formatted error message */\n error: string;\n /** Individual validation issues */\n issues: ValidationIssue[];\n };\n\n/**\n * Validate parameters against a Zod schema and apply defaults/transformations.\n *\n * This replicates the validation behavior from GadgetExecutor, making it\n * available for direct use in tests and other contexts.\n *\n * @param schema - Zod schema to validate against\n * @param params - Raw parameters to validate\n * @returns ValidationResult with either validated data or error details\n *\n * @example\n * ```typescript\n * import { validateAndApplyDefaults } from 'llmist';\n * import { z } from 'zod';\n *\n * const schema = z.object({\n * delay: z.number().default(100),\n * retries: z.number().int().min(0).default(3),\n * });\n *\n * const result = validateAndApplyDefaults(schema, { delay: 50 });\n * if (result.success) {\n * console.log(result.data); // { delay: 50, retries: 3 }\n * }\n * ```\n */\nexport function validateAndApplyDefaults<T = Record<string, unknown>>(\n schema: ZodTypeAny,\n params: Record<string, unknown>,\n): ValidationResult<T> {\n const result = schema.safeParse(params);\n\n if (result.success) {\n return {\n success: true,\n data: result.data as T,\n };\n }\n\n const issues: ValidationIssue[] = result.error.issues.map((issue) => ({\n path: issue.path.join(\".\") || \"root\",\n message: issue.message,\n }));\n\n const formattedError = `Invalid parameters: ${issues.map((i) => `${i.path}: ${i.message}`).join(\"; \")}`;\n\n return {\n success: false,\n error: formattedError,\n issues,\n };\n}\n\n/**\n * Validate gadget parameters using the gadget's schema.\n *\n * Convenience wrapper that extracts the schema from a gadget instance.\n * If the gadget has no schema, validation always succeeds with the\n * original parameters.\n *\n * @param gadget - Gadget instance with optional parameterSchema\n * @param params - Raw parameters to validate\n * @returns ValidationResult with either validated data or error details\n *\n * @example\n * ```typescript\n * import { validateGadgetParams, createGadget } from 'llmist';\n * import { z } from 'zod';\n *\n * const calculator = createGadget({\n * description: 'Add numbers',\n * schema: z.object({\n * a: z.number(),\n * b: z.number().default(0),\n * }),\n * execute: ({ a, b }) => String(a + b),\n * });\n *\n * const result = validateGadgetParams(calculator, { a: 5 });\n * if (result.success) {\n * console.log(result.data); // { a: 5, b: 0 }\n * }\n * ```\n */\nexport function validateGadgetParams(\n gadget: BaseGadget,\n params: Record<string, unknown>,\n): ValidationResult {\n if (!gadget.parameterSchema) {\n return {\n success: true,\n data: params,\n };\n }\n\n return validateAndApplyDefaults(gadget.parameterSchema, params);\n}\n","/**\n * Testing utilities for gadgets.\n *\n * Provides helpers for testing gadgets with schema validation without\n * requiring full executor setup.\n *\n * @module testing/gadget-testing\n */\n\nimport type { BaseGadget } from \"../gadgets/gadget.js\";\nimport { type ValidationResult, validateGadgetParams } from \"../gadgets/validation.js\";\n\n/**\n * Result of testing a gadget.\n */\nexport interface TestGadgetResult {\n /** Result string if execution succeeded */\n result?: string;\n /** Error message if validation or execution failed */\n error?: string;\n /** Parameters after validation and default application */\n validatedParams?: Record<string, unknown>;\n}\n\n/**\n * Options for testGadget.\n */\nexport interface TestGadgetOptions {\n /**\n * If true, skip schema validation.\n * Useful for testing gadget behavior with invalid parameters.\n */\n skipValidation?: boolean;\n}\n\n/**\n * Test a gadget with schema validation and default application.\n *\n * This helper replicates the validation behavior from GadgetExecutor.execute(),\n * making it easy to test gadgets in isolation without setting up a full\n * registry and executor.\n *\n * @param gadget - Gadget instance to test\n * @param params - Raw parameters (before validation)\n * @param options - Test options\n * @returns Promise resolving to test result\n *\n * @example\n * ```typescript\n * import { testGadget } from 'llmist/testing';\n * import { createGadget } from 'llmist';\n * import { z } from 'zod';\n *\n * const calculator = createGadget({\n * description: 'Add numbers',\n * schema: z.object({\n * a: z.number(),\n * b: z.number().default(0),\n * }),\n * execute: ({ a, b }) => String(a + b),\n * });\n *\n * // Test with defaults applied\n * const result = await testGadget(calculator, { a: 5 });\n * expect(result.result).toBe('5');\n * expect(result.validatedParams).toEqual({ a: 5, b: 0 });\n *\n * // Test validation errors\n * const invalid = await testGadget(calculator, { a: 'not a number' });\n * expect(invalid.error).toContain('Invalid parameters');\n *\n * // Test with validation skipped\n * const skipped = await testGadget(calculator, { a: 5 }, { skipValidation: true });\n * expect(skipped.validatedParams).toEqual({ a: 5 }); // No defaults applied\n * ```\n */\nexport async function testGadget(\n gadget: BaseGadget,\n params: Record<string, unknown>,\n options?: TestGadgetOptions,\n): Promise<TestGadgetResult> {\n let validatedParams = params;\n\n // Apply validation if schema exists and not skipped\n if (!options?.skipValidation) {\n const validationResult: ValidationResult = validateGadgetParams(gadget, params);\n\n if (!validationResult.success) {\n return {\n error: validationResult.error,\n validatedParams: params,\n };\n }\n\n validatedParams = validationResult.data;\n }\n\n // Execute the gadget\n try {\n const result = await Promise.resolve(gadget.execute(validatedParams));\n return {\n result,\n validatedParams,\n };\n } catch (error) {\n return {\n error: error instanceof Error ? error.message : String(error),\n validatedParams,\n };\n }\n}\n\n/**\n * Test multiple parameter sets against a gadget.\n *\n * Convenience helper for running the same gadget with different inputs.\n *\n * @param gadget - Gadget instance to test\n * @param paramSets - Array of parameter sets to test\n * @param options - Test options applied to all tests\n * @returns Promise resolving to array of test results\n *\n * @example\n * ```typescript\n * const results = await testGadgetBatch(calculator, [\n * { a: 1, b: 2 },\n * { a: 5 },\n * { a: 'invalid' },\n * ]);\n *\n * expect(results[0].result).toBe('3');\n * expect(results[1].result).toBe('5');\n * expect(results[2].error).toBeDefined();\n * ```\n */\nexport async function testGadgetBatch(\n gadget: BaseGadget,\n paramSets: Record<string, unknown>[],\n options?: TestGadgetOptions,\n): Promise<TestGadgetResult[]> {\n return Promise.all(paramSets.map((params) => testGadget(gadget, params, options)));\n}\n","import type { ILogObj, Logger } from \"tslog\";\nimport { createLogger } from \"../logging/logger.js\";\nimport type {\n MockMatcherContext,\n MockOptions,\n MockRegistration,\n MockResponse,\n MockStats,\n} from \"./mock-types.js\";\n\n/**\n * Global singleton instance for managing LLM mocks.\n * This allows mocks to be registered once and used across the application.\n */\nexport class MockManager {\n private static instance: MockManager | null = null;\n private mocks: Map<string, MockRegistration> = new Map();\n private stats: Map<string, MockStats> = new Map();\n private options: Required<MockOptions>;\n private logger: Logger<ILogObj>;\n private nextId = 1;\n\n private constructor(options: MockOptions = {}) {\n this.options = {\n strictMode: options.strictMode ?? false,\n debug: options.debug ?? false,\n recordStats: options.recordStats ?? true,\n };\n this.logger = createLogger({ name: \"MockManager\", minLevel: this.options.debug ? 2 : 3 });\n }\n\n /**\n * Get the global MockManager instance.\n * Creates one if it doesn't exist.\n */\n static getInstance(options?: MockOptions): MockManager {\n if (!MockManager.instance) {\n MockManager.instance = new MockManager(options);\n } else if (options) {\n // Warn if options are provided after initialization\n console.warn(\n \"MockManager.getInstance() called with options, but instance already exists. \" +\n \"Options are ignored. Use setOptions() to update options or reset() to reinitialize.\",\n );\n }\n return MockManager.instance;\n }\n\n /**\n * Reset the global instance (useful for testing).\n */\n static reset(): void {\n MockManager.instance = null;\n }\n\n /**\n * Register a new mock.\n *\n * @param registration - The mock registration configuration\n * @returns The ID of the registered mock\n *\n * @example\n * const manager = MockManager.getInstance();\n * const mockId = manager.register({\n * label: 'GPT-4 mock',\n * matcher: (ctx) => ctx.modelName.includes('gpt-4'),\n * response: { text: 'Mocked response' }\n * });\n */\n register(registration: Omit<MockRegistration, \"id\"> & { id?: string }): string {\n const id = registration.id ?? `mock-${this.nextId++}`;\n const mock: MockRegistration = {\n id,\n matcher: registration.matcher,\n response: registration.response,\n label: registration.label,\n once: registration.once,\n };\n\n this.mocks.set(id, mock);\n\n if (this.options.recordStats) {\n this.stats.set(id, { matchCount: 0 });\n }\n\n this.logger.debug(\n `Registered mock: ${id}${mock.label ? ` (${mock.label})` : \"\"}${mock.once ? \" [once]\" : \"\"}`,\n );\n\n return id;\n }\n\n /**\n * Unregister a mock by ID.\n */\n unregister(id: string): boolean {\n const deleted = this.mocks.delete(id);\n if (deleted) {\n this.stats.delete(id);\n this.logger.debug(`Unregistered mock: ${id}`);\n }\n return deleted;\n }\n\n /**\n * Clear all registered mocks.\n */\n clear(): void {\n this.mocks.clear();\n this.stats.clear();\n this.logger.debug(\"Cleared all mocks\");\n }\n\n /**\n * Find and return a matching mock for the given context.\n * Returns the mock response if found, null otherwise.\n */\n async findMatch(context: MockMatcherContext): Promise<MockResponse | null> {\n this.logger.debug(\n `Finding match for: ${context.provider}:${context.modelName} (${this.mocks.size} mocks registered)`,\n );\n\n for (const [id, mock] of this.mocks.entries()) {\n let matches = false;\n\n try {\n matches = await Promise.resolve(mock.matcher(context));\n } catch (error) {\n // Matcher errors are caught - a matcher that throws simply doesn't match\n this.logger.warn(`Error in matcher ${id}:`, error);\n // In strict mode, re-throw matcher errors to help catch bugs\n if (this.options.strictMode) {\n throw new Error(`Matcher error in mock ${id}: ${error}`);\n }\n continue; // Skip to next mock\n }\n\n if (matches) {\n this.logger.debug(`Mock matched: ${id}${mock.label ? ` (${mock.label})` : \"\"}`);\n\n // Record stats\n if (this.options.recordStats) {\n const stats = this.stats.get(id);\n if (stats) {\n stats.matchCount++;\n stats.lastUsed = new Date();\n }\n }\n\n // Remove if once\n if (mock.once) {\n this.mocks.delete(id);\n this.stats.delete(id);\n this.logger.debug(`Removed one-time mock: ${id}`);\n }\n\n // Resolve response (could be a function)\n // Response errors are NOT caught - they should propagate to the caller\n const response =\n typeof mock.response === \"function\"\n ? await Promise.resolve(mock.response(context))\n : mock.response;\n\n return response;\n }\n }\n\n // No match found\n this.logger.debug(\"No mock matched\");\n\n if (this.options.strictMode) {\n throw new Error(\n `No mock registered for ${context.provider}:${context.modelName}. ` +\n `Register a mock using MockManager.getInstance().register() or disable strictMode.`,\n );\n }\n\n // Return empty response in non-strict mode\n return {\n text: \"\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n finishReason: \"stop\",\n };\n }\n\n /**\n * Get statistics for a specific mock.\n */\n getStats(id: string): MockStats | undefined {\n return this.stats.get(id);\n }\n\n /**\n * Get all registered mock IDs.\n */\n getMockIds(): string[] {\n return Array.from(this.mocks.keys());\n }\n\n /**\n * Get the number of registered mocks.\n */\n getCount(): number {\n return this.mocks.size;\n }\n\n /**\n * Update the mock manager options.\n */\n setOptions(options: Partial<MockOptions>): void {\n this.options = { ...this.options, ...options };\n this.logger = createLogger({ name: \"MockManager\", minLevel: this.options.debug ? 2 : 3 });\n }\n}\n\n/**\n * Helper function to get the global mock manager instance.\n */\nexport function getMockManager(options?: MockOptions): MockManager {\n return MockManager.getInstance(options);\n}\n","import { GADGET_ARG_PREFIX, GADGET_END_PREFIX, GADGET_START_PREFIX } from \"../core/constants.js\";\nimport type { LLMStream, LLMStreamChunk } from \"../core/options.js\";\nimport type { MockResponse } from \"./mock-types.js\";\n\n/**\n * Utility to sleep for a given duration.\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Generate a unique invocation ID for gadget calls.\n */\nfunction generateInvocationId(): string {\n return `inv-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\n/**\n * Split text into chunks for streaming simulation.\n * Tries to split on word boundaries for more realistic streaming.\n */\nfunction splitIntoChunks(text: string, minChunkSize = 5, maxChunkSize = 30): string[] {\n const chunks: string[] = [];\n let remaining = text;\n\n while (remaining.length > 0) {\n // Determine chunk size\n const chunkSize = Math.min(\n Math.floor(Math.random() * (maxChunkSize - minChunkSize + 1)) + minChunkSize,\n remaining.length,\n );\n\n // Try to split on word boundary\n let chunk: string;\n if (chunkSize < remaining.length) {\n const substr = remaining.substring(0, chunkSize);\n const lastSpace = substr.lastIndexOf(\" \");\n if (lastSpace > minChunkSize / 2) {\n chunk = substr.substring(0, lastSpace + 1);\n } else {\n chunk = substr;\n }\n } else {\n chunk = remaining;\n }\n\n chunks.push(chunk);\n remaining = remaining.substring(chunk.length);\n }\n\n return chunks;\n}\n\n/**\n * Serialize an object to block format parameters with !!!ARG: markers.\n *\n * Example:\n * { operation: \"add\", a: 5, config: { timeout: 30 } }\n * becomes:\n * !!!ARG:operation\n * add\n * !!!ARG:a\n * 5\n * !!!ARG:config/timeout\n * 30\n */\nfunction serializeToBlockFormat(obj: Record<string, unknown>, prefix = \"\"): string {\n let result = \"\";\n\n for (const [key, value] of Object.entries(obj)) {\n const pointer = prefix ? `${prefix}/${key}` : key;\n\n if (value === null || value === undefined) {\n continue;\n }\n\n if (Array.isArray(value)) {\n // Serialize array elements with numeric indices\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n const itemPointer = `${pointer}/${i}`;\n\n if (typeof item === \"object\" && item !== null && !Array.isArray(item)) {\n // Nested object in array\n result += serializeToBlockFormat(item as Record<string, unknown>, itemPointer);\n } else if (Array.isArray(item)) {\n // Nested array - serialize recursively\n for (let j = 0; j < item.length; j++) {\n result += `${GADGET_ARG_PREFIX}${itemPointer}/${j}\\n${String(item[j])}\\n`;\n }\n } else {\n result += `${GADGET_ARG_PREFIX}${itemPointer}\\n${String(item)}\\n`;\n }\n }\n } else if (typeof value === \"object\") {\n // Nested object - recurse\n result += serializeToBlockFormat(value as Record<string, unknown>, pointer);\n } else {\n // Primitive value\n result += `${GADGET_ARG_PREFIX}${pointer}\\n${String(value)}\\n`;\n }\n }\n\n return result;\n}\n\n/**\n * Convert gadget calls in MockResponse to their text representation.\n * Formats them using block format: !!!GADGET_START:name\\n!!!ARG:...\\n!!!GADGET_END\n */\nfunction formatGadgetCalls(gadgetCalls: NonNullable<MockResponse[\"gadgetCalls\"]>): {\n text: string;\n calls: Array<{ name: string; invocationId: string }>;\n} {\n let text = \"\";\n const calls: Array<{ name: string; invocationId: string }> = [];\n\n for (const call of gadgetCalls) {\n const invocationId = call.invocationId ?? generateInvocationId();\n calls.push({ name: call.gadgetName, invocationId });\n\n // Format parameters using block format with !!!ARG: markers\n const blockParams = serializeToBlockFormat(call.parameters);\n\n // Format using the gadget marker format\n text += `\\n${GADGET_START_PREFIX}${call.gadgetName}\\n${blockParams}${GADGET_END_PREFIX}`;\n }\n\n return { text, calls };\n}\n\n/**\n * Create a mock LLM stream from a mock response.\n * This simulates the streaming behavior of real LLM providers.\n *\n * @param response - The mock response configuration\n * @returns An async iterable that yields LLMStreamChunks\n */\nexport async function* createMockStream(response: MockResponse): LLMStream {\n // Initial delay (simulate network latency)\n if (response.delayMs) {\n await sleep(response.delayMs);\n }\n\n const streamDelay = response.streamDelayMs ?? 0;\n let fullText = response.text ?? \"\";\n\n // Add gadget calls to the text if provided\n if (response.gadgetCalls && response.gadgetCalls.length > 0) {\n const { text: gadgetText } = formatGadgetCalls(response.gadgetCalls);\n fullText += gadgetText;\n }\n\n // Stream the text in chunks\n if (fullText.length > 0) {\n const chunks = streamDelay > 0 ? splitIntoChunks(fullText) : [fullText];\n\n for (let i = 0; i < chunks.length; i++) {\n const isLast = i === chunks.length - 1;\n\n const chunk: LLMStreamChunk = {\n text: chunks[i],\n };\n\n // Add finish reason and usage on the last chunk\n if (isLast) {\n if (response.finishReason !== undefined) {\n chunk.finishReason = response.finishReason;\n }\n if (response.usage) {\n chunk.usage = response.usage;\n }\n }\n\n yield chunk;\n\n // Delay between chunks\n if (streamDelay > 0 && !isLast) {\n await sleep(streamDelay);\n }\n }\n } else {\n // Empty response - still yield a final chunk with metadata\n yield {\n text: \"\",\n finishReason: response.finishReason ?? \"stop\",\n usage: response.usage ?? { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n };\n }\n}\n\n/**\n * Create a simple text-only mock stream.\n * Convenience helper for quickly creating mock responses.\n *\n * @param text - The text to stream\n * @param options - Optional streaming configuration\n *\n * @example\n * const stream = createTextMockStream('Hello, world!');\n * for await (const chunk of stream) {\n * console.log(chunk.text);\n * }\n */\nexport function createTextMockStream(\n text: string,\n options?: {\n delayMs?: number;\n streamDelayMs?: number;\n usage?: MockResponse[\"usage\"];\n },\n): LLMStream {\n return createMockStream({\n text,\n delayMs: options?.delayMs,\n streamDelayMs: options?.streamDelayMs,\n usage: options?.usage,\n finishReason: \"stop\",\n });\n}\n","import type { LLMMessage } from \"../core/messages.js\";\nimport type { LLMGenerationOptions, LLMStream, ModelDescriptor } from \"../core/options.js\";\nimport { ModelIdentifierParser } from \"../core/options.js\";\nimport type { ProviderAdapter } from \"../providers/provider.js\";\nimport { getMockManager, type MockManager } from \"./mock-manager.js\";\nimport { createMockStream } from \"./mock-stream.js\";\nimport type { MockMatcherContext, MockOptions } from \"./mock-types.js\";\n\n/**\n * Provider adapter that serves mock responses instead of making real LLM API calls.\n * This is useful for testing applications that use llmist without incurring API costs.\n *\n * The MockProviderAdapter has high priority (100) and is always checked before\n * real providers when both are registered. This enables selective mocking where\n * some models use mocks while others use real providers. If no matching mock is\n * found and strictMode is disabled, requests return an empty response.\n *\n * @example\n * ```typescript\n * import { LLMist, createMockAdapter, mockLLM } from 'llmist/testing';\n *\n * // Use with real providers for selective mocking\n * const client = new LLMist({\n * adapters: [createMockAdapter()],\n * autoDiscoverProviders: true // Also loads real OpenAI, Anthropic, etc.\n * });\n *\n * // Register mocks for specific models\n * mockLLM()\n * .forModel('gpt-5-nano')\n * .returns('Test response')\n * .register();\n *\n * // gpt-5-nano uses mock, other models use real providers\n * const stream = client.stream({\n * model: 'openai:gpt-5-nano',\n * messages: [{ role: 'user', content: 'test' }]\n * });\n * ```\n */\nexport class MockProviderAdapter implements ProviderAdapter {\n readonly providerId = \"mock\";\n readonly priority = 100; // High priority: check mocks before real providers\n private readonly mockManager: MockManager;\n\n constructor(options?: MockOptions) {\n this.mockManager = getMockManager(options);\n }\n\n supports(descriptor: ModelDescriptor): boolean {\n // Support any provider when using mock adapter\n // This allows tests to use \"openai:gpt-4\", \"anthropic:claude\", etc.\n return true;\n }\n\n stream(\n options: LLMGenerationOptions,\n descriptor: ModelDescriptor,\n // spec is unused for mocks\n // biome-ignore lint/correctness/noUnusedVariables: spec parameter required by interface\n spec?: unknown,\n ): LLMStream {\n // Create matcher context\n const context: MockMatcherContext = {\n model: options.model,\n provider: descriptor.provider,\n modelName: descriptor.name,\n options,\n messages: options.messages,\n };\n\n // Find matching mock (async operation)\n // We need to handle this in the stream generator\n return this.createMockStreamFromContext(context);\n }\n\n private async *createMockStreamFromContext(context: MockMatcherContext): LLMStream {\n try {\n // Find matching mock\n const mockResponse = await this.mockManager.findMatch(context);\n\n if (!mockResponse) {\n // This should not happen if MockManager is configured correctly\n // but handle it gracefully\n yield {\n text: \"\",\n finishReason: \"stop\",\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n };\n return;\n }\n\n // Stream the mock response\n yield* createMockStream(mockResponse);\n } catch (error) {\n // If an error occurs (e.g., strictMode with no match), we need to handle it\n throw error;\n }\n }\n}\n\n/**\n * Create a mock provider adapter instance.\n * This is a convenience factory function.\n *\n * @param options - Optional configuration for the mock system\n * @returns A configured MockProviderAdapter\n *\n * @example\n * ```typescript\n * const adapter = createMockAdapter({ strictMode: true, debug: true });\n * const client = new LLMist([adapter]);\n * ```\n */\nexport function createMockAdapter(options?: MockOptions): MockProviderAdapter {\n return new MockProviderAdapter(options);\n}\n","import type { LLMMessage } from \"../core/messages.js\";\nimport { getMockManager } from \"./mock-manager.js\";\nimport type {\n MockMatcher,\n MockMatcherContext,\n MockRegistration,\n MockResponse,\n} from \"./mock-types.js\";\n\n/**\n * Fluent builder for creating mock responses and registrations.\n * Provides a convenient API for common mocking scenarios.\n *\n * @example\n * ```typescript\n * import { mockLLM } from 'llmist';\n *\n * // Simple text mock\n * mockLLM()\n * .forModel('gpt-5')\n * .returns('Hello, world!')\n * .register();\n *\n * // Mock with gadget calls\n * mockLLM()\n * .forProvider('anthropic')\n * .whenMessageContains('calculate')\n * .returnsGadgetCalls([\n * { gadgetName: 'calculator', parameters: { operation: 'add', a: 1, b: 2 } }\n * ])\n * .register();\n *\n * // Complex conditional mock\n * mockLLM()\n * .when((ctx) => ctx.messages.length > 5)\n * .returns('This conversation is getting long!')\n * .once()\n * .register();\n * ```\n */\nexport class MockBuilder {\n private matchers: MockMatcher[] = [];\n private response:\n | MockResponse\n | ((context: MockMatcherContext) => MockResponse | Promise<MockResponse>) = {};\n private label?: string;\n private isOnce = false;\n private id?: string;\n\n /**\n * Match calls to a specific model (by name, supports partial matching).\n *\n * @example\n * mockLLM().forModel('gpt-5')\n * mockLLM().forModel('claude') // matches any Claude model\n */\n forModel(modelName: string): this {\n if (!modelName || modelName.trim() === \"\") {\n throw new Error(\"Model name cannot be empty\");\n }\n this.matchers.push((ctx) => ctx.modelName.includes(modelName));\n return this;\n }\n\n /**\n * Match calls to any model.\n * Useful when you want to mock responses regardless of the model used.\n *\n * @example\n * mockLLM().forAnyModel()\n */\n forAnyModel(): this {\n this.matchers.push(() => true);\n return this;\n }\n\n /**\n * Match calls to a specific provider.\n *\n * @example\n * mockLLM().forProvider('openai')\n * mockLLM().forProvider('anthropic')\n */\n forProvider(provider: string): this {\n if (!provider || provider.trim() === \"\") {\n throw new Error(\"Provider name cannot be empty\");\n }\n this.matchers.push((ctx) => ctx.provider === provider);\n return this;\n }\n\n /**\n * Match calls to any provider.\n * Useful when you want to mock responses regardless of the provider used.\n *\n * @example\n * mockLLM().forAnyProvider()\n */\n forAnyProvider(): this {\n this.matchers.push(() => true);\n return this;\n }\n\n /**\n * Match when any message contains the given text (case-insensitive).\n *\n * @example\n * mockLLM().whenMessageContains('hello')\n */\n whenMessageContains(text: string): this {\n this.matchers.push((ctx) =>\n ctx.messages.some((msg) => msg.content?.toLowerCase().includes(text.toLowerCase())),\n );\n return this;\n }\n\n /**\n * Match when the last message contains the given text (case-insensitive).\n *\n * @example\n * mockLLM().whenLastMessageContains('goodbye')\n */\n whenLastMessageContains(text: string): this {\n this.matchers.push((ctx) => {\n const lastMsg = ctx.messages[ctx.messages.length - 1];\n return lastMsg?.content?.toLowerCase().includes(text.toLowerCase()) ?? false;\n });\n return this;\n }\n\n /**\n * Match when any message matches the given regex.\n *\n * @example\n * mockLLM().whenMessageMatches(/calculate \\d+/)\n */\n whenMessageMatches(regex: RegExp): this {\n this.matchers.push((ctx) => ctx.messages.some((msg) => regex.test(msg.content ?? \"\")));\n return this;\n }\n\n /**\n * Match when a message with a specific role contains text.\n *\n * @example\n * mockLLM().whenRoleContains('system', 'You are a helpful assistant')\n */\n whenRoleContains(role: LLMMessage[\"role\"], text: string): this {\n this.matchers.push((ctx) =>\n ctx.messages.some(\n (msg) => msg.role === role && msg.content?.toLowerCase().includes(text.toLowerCase()),\n ),\n );\n return this;\n }\n\n /**\n * Match based on the number of messages in the conversation.\n *\n * @example\n * mockLLM().whenMessageCount((count) => count > 10)\n */\n whenMessageCount(predicate: (count: number) => boolean): this {\n this.matchers.push((ctx) => predicate(ctx.messages.length));\n return this;\n }\n\n /**\n * Add a custom matcher function.\n * This provides full control over matching logic.\n *\n * @example\n * mockLLM().when((ctx) => {\n * return ctx.options.temperature > 0.8;\n * })\n */\n when(matcher: MockMatcher): this {\n this.matchers.push(matcher);\n return this;\n }\n\n /**\n * Set the text response to return.\n * Can be a static string or a function that returns a string dynamically.\n *\n * @example\n * mockLLM().returns('Hello, world!')\n * mockLLM().returns(() => `Response at ${Date.now()}`)\n * mockLLM().returns((ctx) => `You said: ${ctx.messages[0]?.content}`)\n */\n returns(text: string | ((context: MockMatcherContext) => string | Promise<string>)): this {\n if (typeof text === \"function\") {\n // Convert function to full response generator\n // Use Promise.resolve().then() to properly handle both sync and async errors\n this.response = async (ctx) => {\n const resolvedText = await Promise.resolve().then(() => text(ctx));\n return { text: resolvedText };\n };\n } else {\n if (typeof this.response === \"function\") {\n throw new Error(\"Cannot use returns() after withResponse() with a function\");\n }\n this.response.text = text;\n }\n return this;\n }\n\n /**\n * Set gadget calls to include in the response.\n *\n * @example\n * mockLLM().returnsGadgetCalls([\n * { gadgetName: 'calculator', parameters: { op: 'add', a: 1, b: 2 } }\n * ])\n */\n returnsGadgetCalls(\n calls: Array<{\n gadgetName: string;\n parameters: Record<string, unknown>;\n invocationId?: string;\n }>,\n ): this {\n if (typeof this.response === \"function\") {\n throw new Error(\"Cannot use returnsGadgetCalls() after withResponse() with a function\");\n }\n this.response.gadgetCalls = calls;\n return this;\n }\n\n /**\n * Add a single gadget call to the response.\n *\n * @example\n * mockLLM()\n * .returnsGadgetCall('calculator', { op: 'add', a: 1, b: 2 })\n * .returnsGadgetCall('logger', { message: 'Done!' })\n */\n returnsGadgetCall(gadgetName: string, parameters: Record<string, unknown>): this {\n if (typeof this.response === \"function\") {\n throw new Error(\"Cannot use returnsGadgetCall() after withResponse() with a function\");\n }\n if (!this.response.gadgetCalls) {\n this.response.gadgetCalls = [];\n }\n this.response.gadgetCalls.push({ gadgetName, parameters });\n return this;\n }\n\n /**\n * Set the complete mock response object.\n * This allows full control over all response properties.\n * Can also be a function that generates the response dynamically based on context.\n *\n * @example\n * // Static response\n * mockLLM().withResponse({\n * text: 'Hello',\n * usage: { inputTokens: 10, outputTokens: 5, totalTokens: 15 },\n * finishReason: 'stop'\n * })\n *\n * @example\n * // Dynamic response\n * mockLLM().withResponse((ctx) => ({\n * text: `You said: ${ctx.messages[ctx.messages.length - 1]?.content}`,\n * usage: { inputTokens: 10, outputTokens: 5, totalTokens: 15 }\n * }))\n */\n withResponse(\n response:\n | MockResponse\n | ((context: MockMatcherContext) => MockResponse | Promise<MockResponse>),\n ): this {\n this.response = response;\n return this;\n }\n\n /**\n * Set simulated token usage.\n *\n * @example\n * mockLLM().withUsage({ inputTokens: 100, outputTokens: 50, totalTokens: 150 })\n */\n withUsage(usage: { inputTokens: number; outputTokens: number; totalTokens: number }): this {\n if (typeof this.response === \"function\") {\n throw new Error(\"Cannot use withUsage() after withResponse() with a function\");\n }\n if (usage.inputTokens < 0 || usage.outputTokens < 0 || usage.totalTokens < 0) {\n throw new Error(\"Token counts cannot be negative\");\n }\n if (usage.totalTokens !== usage.inputTokens + usage.outputTokens) {\n throw new Error(\"totalTokens must equal inputTokens + outputTokens\");\n }\n this.response.usage = usage;\n return this;\n }\n\n /**\n * Set the finish reason.\n *\n * @example\n * mockLLM().withFinishReason('stop')\n * mockLLM().withFinishReason('length')\n */\n withFinishReason(reason: string): this {\n if (typeof this.response === \"function\") {\n throw new Error(\"Cannot use withFinishReason() after withResponse() with a function\");\n }\n this.response.finishReason = reason;\n return this;\n }\n\n /**\n * Set initial delay before streaming starts (simulates network latency).\n *\n * @example\n * mockLLM().withDelay(100) // 100ms delay\n */\n withDelay(ms: number): this {\n if (typeof this.response === \"function\") {\n throw new Error(\"Cannot use withDelay() after withResponse() with a function\");\n }\n if (ms < 0) {\n throw new Error(\"Delay must be non-negative\");\n }\n this.response.delayMs = ms;\n return this;\n }\n\n /**\n * Set delay between stream chunks (simulates realistic streaming).\n *\n * @example\n * mockLLM().withStreamDelay(10) // 10ms between chunks\n */\n withStreamDelay(ms: number): this {\n if (typeof this.response === \"function\") {\n throw new Error(\"Cannot use withStreamDelay() after withResponse() with a function\");\n }\n if (ms < 0) {\n throw new Error(\"Stream delay must be non-negative\");\n }\n this.response.streamDelayMs = ms;\n return this;\n }\n\n /**\n * Set a label for this mock (useful for debugging).\n *\n * @example\n * mockLLM().withLabel('greeting mock')\n */\n withLabel(label: string): this {\n this.label = label;\n return this;\n }\n\n /**\n * Set a specific ID for this mock.\n *\n * @example\n * mockLLM().withId('my-custom-mock-id')\n */\n withId(id: string): this {\n this.id = id;\n return this;\n }\n\n /**\n * Mark this mock as one-time use (will be removed after first match).\n *\n * @example\n * mockLLM().once()\n */\n once(): this {\n this.isOnce = true;\n return this;\n }\n\n /**\n * Build the mock registration without registering it.\n * Useful if you want to register it manually later.\n *\n * @returns The built MockRegistration object (without id if not specified)\n */\n build(): Omit<MockRegistration, \"id\"> & { id?: string } {\n // Guard against empty matchers\n if (this.matchers.length === 0) {\n throw new Error(\n \"Mock must have at least one matcher. Use .when(), .forModel(), .forProvider(), etc.\",\n );\n }\n\n // Combine all matchers with AND logic\n const combinedMatcher: MockMatcher = async (ctx) => {\n for (const matcher of this.matchers) {\n const matches = await Promise.resolve(matcher(ctx));\n if (!matches) return false;\n }\n return true;\n };\n\n return {\n id: this.id,\n matcher: combinedMatcher,\n response: this.response,\n label: this.label,\n once: this.isOnce,\n };\n }\n\n /**\n * Register this mock with the global MockManager.\n * Returns the ID of the registered mock.\n *\n * @example\n * const mockId = mockLLM().forModel('gpt-5').returns('Hello!').register();\n * // Later: getMockManager().unregister(mockId);\n */\n register(): string {\n const mockManager = getMockManager();\n const registration = this.build();\n return mockManager.register(registration);\n }\n}\n\n/**\n * Create a new MockBuilder instance.\n * This is the main entry point for the fluent mock API.\n *\n * @example\n * ```typescript\n * import { mockLLM } from 'llmist';\n *\n * mockLLM()\n * .forModel('gpt-5')\n * .whenMessageContains('hello')\n * .returns('Hello there!')\n * .register();\n * ```\n */\nexport function mockLLM(): MockBuilder {\n return new MockBuilder();\n}\n","import { LLMist } from \"../core/client.js\";\nimport { MockProviderAdapter } from \"./mock-adapter.js\";\nimport type { MockOptions } from \"./mock-types.js\";\n\n/**\n * Create a preconfigured LLMist client with mock adapter.\n * This is a convenience function for testing scenarios.\n *\n * @param options - Optional configuration for the mock system\n * @returns A LLMist instance configured to use mocks\n *\n * @example\n * ```typescript\n * import { createMockClient, getMockManager } from 'llmist';\n *\n * // Setup\n * const client = createMockClient({ strictMode: true });\n * const mockManager = getMockManager();\n *\n * // Register mocks\n * mockManager.register({\n * matcher: (ctx) => ctx.modelName === 'gpt-4',\n * response: { text: 'Mocked response' }\n * });\n *\n * // Use in tests\n * const stream = client.stream({\n * model: 'mock:gpt-4',\n * messages: [{ role: 'user', content: 'test' }]\n * });\n * ```\n */\nexport function createMockClient(options?: MockOptions): LLMist {\n return new LLMist({\n adapters: [new MockProviderAdapter(options)],\n autoDiscoverProviders: false,\n defaultProvider: \"mock\",\n });\n}\n","/**\n * Mock gadget utilities for testing.\n *\n * Provides helpers for creating mock gadgets with configurable behavior\n * and call tracking.\n *\n * @module testing/mock-gadget\n */\n\nimport type { ZodType } from \"zod\";\nimport { BaseGadget } from \"../gadgets/gadget.js\";\n\n/**\n * Recorded gadget call for tracking.\n */\nexport interface RecordedCall {\n /** Parameters passed to execute() */\n params: Record<string, unknown>;\n /** When the call was made */\n timestamp: number;\n}\n\n/**\n * Mock gadget with call tracking capabilities.\n */\nexport interface MockGadget extends BaseGadget {\n /** Get all recorded calls */\n getCalls(): RecordedCall[];\n /** Get number of times the gadget was executed */\n getCallCount(): number;\n /** Reset call history */\n resetCalls(): void;\n /** Check if gadget was called with specific params (partial match) */\n wasCalledWith(params: Partial<Record<string, unknown>>): boolean;\n /** Get the last call's parameters */\n getLastCall(): RecordedCall | undefined;\n}\n\n/**\n * Configuration for creating a mock gadget.\n */\nexport interface MockGadgetConfig<TSchema extends ZodType = ZodType> {\n /** Gadget name (required) */\n name: string;\n /** Gadget description */\n description?: string;\n /** Parameter schema */\n schema?: TSchema;\n /** Static result to return */\n result?: string;\n /** Dynamic result based on parameters */\n resultFn?: (params: Record<string, unknown>) => string | Promise<string>;\n /** Error to throw on execution */\n error?: Error | string;\n /** Enable call tracking (default: true) */\n trackCalls?: boolean;\n /** Execution delay in ms */\n delayMs?: number;\n /** Gadget timeout setting */\n timeoutMs?: number;\n}\n\n/**\n * Implementation of MockGadget.\n */\nclass MockGadgetImpl extends BaseGadget implements MockGadget {\n override name: string;\n override description: string;\n override parameterSchema?: ZodType;\n override timeoutMs?: number;\n\n private calls: RecordedCall[] = [];\n private readonly resultValue?: string;\n private readonly resultFn?: (params: Record<string, unknown>) => string | Promise<string>;\n private readonly errorToThrow?: Error;\n private readonly delayMs: number;\n private readonly shouldTrackCalls: boolean;\n\n constructor(config: MockGadgetConfig) {\n super();\n this.name = config.name;\n this.description = config.description ?? `Mock gadget: ${config.name}`;\n this.parameterSchema = config.schema;\n this.resultValue = config.result;\n this.resultFn = config.resultFn;\n this.delayMs = config.delayMs ?? 0;\n this.shouldTrackCalls = config.trackCalls ?? true;\n this.timeoutMs = config.timeoutMs;\n\n if (config.error) {\n this.errorToThrow = typeof config.error === \"string\" ? new Error(config.error) : config.error;\n }\n }\n\n async execute(params: Record<string, unknown>): Promise<string> {\n if (this.shouldTrackCalls) {\n this.calls.push({ params: { ...params }, timestamp: Date.now() });\n }\n\n if (this.delayMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, this.delayMs));\n }\n\n if (this.errorToThrow) {\n throw this.errorToThrow;\n }\n\n if (this.resultFn) {\n return this.resultFn(params);\n }\n\n return this.resultValue ?? \"mock result\";\n }\n\n getCalls(): RecordedCall[] {\n return [...this.calls];\n }\n\n getCallCount(): number {\n return this.calls.length;\n }\n\n resetCalls(): void {\n this.calls = [];\n }\n\n wasCalledWith(params: Partial<Record<string, unknown>>): boolean {\n return this.calls.some((call) =>\n Object.entries(params).every(([key, value]) => call.params[key] === value),\n );\n }\n\n getLastCall(): RecordedCall | undefined {\n return this.calls.length > 0 ? this.calls[this.calls.length - 1] : undefined;\n }\n}\n\n/**\n * Create a mock gadget for testing.\n *\n * @param config - Mock gadget configuration\n * @returns MockGadget instance with call tracking\n *\n * @example\n * ```typescript\n * import { createMockGadget } from 'llmist/testing';\n * import { z } from 'zod';\n *\n * const calculator = createMockGadget({\n * name: 'Calculator',\n * schema: z.object({ a: z.number(), b: z.number() }),\n * resultFn: ({ a, b }) => String(Number(a) + Number(b)),\n * });\n *\n * // Use in tests\n * const registry = new GadgetRegistry();\n * registry.registerByClass(calculator);\n *\n * // After running agent...\n * expect(calculator.getCallCount()).toBe(1);\n * expect(calculator.wasCalledWith({ a: 5 })).toBe(true);\n * ```\n */\nexport function createMockGadget<TSchema extends ZodType>(\n config: MockGadgetConfig<TSchema>,\n): MockGadget {\n return new MockGadgetImpl(config);\n}\n\n/**\n * Fluent builder for creating mock gadgets.\n *\n * @example\n * ```typescript\n * import { mockGadget } from 'llmist/testing';\n * import { z } from 'zod';\n *\n * const mock = mockGadget()\n * .withName('Weather')\n * .withDescription('Get weather for a city')\n * .withSchema(z.object({ city: z.string() }))\n * .returns('Sunny, 72F')\n * .trackCalls()\n * .build();\n *\n * // Or for error testing\n * const errorMock = mockGadget()\n * .withName('Unstable')\n * .throws('Service unavailable')\n * .build();\n * ```\n */\nexport class MockGadgetBuilder {\n private config: MockGadgetConfig = { name: \"MockGadget\" };\n\n /**\n * Set the gadget name.\n */\n withName(name: string): this {\n this.config.name = name;\n return this;\n }\n\n /**\n * Set the gadget description.\n */\n withDescription(description: string): this {\n this.config.description = description;\n return this;\n }\n\n /**\n * Set the parameter schema.\n */\n withSchema<T extends ZodType>(schema: T): MockGadgetBuilder {\n this.config.schema = schema;\n return this;\n }\n\n /**\n * Set a static result to return.\n */\n returns(result: string): this {\n this.config.result = result;\n this.config.resultFn = undefined;\n return this;\n }\n\n /**\n * Set a dynamic result function.\n */\n returnsAsync(resultFn: (params: Record<string, unknown>) => string | Promise<string>): this {\n this.config.resultFn = resultFn;\n this.config.result = undefined;\n return this;\n }\n\n /**\n * Make the gadget throw an error on execution.\n */\n throws(error: Error | string): this {\n this.config.error = error;\n return this;\n }\n\n /**\n * Add execution delay.\n */\n withDelay(ms: number): this {\n this.config.delayMs = ms;\n return this;\n }\n\n /**\n * Set timeout for the gadget.\n */\n withTimeout(ms: number): this {\n this.config.timeoutMs = ms;\n return this;\n }\n\n /**\n * Enable call tracking (enabled by default).\n */\n trackCalls(): this {\n this.config.trackCalls = true;\n return this;\n }\n\n /**\n * Disable call tracking.\n */\n noTracking(): this {\n this.config.trackCalls = false;\n return this;\n }\n\n /**\n * Build the mock gadget.\n */\n build(): MockGadget {\n return createMockGadget(this.config);\n }\n}\n\n/**\n * Create a fluent builder for mock gadgets.\n *\n * @returns New MockGadgetBuilder instance\n *\n * @example\n * ```typescript\n * const mock = mockGadget()\n * .withName('Search')\n * .withSchema(z.object({ query: z.string() }))\n * .returnsAsync(async ({ query }) => {\n * return `Results for: ${query}`;\n * })\n * .build();\n * ```\n */\nexport function mockGadget(): MockGadgetBuilder {\n return new MockGadgetBuilder();\n}\n"],"mappings":"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","names":[]}