Update: 2026-05-07 18:32:31
This commit is contained in:
@@ -98,7 +98,7 @@ function detectAudioMimeType(string $path, string $fallback, string $fileName =
|
||||
|
||||
function extractIntentFromAudio(string $base64Audio, string $mimeType, string $apiKey): array
|
||||
{
|
||||
$model = env('GEMINI_VOICE_MODEL', env('GEMINI_MODEL', 'gemini-2.5-flash'));
|
||||
$model = env('GEMINI_VOICE_MODEL', 'gemini-2.5-flash');
|
||||
|
||||
$systemPrompt = <<<PROMPT
|
||||
أنت مساعد أوامر صوتية عربي لمنصة "مُصادَق" للفوترة الأردنية.
|
||||
@@ -159,28 +159,35 @@ PROMPT;
|
||||
],
|
||||
];
|
||||
|
||||
$url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent?key={$apiKey}";
|
||||
$result = callGeminiGenerateContent($model, $payload, $apiKey);
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
|
||||
CURLOPT_TIMEOUT => 45,
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
if ($httpCode !== 200 || !$response) {
|
||||
error_log("Voice Gemini Error: HTTP {$httpCode} | {$error} | {$response}");
|
||||
json_error('فشل تحليل الصوت بواسطة Gemini', 500);
|
||||
// Some Gemini model/API combinations reject JSON mode for multimodal audio.
|
||||
// Retry once with prompt-only JSON enforcement before failing the request.
|
||||
if ($result['http_code'] !== 200 || !$result['body']) {
|
||||
$fallbackPayload = $payload;
|
||||
unset($fallbackPayload['generationConfig']['responseMimeType']);
|
||||
$result = callGeminiGenerateContent($model, $fallbackPayload, $apiKey);
|
||||
}
|
||||
|
||||
$respData = json_decode($response, true);
|
||||
if ($result['http_code'] !== 200 || !$result['body']) {
|
||||
$geminiError = parseGeminiError($result['body']);
|
||||
error_log(
|
||||
"Voice Gemini Error: HTTP {$result['http_code']} | {$result['curl_error']} | {$result['body']}"
|
||||
);
|
||||
|
||||
json_error(
|
||||
'فشل تحليل الصوت بواسطة Gemini: ' . $geminiError['message'],
|
||||
502,
|
||||
[
|
||||
'gemini_http_code' => $result['http_code'],
|
||||
'gemini_status' => $geminiError['status'],
|
||||
'gemini_model' => $model,
|
||||
'audio_mime_type' => $mimeType,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$respData = json_decode($result['body'], true);
|
||||
if (!is_array($respData)) {
|
||||
json_error('تعذر قراءة رد Gemini', 500);
|
||||
}
|
||||
@@ -217,6 +224,52 @@ PROMPT;
|
||||
];
|
||||
}
|
||||
|
||||
function callGeminiGenerateContent(string $model, array $payload, string $apiKey): array
|
||||
{
|
||||
$url = "https://generativelanguage.googleapis.com/v1beta/models/{$model}:generateContent";
|
||||
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_POST => true,
|
||||
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: application/json',
|
||||
'x-goog-api-key: ' . $apiKey,
|
||||
],
|
||||
CURLOPT_TIMEOUT => 45,
|
||||
]);
|
||||
|
||||
$response = curl_exec($ch);
|
||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
|
||||
return [
|
||||
'body' => is_string($response) ? $response : '',
|
||||
'http_code' => (int)$httpCode,
|
||||
'curl_error' => $error ?: '',
|
||||
];
|
||||
}
|
||||
|
||||
function parseGeminiError(string $response): array
|
||||
{
|
||||
$decoded = json_decode($response, true);
|
||||
$error = is_array($decoded) ? ($decoded['error'] ?? null) : null;
|
||||
|
||||
if (is_array($error)) {
|
||||
return [
|
||||
'message' => (string)($error['message'] ?? 'رد غير معروف من Gemini'),
|
||||
'status' => (string)($error['status'] ?? ''),
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'message' => 'رد غير معروف من Gemini',
|
||||
'status' => '',
|
||||
];
|
||||
}
|
||||
|
||||
function decodeModelJson(string $rawText): ?array
|
||||
{
|
||||
$text = trim($rawText);
|
||||
|
||||
Reference in New Issue
Block a user