LetsTryGPT/agent4-implementation
0
1/**2 * Type definitions for LLM API responses3 * Eliminates 'as any' casts and provides type safety4 */5 6/**7 * Standard LLM API response structure (OpenAI-compatible format)8 * Used by: Mistral, DeepSeek, OpenRouter, Codestral9 */10export interface LLMResponse {11 id?: string;12 object?: string;13 created?: number;14 model?: string;15 choices: Array<{16 index?: number;17 message: {18 role: string;19 content: string;20 };21 finish_reason?: string;22 logprobs?: unknown;23 }>;24 usage?: {25 prompt_tokens: number;26 completion_tokens: number;27 total_tokens: number;28 };29}30 31/**32 * Hugging Face API response structure33 */34export interface HuggingFaceResponse {35 generated_text?: string;36 error?: string;37 [key: string]: unknown;38}39 40/**41 * LLM generation options42 */43export interface LLMOptions {44 max_tokens?: number;45 temperature?: number;46 top_p?: number;47 top_k?: number;48 frequency_penalty?: number;49 presence_penalty?: number;50 stop?: string | string[];51 stream?: boolean;52 n?: number;53 logit_bias?: Record<string, number>;54 user?: string;55 [key: string]: unknown; // Allow provider-specific options56}57 58/**59 * Provider configuration60 */61export interface ProviderConfig {62 apiKey: string;63 model: string;64 apiUrl: string;65 timeout?: number;66 maxRetries?: number;67 headers?: Record<string, string>;68}69 70/**71 * Token usage information72 */73export interface TokenUsage {74 promptTokens: number;75 completionTokens: number;76 totalTokens: number;77}78 79/**80 * Response parser utility81 */82export class ResponseParser {83 /**84 * Extract content from standard LLM response85 */86 static extractContent(response: LLMResponse): string {87 return response.choices?.[0]?.message?.content || '';88 }89 90 /**91 * Extract content from Hugging Face response92 */93 static extractHuggingFaceContent(response: HuggingFaceResponse | HuggingFaceResponse[]): string {94 if (Array.isArray(response)) {95 return response[0]?.generated_text || '';96 }97 return response.generated_text || '';98 }99 100 /**101 * Extract token usage from response102 */103 static extractUsage(response: LLMResponse): TokenUsage | null {104 if (!response.usage) {105 return null;106 }107 108 return {109 promptTokens: response.usage.prompt_tokens,110 completionTokens: response.usage.completion_tokens,111 totalTokens: response.usage.total_tokens,112 };113 }114 115 /**116 * Validate response has required fields117 */118 static isValidResponse(response: unknown): response is LLMResponse {119 if (!response || typeof response !== 'object') {120 return false;121 }122 123 const resp = response as Partial<LLMResponse>;124 return (125 Array.isArray(resp.choices) &&126 resp.choices.length > 0 &&127 typeof resp.choices[0]?.message?.content === 'string'128 );129 }130 131 /**132 * Validate Hugging Face response133 */134 static isValidHuggingFaceResponse(response: unknown): response is HuggingFaceResponse {135 if (!response) {136 return false;137 }138 139 if (Array.isArray(response)) {140 return response.length > 0 && typeof response[0]?.generated_text === 'string';141 }142 143 const resp = response as Partial<HuggingFaceResponse>;144 return typeof resp.generated_text === 'string';145 }146}147 148/**149 * Request builder utility150 */151export class RequestBuilder {152 /**153 * Build standard chat completion request154 */155 static buildChatRequest(model: string, prompt: string, options: LLMOptions = {}): object {156 const { max_tokens = 1024, temperature = 0.7, top_p = 1.0, ...otherOptions } = options;157 158 return {159 model,160 messages: [{ role: 'user', content: prompt }],161 max_tokens,162 temperature,163 top_p,164 ...otherOptions,165 };166 }167 168 /**169 * Build Hugging Face request170 */171 static buildHuggingFaceRequest(prompt: string, options: LLMOptions = {}): object {172 const {173 max_tokens = 1024,174 temperature = 0.7,175 top_p = 1.0,176 top_k = 50,177 ...otherOptions178 } = options;179 180 return {181 inputs: prompt,182 parameters: {183 max_new_tokens: max_tokens,184 temperature,185 top_p,186 top_k,187 return_full_text: false,188 ...otherOptions,189 },190 };191 }192}193 