UNPKG

ai-functions

Version:

Core AI primitives for building intelligent applications

442 lines 14.2 kB
/** * BatchQueue - Deferred execution queue for batch processing * * Collects AI operations and submits them to provider batch APIs * for cost-effective processing (typically 50% discount, 24hr turnaround). * * @example * ```ts * // Create a batch queue * const batch = createBatch({ provider: 'openai' }) * * // Add items to the batch (these are deferred, not executed) * const titles = await list`10 blog post titles about startups` * const posts = titles.map(title => batch.add(write`blog post about ${title}`)) * * // Submit the batch - returns job info * const job = await batch.submit() * console.log(job.id) // batch_abc123 * * // Poll for results or use webhook * const results = await batch.wait() * ``` * * @packageDocumentation */ import type { FunctionOptions } from './template.js'; import type { SimpleSchema } from './schema.js'; import { type BatchTier } from 'language-models'; /** * Batch processing mode * * - `sync`: Process synchronously (blocking) * - `async`: Process asynchronously (non-blocking) * - `background`: Process in background (fire and forget) */ export type BatchMode = 'sync' | 'async' | 'background'; /** * Supported batch providers * * - `openai`: OpenAI Batch API with 50% discount, up to 24hr turnaround * - `anthropic`: Anthropic Message Batches API * - `google`: Google AI batch processing * - `bedrock`: AWS Bedrock batch inference * - `cloudflare`: Cloudflare Workers AI batch processing */ export type BatchProvider = 'openai' | 'anthropic' | 'google' | 'bedrock' | 'cloudflare'; /** * Status of a batch job * * Lifecycle: pending -> validating -> in_progress -> finalizing -> completed * Error states: failed, expired, cancelled * Cancel states: cancelling -> cancelled */ export type BatchStatus = 'pending' | 'validating' | 'in_progress' | 'finalizing' | 'completed' | 'failed' | 'expired' | 'cancelling' | 'cancelled'; /** * Individual item in a batch * * Represents a single prompt/request within a batch job. Each item has its own * ID, prompt, optional schema, and tracks its own completion status and result. * * @typeParam T - The expected result type for this item */ export interface BatchItem<T = unknown> { /** Unique ID for this item */ id: string; /** The prompt to process */ prompt: string; /** Schema for structured output */ schema?: SimpleSchema; /** Generation options */ options?: FunctionOptions; /** Custom metadata */ metadata?: Record<string, unknown>; /** Resolved value (after completion) */ result?: T; /** Error if failed */ error?: string; /** Status of this item */ status: 'pending' | 'completed' | 'failed'; } /** * Batch job information * * Contains metadata about a submitted batch job including its status, * progress, and timing information. Used to track and manage batch jobs. */ export interface BatchJob { /** Unique batch ID */ id: string; /** Provider this batch was submitted to */ provider: BatchProvider; /** Current status */ status: BatchStatus; /** Number of items in the batch */ totalItems: number; /** Number of completed items */ completedItems: number; /** Number of failed items */ failedItems: number; /** When the batch was created */ createdAt: Date; /** When the batch started processing */ startedAt?: Date; /** When the batch completed */ completedAt?: Date; /** Expected completion time */ expiresAt?: Date; /** Webhook URL for completion notification */ webhookUrl?: string; /** Input file ID (for OpenAI) */ inputFileId?: string; /** Output file ID (for OpenAI) */ outputFileId?: string; /** Error file ID (for OpenAI) */ errorFileId?: string; } /** * Result of a batch submission * * Returned when a batch is submitted to the provider. Contains the job * information and a promise that resolves when the batch completes. */ export interface BatchSubmitResult { job: BatchJob; /** Promise that resolves when batch is complete */ completion: Promise<BatchResult[]>; } /** * Result of a single item in the batch * * Contains the outcome of processing a single item including success/failure * status, result data, and token usage information. * * @typeParam T - The type of the result data */ export interface BatchResult<T = unknown> { /** Item ID */ id: string; /** Custom ID if provided */ customId?: string; /** Status */ status: 'completed' | 'failed'; /** The result (if successful) */ result?: T; /** Error message (if failed) */ error?: string; /** Token usage */ usage?: { promptTokens: number; completionTokens: number; totalTokens: number; }; } /** * Options for creating a batch queue * * Configure the batch queue behavior including provider selection, * model, webhook notifications, and auto-submission thresholds. */ export interface BatchQueueOptions { /** Provider to use for batch processing */ provider?: BatchProvider; /** Model to use */ model?: string; /** Webhook URL for completion notification */ webhookUrl?: string; /** Custom metadata for the batch */ metadata?: Record<string, unknown>; /** Maximum items per batch (provider-specific limits) */ maxItems?: number; /** Auto-submit when queue reaches maxItems */ autoSubmit?: boolean; } /** * Event handler type for BatchQueue events */ export type BatchEventHandler<T = unknown> = (data: T) => void; /** * BatchQueue collects AI operations for deferred batch execution */ export declare class BatchQueue { private items; private options; private idCounter; private submitted; private job; private _autoSubmitPromise; private _submissionError; private _eventHandlers; constructor(options?: BatchQueueOptions); /** * Subscribe to batch events * @param event - Event name ('error', 'partial-failure', 'complete') * @param handler - Event handler function */ on<T = unknown>(event: string, handler: BatchEventHandler<T>): void; /** * Unsubscribe from batch events */ off(event: string, handler: BatchEventHandler): void; /** * Emit an event to all subscribed handlers */ private emit; /** * Get the auto-submit promise (if auto-submit was triggered) */ get autoSubmitPromise(): Promise<void> | undefined; /** * Get the last submission error (if any) */ get submissionError(): Error | undefined; /** * Check if there was a submission error */ get hasSubmissionError(): boolean; /** * Await auto-submit completion or failure * Returns a promise that resolves when auto-submit completes or rejects on error */ awaitAutoSubmit(): Promise<void>; /** * Get items that failed during batch processing */ getFailedItems(): BatchItem[]; /** * Retry a failed submission * Only available after a failed auto-submit */ retry(): Promise<BatchSubmitResult>; /** * Add an item to the batch queue * Returns a placeholder that will be resolved after batch completion */ add<T = unknown>(prompt: string, options?: { schema?: SimpleSchema; options?: FunctionOptions; customId?: string; metadata?: Record<string, unknown>; }): BatchItem<T>; /** * Get all items in the queue */ getItems(): BatchItem[]; /** * Get the number of items in the queue */ get size(): number; /** * Check if the batch has been submitted */ get isSubmitted(): boolean; /** * Get the batch job info (after submission) */ getJob(): BatchJob | null; /** * Submit the batch to the provider */ submit(): Promise<BatchSubmitResult>; /** * Cancel the batch (if supported by provider) */ cancel(): Promise<void>; /** * Get the current status of the batch */ getStatus(): Promise<BatchJob>; /** * Wait for the batch to complete and return results */ wait(pollInterval?: number): Promise<BatchResult[]>; } /** * Interface for provider-specific batch implementations * * Implement this interface to add support for a new batch processing provider. * Each provider (OpenAI, Anthropic, etc.) has its own adapter implementation. */ export interface BatchAdapter { /** Submit a batch to the provider */ submit(items: BatchItem[], options: BatchQueueOptions): Promise<BatchSubmitResult>; /** Get the status of a batch */ getStatus(batchId: string): Promise<BatchJob>; /** Cancel a batch */ cancel(batchId: string): Promise<void>; /** Get results of a completed batch */ getResults(batchId: string): Promise<BatchResult[]>; /** Wait for batch completion */ waitForCompletion(batchId: string, pollInterval?: number): Promise<BatchResult[]>; } /** * Interface for flex processing (faster than batch, ~50% discount) * * Flex processing provides the same cost savings as batch processing * but with faster turnaround (minutes instead of hours). * Currently available for OpenAI and AWS Bedrock only. */ export interface FlexAdapter { /** * Submit items for flex processing * Flex is faster than batch (minutes vs hours) but has same discount * * @param items - Items to process * @param options - Processing options * @returns Results (resolves when all items complete) */ submitFlex(items: BatchItem[], options: { model?: string; }): Promise<BatchResult[]>; } /** * Register a batch adapter for a provider * * Call this to register a custom batch adapter for a provider. * This is typically done by provider-specific packages. * * @param provider - The provider to register the adapter for * @param adapter - The batch adapter implementation * * @example * ```ts * import { registerBatchAdapter } from 'ai-functions' * import { OpenAIBatchAdapter } from './openai-adapter' * * registerBatchAdapter('openai', new OpenAIBatchAdapter()) * ``` */ export declare function registerBatchAdapter(provider: BatchProvider, adapter: BatchAdapter): void; /** * Register a flex adapter for a provider * * Flex adapters provide faster-than-batch processing with the same cost savings. * Only OpenAI and AWS Bedrock currently support flex processing. * * @param provider - The provider to register the adapter for * @param adapter - The flex adapter implementation */ export declare function registerFlexAdapter(provider: BatchProvider, adapter: FlexAdapter): void; /** * Get the batch adapter for a provider * * @param provider - The provider to get the adapter for * @returns The registered batch adapter * @throws Error if no adapter is registered for the provider */ export declare function getBatchAdapter(provider: BatchProvider): BatchAdapter; /** * Get the flex adapter for a provider * * @param provider - The provider to get the adapter for * @returns The registered flex adapter * @throws Error if no flex adapter is registered (flex not supported by provider) */ export declare function getFlexAdapter(provider: BatchProvider): FlexAdapter; /** * Check if flex processing is available for a provider * * @param provider - The provider to check * @returns true if flex adapter is registered, false otherwise */ export declare function hasFlexAdapter(provider: BatchProvider): boolean; /** * List the batch tiers a model is eligible for. * * Reads `ModelPolicy.batchTier` from `language-models` — this is the per-model * policy data, distinct from the runtime adapter registration above. * * @example * ```ts * tiersForModel('sonnet') // ['immediate', 'batch'] * tiersForModel('gpt-4o') // ['immediate', 'flex', 'batch'] * ``` */ export declare function tiersForModel(alias: string): BatchTier[]; /** * Check whether a model is eligible for a given tier. */ export declare function modelSupportsTier(alias: string, tier: BatchTier): boolean; /** * Create a new batch queue * * @example * ```ts * const batch = createBatch({ provider: 'openai' }) * batch.add('Write a poem about cats') * batch.add('Write a poem about dogs') * const { job } = await batch.submit() * const results = await batch.wait() * ``` */ export declare function createBatch(options?: BatchQueueOptions): BatchQueue; /** * Execute operations in batch mode * * @example * ```ts * const results = await withBatch(async (batch) => { * const titles = ['TypeScript', 'React', 'Next.js'] * return titles.map(title => batch.add(`Write a blog post about ${title}`)) * }) * ``` */ export declare function withBatch<T>(fn: (batch: BatchQueue) => T[] | Promise<T[]>, options?: BatchQueueOptions): Promise<BatchResult<T>[]>; /** * Symbol to mark an AIPromise as batched/deferred * * Used internally to identify promises that should be processed via batch API. */ export declare const BATCH_MODE_SYMBOL: unique symbol; /** * Options for deferred execution * * Extends FunctionOptions with batch-specific settings. */ export interface DeferredOptions extends FunctionOptions { /** Batch queue to add to */ batch?: BatchQueue; /** Custom ID for this item in the batch */ customId?: string; } /** * Check if we're in batch mode * * @param options - Options that may contain a batch queue * @returns true if a batch queue is present in options */ export declare function isBatchMode(options?: DeferredOptions): boolean; /** * Add an operation to the batch queue instead of executing immediately * * @typeParam T - The expected result type * @param batch - The batch queue to add to * @param prompt - The prompt to process * @param schema - Optional schema for structured output * @param options - Additional options including custom ID * @returns A BatchItem that will be resolved when the batch completes */ export declare function deferToBatch<T>(batch: BatchQueue, prompt: string, schema: SimpleSchema | undefined, options?: FunctionOptions & { customId?: string; }): BatchItem<T>; //# sourceMappingURL=batch-queue.d.ts.map