UNPKG

@tanstack/ai

Version:

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

102 lines (101 loc) • 4.58 kB
/** * How hard a model thinks. `off` asks for no thinking. The levels are ordered * from least to most, and the clamp rule walks this order. */ export type ReasoningLevel = 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'; /** Every level, from least to most thinking. */ export declare const REASONING_LEVELS: ReadonlyArray<ReasoningLevel>; /** * A model's levels: the provider value to send for each level the model has. * A level with no entry is not supported. */ export type ReasoningLevels = Partial<Record<ReasoningLevel, string>>; /** * What a model supports, at the type level. Adapters declare it per model in * `'~types'.reasoning`. `levels` is a union of the model's levels. `budget` * says whether the model takes a thinking token budget. */ export interface ReasoningCapability { levels: ReasoningLevel; budget: boolean; } /** * The `reasoning` option of `chat()`: a level, or an object. `summary` asks * the provider to stream the thinking text (default `true`). `budgetTokens` * sets an exact thinking budget, on models that take one. */ export type ReasoningOption<TCapability extends ReasoningCapability = ReasoningCapability> = TCapability['levels'] | ({ level: TCapability['levels']; summary?: boolean; } & (true extends TCapability['budget'] ? { budgetTokens?: number; } : { budgetTokens?: never; })); /** The reasoning capability an adapter declares in `'~types'`, or `never`. */ export type AdapterReasoning<TAdapter> = TAdapter extends { '~types': { reasoning?: infer TCapability; }; } ? TCapability : never; /** The `reasoning` option a model's capability allows. `never` for a model that does not reason. */ export type ReasoningOptionFor<TCapability> = [TCapability] extends [never] ? never : TCapability extends ReasoningCapability ? ReasoningOption<TCapability> : never; /** The `reasoning` an adapter gets in `TextOptions`, after `chat()` normalized it. */ export interface ReasoningRequest { level: ReasoningLevel; summary: boolean; budgetTokens?: number; } /** * A model's reasoning data at runtime. `false`: the model does not reason. * Otherwise the levels it has, and whether it takes a token budget. */ export type ModelReasoning = false | { levels: ReasoningLevels; budget: boolean; }; /** * The type-level capability of a model's reasoning data, for an adapter's * `'~types'.reasoning`. Provider packages keep the data in their model meta * `as const`, and derive the levels from it with this type. */ export type ModelReasoningCapability<TReasoning extends { levels: ReasoningLevels; budget: boolean; }> = { levels: keyof TReasoning['levels'] & ReasoningLevel; budget: TReasoning['budget']; }; /** A level or an object, as the user passed it, into the one shape adapters read. */ export declare function normalizeReasoning(option: ReasoningOption | undefined): ReasoningRequest | undefined; /** * The levels a model supports, from least to most thinking: the levels in its * data. A model that does not reason, or has no data, supports only `off`. */ export declare function supportedReasoningLevels(reasoning: ModelReasoning | undefined): ReadonlyArray<ReasoningLevel>; /** * A level the model supports: the level itself, else the nearest supported * level above it, else the nearest below it, else `off`. The same rule as pi. */ export declare function clampReasoningLevel(reasoning: ModelReasoning | undefined, level: ReasoningLevel): ReasoningLevel; /** * pi's thinking budgets for budget-based models. `xhigh` and `max` get the * `high` budget: budget-based models have no higher level. */ export declare const DEFAULT_REASONING_BUDGETS: Readonly<Record<Exclude<ReasoningLevel, 'off'>, number>>; /** The thinking budget for a request: `budgetTokens`, else pi's table. `0` for `off`. */ export declare function reasoningBudget(request: ReasoningRequest): number; /** A request resolved for one model: the clamped level and its provider value. */ export interface ResolvedReasoning { level: ReasoningLevel; /** The provider value to send for `level`. */ value: string; summary: boolean; budgetTokens?: number; } /** * Resolve `request` for a model: clamp the level to the model's levels, and * look up its provider value. `undefined` when there is nothing to send: no * request, or a model that does not reason, has no data, or has no levels. */ export declare function resolveReasoning(request: ReasoningRequest | undefined, reasoning: ModelReasoning | undefined): ResolvedReasoning | undefined;