UNPKG

@tanstack/ai

Version:

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

161 lines (160 loc) 5.89 kB
import { InternalLogger } from '../../logger/internal-logger.js'; import { TokenUsage } from '../../types.js'; /** * Configuration for evaluate adapter instances. */ export interface EvaluateAdapterConfig { apiKey?: string; baseUrl?: string; timeout?: number; headers?: Record<string, string>; } /** * Shared JSON value for `state` and question `instructions`. * A JSON array is one value, not a batch. */ export type EvaluateJsonValue = string | object | Array<unknown>; /** Content the model judges. A JSON array is one state, not a batch. */ export type EvaluateState = EvaluateJsonValue; /** Question text. Matches TypeSafe: string, object, or array. */ export type EvaluateInstructions = EvaluateJsonValue; /** * TypeSafe choice question on the adapter wire. * * Generic parameters: * - TOptions: option key to description (or `null` when the key is enough) */ export interface WireChoiceQuestion<TOptions extends Record<string, string | null> = Record<string, string | null>> { type: 'choice'; instructions: EvaluateInstructions; criteria: TOptions; } /** * TypeSafe score question on the adapter wire. * * Generic parameters: * - TLevels: ordered level labels, at least two */ export interface WireScoreQuestion<TLevels extends ReadonlyArray<string> = ReadonlyArray<string>> { type: 'score'; instructions: EvaluateInstructions; criteria: TLevels; } /** * TypeSafe yes/no question on the adapter wire. * Public helpers call this `boolean`. The wire type is `noul`. */ export interface WireNoulQuestion { type: 'noul'; instructions: EvaluateInstructions; criteria?: { true?: string; false?: string; }; } /** Question payload adapters send to the provider. */ export type WireQuestion = WireChoiceQuestion | WireScoreQuestion | WireNoulQuestion; /** TypeSafe choice answer. Adapters do not invent a public `.value`. */ export interface WireChoiceAnswer { type: 'choice'; choice: string; probabilities: Record<string, number>; confidence: number; } /** TypeSafe score answer. `score` is the raw fraction. */ export interface WireScoreAnswer { type: 'score'; score: number; legend: Record<string, string>; probabilities: Record<string, number>; confidence: number; } /** TypeSafe yes/no answer. `noul` is P(true). */ export interface WireNoulAnswer { type: 'noul'; noul: number; } /** Provider payload for one question. The activity maps this to a unified answer. */ export type WireAnswer = WireChoiceAnswer | WireScoreAnswer | WireNoulAnswer; /** * Options passed to {@link EvaluateAdapter.evaluate}. */ export interface EvaluateOptions<TProviderOptions extends object = Record<string, unknown>> { model: string; /** Shared state every question judges. A JSON array is one state, not a batch. */ state: EvaluateState; /** TypeSafe wire questions, keyed by the caller's question ids. */ questions: Record<string, WireQuestion>; /** Provider-specific options forwarded by `decide()`. */ modelOptions?: TProviderOptions; /** Forwarded to the provider request for cancellation. */ abortSignal?: AbortSignal; /** * Internal logger threaded from `decide()`. Adapters must call * `logger.request()` before the provider call and `logger.errors()` in catch * blocks. */ logger: InternalLogger; } /** * Provider-level evaluate result. Adapters return the wire payload plus usage. * The activity maps answers to the unified public shape. */ export interface EvaluateAdapterResult { /** Resolved model id from the provider. */ model: string; answers: Record<string, WireAnswer>; usage: TokenUsage; } /** * Evaluate adapter interface with pre-resolved generics. * * An adapter is created by a provider function: `provider('model')` → `adapter`. * All type resolution happens at the provider call site, not in this interface. * * Generic parameters: * - TModel: The specific model name (e.g. `'jev-latest'`) * - TProviderOptions: Provider-specific options (already resolved) */ export interface EvaluateAdapter<TModel extends string = string, TProviderOptions extends object = Record<string, unknown>> { /** Discriminator for adapter kind */ readonly kind: 'evaluate'; /** Adapter name identifier */ readonly name: string; /** The model this adapter is configured for */ readonly model: TModel; /** * @internal Type-only properties for inference. Not assigned at runtime. */ '~types': { providerOptions: TProviderOptions; }; /** * Evaluate typed questions against `state`. Return the provider payload. * Do not invent unified `.value` fields. The activity maps wire answers. */ evaluate: (options: EvaluateOptions<TProviderOptions>) => Promise<EvaluateAdapterResult>; } /** * An EvaluateAdapter with any/unknown type parameters. * Useful as a constraint in generic functions and interfaces. */ export type AnyEvaluateAdapter = EvaluateAdapter<any, any>; /** * Abstract base class for evaluate adapters. * Extend this class to implement an evaluate adapter for a specific provider. * * Generic parameters match EvaluateAdapter. The provider function resolves them. */ export declare abstract class BaseEvaluateAdapter<TModel extends string = string, TProviderOptions extends object = Record<string, unknown>> implements EvaluateAdapter<TModel, TProviderOptions> { readonly kind: "evaluate"; abstract readonly name: string; readonly model: TModel; '~types': { providerOptions: TProviderOptions; }; protected config: EvaluateAdapterConfig; constructor(config: EvaluateAdapterConfig | undefined, model: TModel); abstract evaluate(options: EvaluateOptions<TProviderOptions>): Promise<EvaluateAdapterResult>; protected generateId(): string; }