First Commit

This commit is contained in:
marco
2026-09-01 07:49:48 -03:00
commit 28b1044038
399 changed files with 41659 additions and 0 deletions
+117
View File
@@ -0,0 +1,117 @@
<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class OpenRouterService
{
public function generateInsight(string $subject, string $userMessage, array $context = []): array
{
$apiKey = config("services.openrouter.api_key");
$model = config("services.openrouter.model", "google/gemini-2.0-flash-exp:free");
// Get language preference from context or default to English
$language = $context['language'] ?? 'en';
unset($context['language']);
// Map language codes to full names
$languageNames = [
'pt_BR' => 'Brazilian Portuguese',
'en' => 'English',
'es' => 'Spanish',
];
$languageName = $languageNames[$language] ?? 'English';
if (!$apiKey) {
return [
"success" => false,
"error" => "OpenRouter API key not configured",
];
}
try {
$systemPrompt = "You are an expert learning assistant for the subject: {$subject}. "
. "Provide insightful, educational content. Be concise and practical.\n\n"
. "CRITICAL LANGUAGE INSTRUCTION - You MUST follow this exactly:\n"
. "Your entire response MUST be written ONLY in {$languageName} ({$language}).\n"
. "Do NOT use any other language. Do NOT include English translations or explanations.\n"
. "If the subject is a language course (like English), you may use that language as examples,\n"
. "but all instructions, explanations, and tips MUST be in {$languageName}.\n"
. "This is mandatory. Start your response directly with the tip in {$languageName}.";
// Append language instruction to user message as well
$userMessageWithLanguage = "[IMPORTANTE: Responda EXCLUSIVAMENTE em {$languageName}. "
. "NÃO use inglês. NÃO traduza. NÃO misture idiomas. "
. "Toda a resposta deve ser APENAS em {$languageName}.]\n\n"
. $userMessage;
$messages = [
["role" => "system", "content" => $systemPrompt],
["role" => "user", "content" => $userMessageWithLanguage],
];
// Add context if provided
if (!empty($context)) {
$contextStr = "Context information:\n";
foreach ($context as $key => $value) {
$contextStr .= "- {$key}: {$value}\n";
}
array_unshift($messages, ["role" => "system", "content" => $contextStr]);
}
$response = Http::withHeaders([
"Authorization" => "Bearer " . $apiKey,
"Content-Type" => "application/json",
"HTTP-Referer" => config("app.url"),
"X-Title" => config("app.name"),
])->timeout(120)->post("https://openrouter.ai/api/v1/chat/completions", [
"model" => $model,
"messages" => $messages,
]);
$data = $response->json();
if (!$data || !isset($data["choices"][0]["message"])) {
$errorMsg = $data["error"]["message"] ?? "Unknown API error";
Log::error("OpenRouter API error response", [
"response" => $data,
"subject" => $subject,
]);
return [
"success" => false,
"error" => $errorMsg,
];
}
$message = $data["choices"][0]["message"];
$content = $message["content"] ?? $message["reasoning"] ?? null;
if ($content) {
return [
"success" => true,
"content" => $content,
"input_tokens" => $data["usage"]["prompt_tokens"] ?? 0,
"output_tokens" => $data["usage"]["completion_tokens"] ?? 0,
];
}
Log::error("OpenRouter API: Empty response content", [
"response" => $data,
"subject" => $subject,
]);
return [
"success" => false,
"error" => "The AI model returned an empty response. Please try again.",
];
} catch (\Exception $e) {
Log::error("OpenRouter API error: " . $e->getMessage());
return [
"success" => false,
"error" => $e->getMessage(),
];
}
}
}