diff --git a/src/types/index.ts b/src/types/index.ts index c3d650f..0a4314e 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -22,7 +22,7 @@ export interface AIProviderConfig { /** * Message role types supported by AI providers */ -export type MessageRole = 'system' | 'user' | 'assistant'; +export type MessageRole = "system" | "user" | "assistant"; /** * Individual message in a conversation @@ -122,13 +122,13 @@ export interface CompletionChunk { * Error types that can occur during AI operations */ export enum AIErrorType { - AUTHENTICATION = 'authentication', - RATE_LIMIT = 'rate_limit', - INVALID_REQUEST = 'invalid_request', - MODEL_NOT_FOUND = 'model_not_found', - NETWORK = 'network', - TIMEOUT = 'timeout', - UNKNOWN = 'unknown' + AUTHENTICATION = "authentication", + RATE_LIMIT = "rate_limit", + INVALID_REQUEST = "invalid_request", + MODEL_NOT_FOUND = "model_not_found", + NETWORK = "network", + TIMEOUT = "timeout", + UNKNOWN = "unknown", } /** @@ -139,10 +139,10 @@ export class AIProviderError extends Error { message: string, public type: AIErrorType, public statusCode?: number, - public originalError?: Error + public originalError?: Error, ) { super(message); - this.name = 'AIProviderError'; + this.name = "AIProviderError"; } } @@ -164,18 +164,18 @@ export interface ProviderInfo { capabilities?: Record; } -// ============================================================================ +// ============================================================================ // RESPONSE TYPE UTILITIES -// ============================================================================ +// ============================================================================ /** * Creates a response type definition for structured AI outputs - * + * * @param description - Human-readable description of the expected format * @param example - Optional example of the expected response structure * @param strictJson - Whether to enforce strict JSON formatting (default: true) * @returns ResponseType object for use in completion requests - * + * * @example * ```typescript * const userType = createResponseType( @@ -192,51 +192,58 @@ export interface ProviderInfo { export function createResponseType( description: string, example?: T, - strictJson: boolean = true + strictJson: boolean = true, ): ResponseType { return { description, example, - strictJson + strictJson, }; } /** * Generates a system prompt instruction for structured output based on response type - * + * * @param responseType - The response type definition * @returns Formatted system prompt instruction */ export function generateResponseTypePrompt(responseType: ResponseType): string { const { typeDefinition, description, example, strictJson } = responseType; - - let prompt = 'You are an AI assistant that must respond with a JSON object.'; + + let prompt = "You are an AI assistant that must respond with a JSON object."; if (typeDefinition) { - prompt += ' The JSON object must strictly adhere to the following TypeScript type definition:\n\n'; - prompt += 'Type Definition:\n```typescript\n' + typeDefinition + '\n```\n\n'; + prompt += + " The JSON object must strictly adhere to the following TypeScript type definition:\n\n"; + prompt += + "Type Definition:\n```typescript\n" + typeDefinition + "\n```\n\n"; } else { - prompt += '\n\n'; + prompt += "\n\n"; } - - prompt += 'Description: ' + description + '\n\n'; - + + prompt += "Description: " + description + "\n\n"; + if (example) { - prompt += 'Example of the expected JSON output:\n```json\n' + JSON.stringify(example, null, 2) + '\n```\n\n'; + prompt += + "Example of the expected JSON output:\n```json\n" + + JSON.stringify(example, null, 2) + + "\n```\n\n"; } - + if (strictJson) { - prompt += 'IMPORTANT: Your entire response must be a single, valid JSON object. Do not include any additional text, explanations, or markdown formatting before or after the JSON object.'; + prompt += + "IMPORTANT: Your entire response must be a single, valid JSON object. Do not include any additional text, explanations, or markdown formatting before or after the JSON object."; } else { - prompt += 'Your response should contain a JSON object that follows the structure defined above.'; + prompt += + "Your response should contain a JSON object that follows the structure defined above."; } - + return prompt; } /** * Parses and validates that a response matches the expected type structure - * + * * @param response - The response content to validate * @param responseType - The expected response type * @returns The parsed and validated data object @@ -244,22 +251,24 @@ export function generateResponseTypePrompt(responseType: ResponseType): string { */ export function parseAndValidateResponseType( response: string, - responseType: ResponseType + responseType: ResponseType, ): T { try { // Attempt to parse the JSON response - const parsed = JSON.parse(response); - + const parsed = JSON.parse( + response.replaceAll("```json", "").replaceAll("```", ""), + ); + // Basic validation: ensure it's a non-null object. // For more robust validation, a library like Zod or Ajv could be used // based on the typeDefinition, but that's beyond the current scope. - if (typeof parsed !== 'object' || parsed === null) { - throw new Error('Response must be a JSON object'); + if (typeof parsed !== "object" || parsed === null) { + throw new Error("Response must be a JSON object"); } - + // Here you could add more sophisticated validation if needed, e.g., // checking keys against the responseType.typeDefinition - + return parsed as T; } catch (error) { // Wrap parsing/validation errors in a standardized AIProviderError @@ -267,7 +276,7 @@ export function parseAndValidateResponseType( `Failed to parse or validate structured response: ${(error as Error).message}`, AIErrorType.INVALID_REQUEST, undefined, - error as Error + error as Error, ); } }