Update: 2026-05-07 18:32:31

This commit is contained in:
Hamza-Ayed
2026-05-07 18:32:31 +03:00
parent 10432e7b81
commit 3cdab9dccc

View File

@@ -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);