import OpenAI from 'openai'; import { BaseTool } from './tool'; let ovhAI: OpenAI | null = null; function getClient(): OpenAI { if (!ovhAI) { ovhAI = new OpenAI({ apiKey: process.env.OVHCLOUD_API_KEY, baseURL: 'https://oai.endpoints.kepler.ai.cloud.ovh.net/v1' }); } return ovhAI; } const MAX_RETRIES = 3; export async function getMessage( text: string, baseTool: BaseTool ): Promise { const requiredFields = baseTool.input_schema.required ? [...baseTool.input_schema.required] : Object.keys(baseTool.input_schema.properties); let lastError: Error | null = null; for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) { try { console.info(`OVH AI request attempt ${attempt}/${MAX_RETRIES}`); const completion = await getClient().chat.completions.create({ model: 'Meta-Llama-3_3-70B-Instruct', temperature: 0.7, max_tokens: 16000, tools: [ { type: 'function', function: { name: baseTool.name, description: baseTool.input_schema.description || '', parameters: { type: 'object', properties: baseTool.input_schema.properties, required: requiredFields } } } ], tool_choice: { type: 'function', function: { name: baseTool.name } }, messages: [ { role: 'system', content: `You are a professional tech journalist creating newsletter content. CRITICAL REQUIREMENTS: 1. You MUST call the function with ALL required fields populated 2. Required fields: ${requiredFields.join(', ')} 3. Every field must be fully populated with high-quality content 4. Do NOT leave any field as null, undefined, or empty` }, { role: 'user', content: text } ] }); const message = completion.choices[0]?.message; if (!message?.tool_calls || message.tool_calls.length === 0) { throw new Error('No function call found in response'); } const toolCall = message.tool_calls[0]; if (toolCall.function.name !== baseTool.name) { throw new Error( `Expected tool ${baseTool.name} but got ${toolCall.function.name}` ); } const result = JSON.parse(toolCall.function.arguments); console.info('OVH AI response:', result); return result as T; } catch (error) { console.error(`Attempt ${attempt} failed:`, error); lastError = error as Error; if (attempt < MAX_RETRIES) { const delay = 1000 * attempt; console.info(`Retrying in ${delay}ms...`); await new Promise(resolve => setTimeout(resolve, delay)); } } } console.error('All retry attempts failed'); throw lastError || new Error('OVH AI Endpoints client error.'); }