97 lines
3.2 KiB
PHP
97 lines
3.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services\AI;
|
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
class GptProvider extends BaseAiProvider
|
|
{
|
|
public function getIdentifier(): string
|
|
{
|
|
return 'gpt';
|
|
}
|
|
|
|
public function generate(string $prompt, array $options = []): array
|
|
{
|
|
$key = $options['key'] ?? $this->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']);
|
|
}
|
|
}
|