UNPKG

@tanstack/ai

Version:

Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.

92 lines (91 loc) • 3.82 kB
import { BaseTextAdapter, StructuredOutputOptions, StructuredOutputResult } from '../activities/chat/adapter.js'; import { AdapterYieldChunk } from '../utilities/adapter-yield-chunk.js'; import { DefaultMessageMetadataByModality, Modality, TextOptions } from '../types.js'; /** One scripted answer of the fake model. */ export interface FakeResponse { /** The visible text. */ text?: string; /** Thinking text, streamed before the answer. */ thinking?: string; /** * Tool calls. `id` defaults to `fake-call-<fake>-<call>-<index>`, unique * across fakes. */ toolCalls?: Array<{ name: string; input?: unknown; id?: string; }>; /** Default: `'tool_calls'` when there are tool calls, else `'stop'`. */ finishReason?: 'stop' | 'length' | 'content_filter' | 'tool_calls'; /** Fail the call with a `RUN_ERROR` that has this message. */ error?: string; } /** Counters of a fake adapter. */ export interface FakeTextState { /** How many model calls the fake answered. */ callCount: number; } /** A scripted answer, or a function that builds one from the request. */ export type FakeResponseStep = FakeResponse | ((call: { request: TextOptions; state: FakeTextState; }) => FakeResponse | Promise<FakeResponse>); export interface FakeTextOptions<TModel extends string> { /** The model id. Default `'fake-model'`. */ model?: TModel; /** The model's context window in tokens. Data for the caller. */ contextWindow?: number; /** Stream the text at this many tokens (4 characters each) per second. */ tokensPerSecond?: number; /** * Estimate prompt caching per `threadId`: the part of the request that * matches the thread's previous request counts as cached. */ cache?: boolean; } /** * A text adapter that answers from a script. Use it to test `chat()`, tools, * and middleware with no network and no API key. Create it with `fakeText()`. */ export declare class FakeTextAdapter<TModel extends string> extends BaseTextAdapter<TModel, Record<string, unknown>, ReadonlyArray<Modality>, DefaultMessageMetadataByModality> { readonly name = "fake"; /** The context window from the options. */ readonly contextWindow: number | undefined; readonly state: FakeTextState; private queue; private readonly previousRequests; private readonly options; private readonly instance; constructor(model: TModel, options: FakeTextOptions<TModel>); /** Replace the queue of answers. */ setResponses(responses: Array<FakeResponseStep>): void; /** Add answers to the end of the queue. */ appendResponses(responses: Array<FakeResponseStep>): void; /** How many answers are still queued. */ pendingResponses(): number; private nextResponse; private usage; private pace; chatStream(options: TextOptions): AsyncIterable<AdapterYieldChunk>; /** Answers with the next queued response. Its `text` must be JSON. */ structuredOutput(options: StructuredOutputOptions<Record<string, unknown>>): Promise<StructuredOutputResult<unknown>>; } /** * Create a scripted fake text adapter for tests. Queue answers with * `setResponses`, then pass the fake to `chat()` as its adapter. * * - An empty queue answers with a `RUN_ERROR`: "No more fake responses queued". * - Usage is estimated as `ceil(characters / 4)` over the request and the * answer, so a long message can overflow a small `contextWindow`. * * @example * ```ts * const fake = fakeText() * fake.setResponses([{ text: 'Hello' }]) * for await (const chunk of chat({ adapter: fake, messages })) { * // ... * } * ``` */ export declare function fakeText<const TModel extends string = 'fake-model'>(options?: FakeTextOptions<TModel>): FakeTextAdapter<TModel>;