config['key'] ?? null; if (! $key) { return ['success' => false, 'error' => 'API Key not configured.']; } $model = $options['model'] ?? $this->config['default_model'] ?? 'gpt-4o'; $instruction = $options['instruction'] ?? $this->config['instruction'] ?? ''; $startTime = microtime(true); try { $res = Http::withToken($key) ->timeout(60) ->post('https://api.openai.com/v1/chat/completions', [ 'model' => $model, 'messages' => [ ['role' => 'system', 'content' => $instruction], ['role' => 'user', 'content' => $prompt], ], 'temperature' => (float) ($options['temperature'] ?? $this->config['temperature'] ?? 0.7), 'max_tokens' => (int) ($options['max_tokens'] ?? $this->config['max_tokens'] ?? 2000), ]); if ($res->failed()) { $error = $res->json()['error']['message'] ?? 'OpenAI Error'; $this->logUsage([ 'model' => $model, 'prompt' => $prompt, 'status' => 'failed', 'error' => $error, ]); return ['success' => false, 'error' => $error]; } $data = $res->json(); $response = $data['choices'][0]['message']['content']; $usage = $data['usage'] ?? []; $result = [ 'success' => true, 'response' => $response, 'usage' => $usage, 'model' => $model, 'latency' => microtime(true) - $startTime, ]; $this->logUsage([ 'model' => $model, 'prompt' => $prompt, 'response' => $response, 'usage' => $usage, 'status' => 'success', 'metadata' => ['latency' => $result['latency']], ]); return $result; } catch (\Exception $e) { return ['success' => false, 'error' => $e->getMessage()]; } } protected function calculateCost(array $data): float { $model = $data['model'] ?? ''; $promptTokens = $data['usage']['prompt_tokens'] ?? 0; $completionTokens = $data['usage']['completion_tokens'] ?? 0; // Simplified estimation $rates = [ 'gpt-4o' => ['prompt' => 0.005 / 1000, 'completion' => 0.015 / 1000], 'gpt-4-turbo' => ['prompt' => 0.01 / 1000, 'completion' => 0.03 / 1000], 'gpt-3.5-turbo' => ['prompt' => 0.0005 / 1000, 'completion' => 0.0015 / 1000], ]; $rate = $rates[$model] ?? $rates['gpt-4o']; return ($promptTokens * $rate['prompt']) + ($completionTokens * $rate['completion']); } }