Middleware API
Full API reference for built-in middleware.
logging(opts?)
Log stream lifecycle events to the console.
function logging(opts?: {
level?: 'debug' | 'info'; // default: 'info'
filter?: (event: StreamEvent) => boolean;
logger?: Pick<Console, 'log' | 'warn' | 'error'>;
}): Middleware;'info'level logs start, complete, and error events.'debug'level logs every event.filterlets you suppress specific event types from logging.
validateSchema(schema)
Incremental Zod validation for structured output.
function validateSchema<T>(schema: ZodType<T>): Middleware;Emits object-delta events that populate partialObject during streaming. Validates the final result against the full schema on completion, setting object.
throttle(ms)
Rate-limits text-delta and thinking-delta events.
function throttle(ms: number): Middleware;Non-delta events (tool calls, usage, finish) pass through immediately. Flushes any buffered delta on stream completion.
persist(storage, chatId?)
Saves messages to a storage adapter on stream completion.
function persist(storage: StorageAdapter, chatId?: string): Middleware;Use restoreChat(), listChats(), and deleteChat() from @store-ai/core to manage persisted data.
retryOn(opts)
Automatically retry on transient errors.
function retryOn(opts: {
maxRetries: number;
delay: number; // milliseconds between retries
filter?: (error: Error) => boolean; // only retry matching errors
}): Middleware;Suppresses error events when retries remain. Resets the retry counter on success or when the filter rejects an error.
trackCost(pricing)
Calculate token costs from usage events.
function trackCost(pricing: {
inputCostPer1k: number;
outputCostPer1k: number;
reasoningCostPer1k?: number; // defaults to outputCostPer1k
}): Middleware;After a usage event, cost is available via ctx.metadata.get('cost') returning a CostInfo object:
interface CostInfo {
inputCost: number;
outputCost: number;
reasoningCost: number;
totalCost: number;
}mapEvents(fn)
Transform or filter stream events.
function mapEvents(fn: (event: StreamEvent) => StreamEvent | null): Middleware;Return the event (possibly modified) to pass it through. Return null to suppress it.
Custom Middleware Types
type MiddlewareFn = (ctx: MiddlewareContext, next: () => Promise<void>) => Promise<void> | void;
interface MiddlewareObject {
name?: string;
onStart?(ctx: { state: AIState; store: AIStore }): void | Promise<void>;
onEvent?: MiddlewareFn;
onComplete?(ctx: { state: AIState; store: AIStore }): void | Promise<void>;
onError?(error: Error, ctx: { state: AIState; store: AIStore }): void | Promise<void>;
onAbort?(ctx: { state: AIState; store: AIStore }): void | Promise<void>;
}
type Middleware = MiddlewareFn | MiddlewareObject;
interface MiddlewareContext {
event: StreamEvent;
state: Readonly<AIState>;
store: AIStore;
metadata: Map<string, unknown>;
}