@llumiverse/drivers
Version:
LLM driver implementations. Currently supported are: openai, huggingface, bedrock, replicate.
127 lines • 6.98 kB
TypeScript
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