UNPKG

@llumiverse/drivers

Version:

LLM driver implementations. Currently supported are: openai, huggingface, bedrock, replicate.

127 lines 6.98 kB
import { AbstractDriver, AIModel, Completion, CompletionChunkObject, DataSource, DriverOptions, EmbeddingsOptions, EmbeddingsResult, ExecutionOptions, LlumiverseError, LlumiverseErrorContext, Providers, ToolUse, TrainingJob, TrainingOptions, TrainingPromptOptions } from "@llumiverse/core"; import OpenAI, { AzureOpenAI } from "openai"; type ResponseInputItem = OpenAI.Responses.ResponseInputItem; export interface BaseOpenAIDriverOptions extends DriverOptions { } export declare abstract class BaseOpenAIDriver extends AbstractDriver<BaseOpenAIDriverOptions, ResponseInputItem[]> { abstract provider: Providers.openai | Providers.azure_openai | Providers.xai | Providers.azure_foundry | Providers.openai_compatible; abstract service: OpenAI | AzureOpenAI; constructor(opts: BaseOpenAIDriverOptions); extractDataFromResponse(_options: ExecutionOptions, result: OpenAI.Responses.Response): Completion; requestTextCompletionStream(prompt: ResponseInputItem[], options: ExecutionOptions): Promise<AsyncIterable<CompletionChunkObject>>; requestTextCompletion(prompt: ResponseInputItem[], options: ExecutionOptions): Promise<Completion>; protected canStream(_options: ExecutionOptions): Promise<boolean>; /** * Build conversation context after streaming completion. * Reconstructs the assistant message from accumulated results and applies stripping. */ buildStreamingConversation(prompt: ResponseInputItem[], result: unknown[], toolUse: unknown[] | undefined, options: ExecutionOptions): ResponseInputItem[] | undefined; createTrainingPrompt(options: TrainingPromptOptions): Promise<string>; startTraining(dataset: DataSource, options: TrainingOptions): Promise<TrainingJob>; cancelTraining(jobId: string): Promise<TrainingJob>; getTrainingJob(jobId: string): Promise<TrainingJob>; validateConnection(): Promise<boolean>; listTrainableModels(): Promise<AIModel<string>[]>; listModels(): Promise<AIModel[]>; _listModels(filter?: (m: OpenAI.Models.Model) => boolean): Promise<AIModel[]>; generateEmbeddings({ text, image, model }: EmbeddingsOptions): Promise<EmbeddingsResult>; imageModels: string[]; /** * Determine if a model is specifically an image generation model (not conversational image model) */ isImageModel(model: string): boolean; /** * Request image generation from standalone Images API * Supports: DALL-E 2, DALL-E 3, GPT-image models (for edit/variation) */ requestImageGeneration(prompt: ResponseInputItem[], options: ExecutionOptions): Promise<Completion>; /** * Format OpenAI API errors into LlumiverseError with proper status codes and retryability. * * OpenAI API errors have a specific structure: * - APIError.status: HTTP status code (400, 401, 403, 404, 409, 422, 429, 500+) * - APIError.error: Error object with type, message, param, code * - APIError.requestID: Request ID for support * - APIError.code: Error code (e.g., 'invalid_api_key', 'rate_limit_exceeded') * - APIError.param: Parameter that caused the error (optional) * - APIError.type: Error type (optional) * * Common error types: * - BadRequestError (400): Invalid request parameters * - AuthenticationError (401): Invalid API key * - PermissionDeniedError (403): Insufficient permissions * - NotFoundError (404): Resource not found * - ConflictError (409): Resource conflict * - UnprocessableEntityError (422): Validation error * - RateLimitError (429): Rate limit exceeded * - InternalServerError (500+): Server-side errors * - APIConnectionError: Connection issues (no status code) * - APIConnectionTimeoutError: Request timeout (no status code) * - LengthFinishReasonError: Response truncated due to length * - ContentFilterFinishReasonError: Content filtered * * This implementation works for: * - OpenAI API * - Azure OpenAI * - xAI (uses OpenAI-compatible API) * - Azure Foundry (OpenAI-compatible) * - Other OpenAI-compatible APIs * * @see https://platform.openai.com/docs/guides/error-codes */ formatLlumiverseError(error: unknown, context: LlumiverseErrorContext): LlumiverseError; /** * Type guard to check if error is an OpenAI API error or OpenAI-specific error. */ private isOpenAIApiError; /** * Determine if an OpenAI API error is retryable. * * Retryable errors: * - RateLimitError (429): Rate limit exceeded, retry with backoff * - InternalServerError (500+): Server-side errors * - APIConnectionTimeoutError: Request timeout * - Error codes: 'timeout', 'server_error', 'service_unavailable' * - Status codes: 408, 429, 502, 503, 504, 529, 5xx * * Non-retryable errors: * - BadRequestError (400): Invalid request parameters * - AuthenticationError (401): Invalid API key * - PermissionDeniedError (403): Insufficient permissions * - NotFoundError (404): Resource not found * - ConflictError (409): Resource conflict * - UnprocessableEntityError (422): Validation error * - LengthFinishReasonError: Length limit reached * - ContentFilterFinishReasonError: Content filtered * - Error codes: 'invalid_api_key', 'invalid_request_error', 'model_not_found' * - Other 4xx client errors * * @param error - The error object * @param httpStatusCode - The HTTP status code if available * @param errorCode - The error code if available * @param errorType - The error type if available * @returns True if retryable, false if not retryable, undefined if unknown */ private isOpenAIErrorRetryable; } export declare function mapResponseStream(stream: AsyncIterable<OpenAI.Responses.ResponseStreamEvent>): AsyncIterable<CompletionChunkObject>; /** * Converts function_call and function_call_output items to text messages in OpenAI conversation. * Preserves tool call information while removing structured items that require * tools to be defined in the API request. */ export declare function convertOpenAIFunctionItemsToText(items: ResponseInputItem[]): ResponseInputItem[]; export declare function collectTools(output?: OpenAI.Responses.ResponseOutputItem[]): ToolUse[] | undefined; /** * Fix orphaned function_call items in the OpenAI Responses API conversation. * * When an agent is stopped mid-tool-execution, the conversation may contain * function_call items without matching function_call_output items. The OpenAI * Responses API requires every function_call to have a matching function_call_output. * * This function detects such cases and injects synthetic function_call_output items * indicating the tools were interrupted, allowing the conversation to continue. */ export declare function fixOrphanedToolUse(items: ResponseInputItem[]): ResponseInputItem[]; export {}; //# sourceMappingURL=index.d.ts.map