import type { PromptResult, StreamChunk, Result } from "smoltalk"; import type { EmbedConfig, EmbedResult, ImageConfig, ImageGenResult, ImageInput, LLMClient, PromptConfig } from "./llmClient.js"; export type ReturnMock = { return: any; /** Milliseconds this mock "generates" before returning, honoring the * request's abort signal like a real provider: if the signal fires * mid-delay, the mock rejects with the signal's reason (or a plain * abort Error), which is exactly how a cancelled in-flight request * surfaces. Lets fixtures exercise mid-request cancellation — e.g. a * time guard tripping while a request is out — deterministically: * the only timing requirement is limit << delayMs. */ delayMs?: number; }; export type ToolCallMock = { toolCall: { name: string; args?: Record; }; }; /** Multi-tool variant: simulate the LLM returning multiple tool calls in * one round (used to test concurrent tool execution in `runPrompt`). * * `id` is optional: when omitted a synthetic `mock-tool-*` id is used. * Pass `id: ""` to reproduce providers (notably Google Gemini) whose * function-calling protocol returns no tool-call id — smoltalk defaults * the missing id to "". */ export type MultiToolCallMock = { toolCalls: Array<{ name: string; args?: Record; id?: string; }>; }; export type LLMMock = ReturnMock | ToolCallMock | MultiToolCallMock; /** * Per-agent mock queues. Keys are matched against the executing module: * the exact module id ("lib/agents/optimize/mutatePrompt.agency"), then its * basename without the extension ("mutatePrompt"), then the "*" fallback * queue. Each queue is consumed in order, independently of the others, * so tests that span several agents (e.g. a full optimize iteration: * task agent + mutator + judge) don't have to predict the global * interleaving of llm() calls. */ export type ScopedLLMMocks = Record; export declare class DeterministicClient implements LLMClient { private queues; /** Array form: one anonymous queue, original error messages. */ private readonly scoped; constructor(mocks: LLMMock[] | ScopedLLMMocks); /** * Picks the mock queue for the currently-executing module. The module * id comes from the ALS frame's callsite (seeded by `Runner.runInScope` * for every step body); outside any frame — or when no scope matches — * the "*" queue applies. */ private resolveQueue; text(config: PromptConfig): Promise>; textStream(config: PromptConfig): AsyncGenerator; embed(_input: string | string[], _config?: Partial): Promise>; image(_input: ImageInput, _config?: Partial): Promise>; }