diff --git a/hesabixCore/src/Controller/AdminController.php b/hesabixCore/src/Controller/AdminController.php index 26414b7a..070bc01d 100644 --- a/hesabixCore/src/Controller/AdminController.php +++ b/hesabixCore/src/Controller/AdminController.php @@ -459,6 +459,17 @@ class AdminController extends AbstractController $resp['cardToShebaFee'] = $registryMGR->get('system', key: 'cardToShebaFee'); $resp['enableAccountToSheba'] = $registryMGR->get('system', key: 'enableAccountToSheba'); $resp['accountToShebaFee'] = $registryMGR->get('system', key: 'accountToShebaFee'); + + // تنظیمات جادوگر هوش مصنوعی + $resp['aiEnabled'] = $registryMGR->get('system', key: 'aiEnabled'); + $resp['aiAgentSource'] = $registryMGR->get('system', key: 'aiAgentSource'); + $resp['aiModel'] = $registryMGR->get('system', key: 'aiModel'); + $resp['aiApiKey'] = $registryMGR->get('system', key: 'aiApiKey'); + $resp['localModelAddress'] = $registryMGR->get('system', key: 'localModelAddress'); + $resp['inputTokenPrice'] = $registryMGR->get('system', key: 'inputTokenPrice'); + $resp['outputTokenPrice'] = $registryMGR->get('system', key: 'outputTokenPrice'); + $resp['aiPrompt'] = $registryMGR->get('system', key: 'aiPrompt'); + return $this->json($resp); } @@ -492,6 +503,25 @@ class AdminController extends AbstractController $registryMGR->update('system', 'cardToShebaFee', $params['cardToShebaFee']); $registryMGR->update('system', 'enableAccountToSheba', $params['enableAccountToSheba']); $registryMGR->update('system', 'accountToShebaFee', $params['accountToShebaFee']); + + // ذخیره تنظیمات جادوگر هوش مصنوعی + if (array_key_exists('aiEnabled', $params)) + $registryMGR->update('system', 'aiEnabled', $params['aiEnabled']); + if (array_key_exists('aiAgentSource', $params)) + $registryMGR->update('system', 'aiAgentSource', $params['aiAgentSource']); + if (array_key_exists('aiModel', $params)) + $registryMGR->update('system', 'aiModel', $params['aiModel']); + if (array_key_exists('aiApiKey', $params)) + $registryMGR->update('system', 'aiApiKey', $params['aiApiKey']); + if (array_key_exists('localModelAddress', $params)) + $registryMGR->update('system', 'localModelAddress', $params['localModelAddress']); + if (array_key_exists('inputTokenPrice', $params)) + $registryMGR->update('system', 'inputTokenPrice', $params['inputTokenPrice']); + if (array_key_exists('outputTokenPrice', $params)) + $registryMGR->update('system', 'outputTokenPrice', $params['outputTokenPrice']); + if (array_key_exists('aiPrompt', $params)) + $registryMGR->update('system', 'aiPrompt', $params['aiPrompt']); + $entityManager->persist($item); $entityManager->flush(); return $this->json(['result' => 1]); diff --git a/hesabixCore/src/Controller/wizardController.php b/hesabixCore/src/Controller/wizardController.php new file mode 100644 index 00000000..e8309dc8 --- /dev/null +++ b/hesabixCore/src/Controller/wizardController.php @@ -0,0 +1,192 @@ +aiService = $aiService; + } + + #[Route('/api/wizard/talk', name: 'wizard_talk', methods: ['POST'])] + public function wizard_talk(Request $request): JsonResponse + { + try { + $params = json_decode($request->getContent(), true) ?? []; + + if (!isset($params['message']) || empty($params['message'])) { + return $this->json([ + 'success' => false, + 'error' => 'پیام الزامی است' + ]); + } + + $message = $params['message']; + $options = $params['options'] ?? []; + + // بررسی فعال بودن هوش مصنوعی + if (!$this->aiService->isAIEnabled()) { + return $this->json([ + 'success' => false, + 'error' => 'سرویس هوش مصنوعی غیرفعال است' + ]); + } + + // ارسال درخواست به سرویس هوش مصنوعی + $result = $this->aiService->sendRequest($message, $options); + + if ($result['success']) { + $response = [ + 'success' => true, + 'response' => $result['response'], + 'model' => $result['model'] ?? null, + 'usage' => $result['usage'] ?? null + ]; + + // محاسبه هزینه در صورت وجود اطلاعات usage + if (isset($result['usage'])) { + $cost = $this->aiService->calculateCost($result['usage']); + $response['cost'] = $cost; + } + + return $this->json($response); + } else { + return $this->json([ + 'success' => false, + 'error' => $result['error'] + ]); + } + + } catch (\Exception $e) { + return $this->json([ + 'success' => false, + 'error' => 'خطا در پردازش درخواست: ' . $e->getMessage() + ]); + } + } + + #[Route('/api/wizard/status', name: 'wizard_status', methods: ['GET'])] + public function wizard_status(): JsonResponse + { + try { + $isEnabled = $this->aiService->isAIEnabled(); + $agentSource = $this->aiService->getAIAgentSource(); + $model = $this->aiService->getAIModel(); + $apiKey = $this->aiService->getAIApiKey(); + + // بررسی وضعیت کامل + $status = 'available'; + $message = 'سرویس هوش مصنوعی در دسترس است'; + + if (!$isEnabled) { + $status = 'disabled'; + $message = 'سرویس هوش مصنوعی غیرفعال است'; + } elseif (empty($apiKey)) { + $status = 'no_api_key'; + $message = 'کلید API تنظیم نشده است'; + } + + return $this->json([ + 'success' => true, + 'status' => $status, + 'agent_source' => $agentSource, + 'model' => $model, + 'message' => $message, + 'debug_info' => [ + 'ai_enabled' => $isEnabled, + 'has_api_key' => !empty($apiKey), + 'agent_source' => $agentSource, + 'model' => $model + ] + ]); + } catch (\Exception $e) { + return $this->json([ + 'success' => false, + 'error' => 'خطا در بررسی وضعیت: ' . $e->getMessage() + ]); + } + } + + #[Route('/api/wizard/models', name: 'wizard_models', methods: ['GET'])] + public function wizard_models(): JsonResponse + { + try { + $agentSource = $this->aiService->getAIAgentSource(); + $currentModel = $this->aiService->getAIModel(); + + // لیست مدل‌های موجود بر اساس منبع ایجنت + $models = []; + + switch ($agentSource) { + case 'gapgpt': + $models = [ + 'gpt-4o' => 'GPT-4 Omni', + 'gpt-4-turbo' => 'GPT-4 Turbo', + 'gpt-3.5-turbo' => 'GPT-3.5 Turbo', + 'claude-3-opus' => 'Claude 3 Opus', + 'claude-3-sonnet' => 'Claude 3 Sonnet', + 'gemini-pro' => 'Gemini Pro' + ]; + break; + case 'avalai': + $models = [ + 'gpt-4' => 'GPT-4', + 'gpt-3.5-turbo' => 'GPT-3.5 Turbo', + 'claude-3' => 'Claude 3', + 'gemini-pro' => 'Gemini Pro' + ]; + break; + case 'local': + $models = [ + 'local-model' => 'مدل لوکال', + 'custom-model' => 'مدل سفارشی' + ]; + break; + } + + return $this->json([ + 'success' => true, + 'models' => $models, + 'current_model' => $currentModel, + 'agent_source' => $agentSource + ]); + } catch (\Exception $e) { + return $this->json([ + 'success' => false, + 'error' => 'خطا در دریافت مدل‌ها: ' . $e->getMessage() + ]); + } + } + + #[Route('/api/wizard/settings', name: 'wizard_settings', methods: ['GET'])] + public function wizard_settings(): JsonResponse + { + try { + return $this->json([ + 'success' => true, + 'settings' => [ + 'aiEnabled' => $this->aiService->isAIEnabled(), + 'aiAgentSource' => $this->aiService->getAIAgentSource(), + 'aiModel' => $this->aiService->getAIModel(), + 'inputTokenPrice' => $this->aiService->getInputTokenPrice(), + 'outputTokenPrice' => $this->aiService->getOutputTokenPrice(), + 'aiPrompt' => $this->aiService->getAIPrompt() + ] + ]); + } catch (\Exception $e) { + return $this->json([ + 'success' => false, + 'error' => 'خطا در دریافت تنظیمات: ' . $e->getMessage() + ]); + } + } +} diff --git a/hesabixCore/src/Service/AIService.php b/hesabixCore/src/Service/AIService.php new file mode 100644 index 00000000..8076b210 --- /dev/null +++ b/hesabixCore/src/Service/AIService.php @@ -0,0 +1,377 @@ +registryMGR = $registryMGR; + } + + /** + * ارسال درخواست به سرویس هوش مصنوعی + */ + public function sendRequest(string $message, array $options = []): array + { + try { + // بررسی فعال بودن هوش مصنوعی + if (!$this->isAIEnabled()) { + return [ + 'success' => false, + 'error' => 'سرویس هوش مصنوعی غیرفعال است' + ]; + } + + // ترکیب پرامپ با پیام کاربر + $enhancedMessage = $this->combinePromptWithMessage($message); + + $agentSource = $this->getAIAgentSource(); + + switch ($agentSource) { + case 'gapgpt': + return $this->sendToGapGPT($enhancedMessage, $options); + case 'avalai': + return $this->sendToAvalAI($enhancedMessage, $options); + case 'local': + return $this->sendToLocalModel($enhancedMessage, $options); + default: + return [ + 'success' => false, + 'error' => 'سرویس هوش مصنوعی نامعتبر است' + ]; + } + } catch (Exception $e) { + return [ + 'success' => false, + 'error' => 'خطا در ارتباط با سرویس هوش مصنوعی: ' . $e->getMessage() + ]; + } + } + + /** + * ترکیب پرامپ با پیام کاربر + */ + private function combinePromptWithMessage(string $message): string + { + $prompt = $this->getAIPrompt(); + + if (empty($prompt)) { + return $message; + } + + // اگر پرامپ وجود دارد، آن را با پیام کاربر ترکیب کن + return $prompt . "\n\nسوال کاربر: " . $message; + } + + /** + * ارسال درخواست به GapGPT + */ + private function sendToGapGPT(string $message, array $options = []): array + { + $apiKey = $this->getAIApiKey(); + if (empty($apiKey)) { + return [ + 'success' => false, + 'error' => 'کلید API GapGPT تنظیم نشده است' + ]; + } + + $url = 'https://api.gapgpt.app/v1/chat/completions'; + $model = $options['model'] ?? $this->getAIModel(); + + $data = [ + 'model' => $model, + 'messages' => [ + [ + 'role' => 'user', + 'content' => $message + ] + ] + ]; + + // اضافه کردن تنظیمات اختیاری + if (isset($options['temperature'])) { + $data['temperature'] = $options['temperature']; + } + if (isset($options['max_tokens'])) { + $data['max_tokens'] = $options['max_tokens']; + } + + $headers = [ + 'Content-Type: application/json', + 'Authorization: Bearer ' . $apiKey + ]; + + $response = $this->makeHttpRequest($url, $data, $headers); + + if ($response['success']) { + return [ + 'success' => true, + 'response' => $response['data']['choices'][0]['message']['content'] ?? '', + 'usage' => $response['data']['usage'] ?? null, + 'model' => $response['data']['model'] ?? $model + ]; + } + + return [ + 'success' => false, + 'error' => $response['error'] ?? 'خطا در ارتباط با GapGPT' + ]; + } + + /** + * ارسال درخواست به AvalAI + */ + private function sendToAvalAI(string $message, array $options = []): array + { + $apiKey = $this->getAIApiKey(); + if (empty($apiKey)) { + return [ + 'success' => false, + 'error' => 'کلید API AvalAI تنظیم نشده است' + ]; + } + + $url = 'https://api.avalai.ir/v1/chat/completions'; + $model = $options['model'] ?? $this->getAIModel(); + + $data = [ + 'model' => $model, + 'messages' => [ + [ + 'role' => 'user', + 'content' => $message + ] + ] + ]; + + // اضافه کردن تنظیمات اختیاری + if (isset($options['temperature'])) { + $data['temperature'] = $options['temperature']; + } + if (isset($options['max_tokens'])) { + $data['max_tokens'] = $options['max_tokens']; + } + + $headers = [ + 'Content-Type: application/json', + 'Authorization: Bearer ' . $apiKey + ]; + + $response = $this->makeHttpRequest($url, $data, $headers); + + if ($response['success']) { + return [ + 'success' => true, + 'response' => $response['data']['choices'][0]['message']['content'] ?? '', + 'usage' => $response['data']['usage'] ?? null, + 'model' => $response['data']['model'] ?? $model + ]; + } + + return [ + 'success' => false, + 'error' => $response['error'] ?? 'خطا در ارتباط با AvalAI' + ]; + } + + /** + * ارسال درخواست به مدل لوکال + */ + private function sendToLocalModel(string $message, array $options = []): array + { + $localAddress = $this->getLocalModelAddress(); + if (empty($localAddress)) { + return [ + 'success' => false, + 'error' => 'آدرس مدل لوکال تنظیم نشده است' + ]; + } + + $url = rtrim($localAddress, '/') . '/v1/chat/completions'; + $model = $options['model'] ?? 'local-model'; + + $data = [ + 'model' => $model, + 'messages' => [ + [ + 'role' => 'user', + 'content' => $message + ] + ] + ]; + + // اضافه کردن تنظیمات اختیاری + if (isset($options['temperature'])) { + $data['temperature'] = $options['temperature']; + } + if (isset($options['max_tokens'])) { + $data['max_tokens'] = $options['max_tokens']; + } + + $headers = [ + 'Content-Type: application/json' + ]; + + // اضافه کردن کلید API در صورت وجود + $apiKey = $this->getAIApiKey(); + if (!empty($apiKey)) { + $headers[] = 'Authorization: Bearer ' . $apiKey; + } + + $response = $this->makeHttpRequest($url, $data, $headers); + + if ($response['success']) { + return [ + 'success' => true, + 'response' => $response['data']['choices'][0]['message']['content'] ?? '', + 'usage' => $response['data']['usage'] ?? null, + 'model' => $response['data']['model'] ?? $model + ]; + } + + return [ + 'success' => false, + 'error' => $response['error'] ?? 'خطا در ارتباط با مدل لوکال' + ]; + } + + /** + * انجام درخواست HTTP + */ + private function makeHttpRequest(string $url, array $data, array $headers): array + { + $ch = curl_init(); + + curl_setopt_array($ch, [ + CURLOPT_URL => $url, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => json_encode($data), + CURLOPT_HTTPHEADER => $headers, + CURLOPT_TIMEOUT => 30, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_FOLLOWLOCATION => true + ]); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $error = curl_error($ch); + curl_close($ch); + + if ($error) { + return [ + 'success' => false, + 'error' => 'خطا در cURL: ' . $error + ]; + } + + if ($httpCode !== 200) { + return [ + 'success' => false, + 'error' => 'خطای HTTP: ' . $httpCode . ' - ' . $response + ]; + } + + $responseData = json_decode($response, true); + if (json_last_error() !== JSON_ERROR_NONE) { + return [ + 'success' => false, + 'error' => 'خطا در پردازش پاسخ JSON' + ]; + } + + return [ + 'success' => true, + 'data' => $responseData + ]; + } + + /** + * بررسی فعال بودن هوش مصنوعی + */ + public function isAIEnabled(): bool + { + return $this->registryMGR->get('system', 'aiEnabled') === '1'; + } + + /** + * دریافت منبع ایجنت هوش مصنوعی + */ + public function getAIAgentSource(): string + { + return $this->registryMGR->get('system', 'aiAgentSource') ?: 'gapgpt'; + } + + /** + * دریافت مدل هوش مصنوعی + */ + public function getAIModel(): string + { + return $this->registryMGR->get('system', 'aiModel') ?: 'gpt-4o'; + } + + /** + * دریافت کلید API هوش مصنوعی + */ + public function getAIApiKey(): string + { + return $this->registryMGR->get('system', 'aiApiKey') ?: ''; + } + + /** + * دریافت آدرس مدل لوکال + */ + public function getLocalModelAddress(): string + { + return $this->registryMGR->get('system', 'localModelAddress') ?: ''; + } + + /** + * دریافت قیمت توکن ورودی + */ + public function getInputTokenPrice(): float + { + return (float) ($this->registryMGR->get('system', 'inputTokenPrice') ?: 0); + } + + /** + * دریافت قیمت توکن خروجی + */ + public function getOutputTokenPrice(): float + { + return (float) ($this->registryMGR->get('system', 'outputTokenPrice') ?: 0); + } + + /** + * دریافت پرامپ هوش مصنوعی + */ + public function getAIPrompt(): string + { + return $this->registryMGR->get('system', 'aiPrompt') ?: ''; + } + + /** + * محاسبه هزینه بر اساس تعداد توکن‌ها + */ + public function calculateCost(array $usage): float + { + $inputTokenPrice = (float) ($this->registryMGR->get('system', 'inputTokenPrice') ?: 0); + $outputTokenPrice = (float) ($this->registryMGR->get('system', 'outputTokenPrice') ?: 0); + + $inputTokens = $usage['prompt_tokens'] ?? 0; + $outputTokens = $usage['completion_tokens'] ?? 0; + + $inputCost = ($inputTokens / 1000) * $inputTokenPrice; + $outputCost = ($outputTokens / 1000) * $outputTokenPrice; + + return $inputCost + $outputCost; + } +} \ No newline at end of file diff --git a/webUI/src/views/user/manager/settings/system.vue b/webUI/src/views/user/manager/settings/system.vue index b8e2ac6f..85ab44e9 100644 --- a/webUI/src/views/user/manager/settings/system.vue +++ b/webUI/src/views/user/manager/settings/system.vue @@ -11,7 +11,8 @@ export default defineComponent({ tabs: [ { title: 'تنظیمات پایه', icon: 'mdi-cog' }, { title: 'درگاه‌های پرداخت', icon: 'mdi-credit-card' }, - { title: 'پنل استعلامات', icon: 'mdi-magnify' } + { title: 'پنل استعلامات', icon: 'mdi-magnify' }, + { title: 'جادوگر هوش مصنوعی', icon: 'mdi-robot' } ], gatepays: [ { @@ -62,6 +63,79 @@ export default defineComponent({ accountToShebaFee: 0, }, loading: true, + // افزودن ایجنت‌های هوش مصنوعی + aiEnabled: true, + aiAgentSource: 'gapgpt', + aiModel: 'gpt-4o', + aiApiKey: '', + showApiKey: false, + localModelAddress: '', + inputTokenPrice: 0, + outputTokenPrice: 0, + aiPrompt: '', + aiAgentSources: [ + { title: 'GapGPT', value: 'gapgpt', subtitle: 'gapgpt.app' }, + { title: 'AvalAI', value: 'avalai', subtitle: 'avalai.ir' }, + { title: 'مدل لوکال', value: 'local', subtitle: 'local' }, + ], + aiModels: [ + // OpenAI Models + { title: 'GPT-4 Omni', value: 'gpt-4o', subtitle: 'OpenAI - $2.50/$1.25/$10.00', provider: 'OpenAI' }, + { title: 'GPT-4.5 Preview', value: 'gpt-4.5-preview', subtitle: 'OpenAI - $75.00/$37.50/$150.00', provider: 'OpenAI' }, + { title: 'GPT-4.1', value: 'gpt-4.1', subtitle: 'OpenAI - $2.00/$0.50/$8.00', provider: 'OpenAI' }, + { title: 'GPT-4.1 Mini', value: 'gpt-4.1-mini', subtitle: 'OpenAI - $0.40/$0.10/$1.60', provider: 'OpenAI' }, + { title: 'GPT-4.1 Nano', value: 'gpt-4.1-nano', subtitle: 'OpenAI - $0.10/$0.03/$0.40', provider: 'OpenAI' }, + { title: 'GPT-4o Mini', value: 'gpt-4o-mini', subtitle: 'OpenAI - $0.15/$0.07/$0.60', provider: 'OpenAI' }, + { title: 'GPT-4o Audio Preview', value: 'gpt-4o-audio-preview', subtitle: 'OpenAI - $2.50/-/$10.00', provider: 'OpenAI' }, + { title: 'ChatGPT-4o Latest', value: 'chatgpt-4o-latest', subtitle: 'OpenAI - $5.00/-/$15.00', provider: 'OpenAI' }, + { title: 'O1', value: 'o1', subtitle: 'OpenAI - $15.00/$7.50/$60.00', provider: 'OpenAI' }, + { title: 'O4 Mini', value: 'o4-mini', subtitle: 'OpenAI - $1.10/$0.28/$4.40', provider: 'OpenAI' }, + { title: 'O3', value: 'o3', subtitle: 'OpenAI - $2.00/$0.50/$8.00', provider: 'OpenAI' }, + { title: 'O3 Mini', value: 'o3-mini', subtitle: 'OpenAI - $1.10/$0.55/$4.40', provider: 'OpenAI' }, + { title: 'O3 Mini High', value: 'o3-mini-high', subtitle: 'OpenAI - $1.10/-/$4.40', provider: 'OpenAI' }, + { title: 'O3 Mini Low', value: 'o3-mini-low', subtitle: 'OpenAI - $1.10/-/$4.40', provider: 'OpenAI' }, + { title: 'O1 Mini', value: 'o1-mini', subtitle: 'OpenAI - $1.10/$0.55/$4.40', provider: 'OpenAI' }, + + // Anthropic Models + { title: 'Claude Opus 4', value: 'claude-opus-4-20250514', subtitle: 'Anthropic - $15.00/-/$75.00', provider: 'Anthropic' }, + { title: 'Claude Sonnet 4', value: 'claude-sonnet-4-20250514', subtitle: 'Anthropic - $3.00/-/$15.00', provider: 'Anthropic' }, + { title: 'Claude 3.7 Sonnet', value: 'claude-3-7-sonnet-20250219', subtitle: 'Anthropic - $3.00/$0.30/$15.00', provider: 'Anthropic' }, + { title: 'Claude 3.7 Sonnet Thinking', value: 'claude-3-7-sonnet-20250219-thinking', subtitle: 'Anthropic - $3.00/$0.30/$15.00', provider: 'Anthropic' }, + { title: 'Claude 3.5 Sonnet', value: 'claude-3-5-sonnet-20241022', subtitle: 'Anthropic - $3.00/$0.30/$15.00', provider: 'Anthropic' }, + + // Google Models + { title: 'Gemini 2.5 Pro', value: 'gemini-2.5-pro', subtitle: 'Google - $2.50/-/$20.00', provider: 'Google' }, + { title: 'Gemini 2.5 Flash', value: 'gemini-2.5-flash', subtitle: 'Google - $0.30/-/$2.50', provider: 'Google' }, + { title: 'Gemini 1.5 Pro', value: 'gemini-1.5-pro', subtitle: 'Google - $1.25/-/$5.00', provider: 'Google' }, + { title: 'Gemini 1.5 Pro Latest', value: 'gemini-1.5-pro-latest', subtitle: 'Google - $3.50/-/$14.00', provider: 'Google' }, + { title: 'Gemini 1.5 Pro 002', value: 'gemini-1.5-pro-002', subtitle: 'Google - $3.50/-/$14.00', provider: 'Google' }, + { title: 'Gemini Live 2.5 Flash Preview', value: 'gemini-live-2.5-flash-preview', subtitle: 'Google - $0.30/-/$1.20', provider: 'Google' }, + { title: 'Gemini 2.5 Flash Preview Native Audio Dialog', value: 'gemini-2.5-flash-preview-native-audio-dialog', subtitle: 'Google - $1.00/-/$4.00', provider: 'Google' }, + { title: 'Gemini 2.5 Flash Lite Preview', value: 'gemini-2.5-flash-lite-preview-06-17', subtitle: 'Google - $0.10/-/$0.40', provider: 'Google' }, + { title: 'Gemini 2.0 Flash Lite', value: 'gemini-2.0-flash-lite', subtitle: 'Google - $0.07/-/$0.30', provider: 'Google' }, + { title: 'Gemini 2.0 Flash Live', value: 'gemini-2.0-flash-live-001', subtitle: 'Google - $0.10/-/$0.40', provider: 'Google' }, + { title: 'Gemini 2.0 Flash Lite Preview', value: 'gemini-2.0-flash-lite-preview', subtitle: 'Google - $0.07/-/$0.30', provider: 'Google' }, + { title: 'Gemini 2.0 Flash', value: 'gemini-2.0-flash', subtitle: 'Google - $0.10/-/$0.40', provider: 'Google' }, + { title: 'Gemini 2.5 Flash Exp Native Audio Thinking Dialog', value: 'gemini-2.5-flash-exp-native-audio-thinking-dialog', subtitle: 'Google - $75.00/-/$625.00', provider: 'Google' }, + { title: 'Gemini 2.0 Flash Lite Preview 02-05', value: 'gemini-2.0-flash-lite-preview-02-05', subtitle: 'Google - $0.07/-/$0.30', provider: 'Google' }, + { title: 'Gemini 2.0 Flash Preview Image Generation', value: 'gemini-2.0-flash-preview-image-generation', subtitle: 'Google - $0.10/-/$0.40', provider: 'Google' }, + { title: 'Gemini 2.0 Flash Lite 001', value: 'gemini-2.0-flash-lite-001', subtitle: 'Google - $0.07/-/$0.30', provider: 'Google' }, + { title: 'Gemini 2.0 Flash 001', value: 'gemini-2.0-flash-001', subtitle: 'Google - $0.10/-/$0.40', provider: 'Google' }, + + // XAI Models + { title: 'Grok-4', value: 'grok-4', subtitle: 'XAI - $3.00/-/$15.00', provider: 'XAI' }, + { title: 'Grok-3', value: 'grok-3', subtitle: 'XAI - $3.00/-/$15.00', provider: 'XAI' }, + { title: 'Grok-3 Mini', value: 'grok-3-mini', subtitle: 'XAI - $0.30/-/$1.50', provider: 'XAI' }, + { title: 'Grok-3 Fast', value: 'grok-3-fast', subtitle: 'XAI - $5.00/-/$25.00', provider: 'XAI' }, + { title: 'Grok-3 Mini Fast', value: 'grok-3-mini-fast', subtitle: 'XAI - $0.60/-/$4.00', provider: 'XAI' }, + + // Deepseek Models + { title: 'Deepseek Reasoner', value: 'deepseek-reasoner', subtitle: 'Deepseek - $0.55/$0.14/$2.20', provider: 'Deepseek' }, + { title: 'Deepseek Chat', value: 'deepseek-chat', subtitle: 'Deepseek - $0.27/$0.07/$1.08', provider: 'Deepseek' }, + + // Alibaba Models + { title: 'Qwen3 235B A22B', value: 'qwen3-235b-a22b', subtitle: 'Alibaba - $0.16/-/$0.48', provider: 'Alibaba' }, + ], } }, methods: { @@ -80,6 +154,16 @@ export default defineComponent({ activeGateway: data.activeGateway || 'zarinpal', inquiryPanel: data.inquiryPanel || 'zohal' }; + + // بازیابی تنظیمات جادوگر هوش مصنوعی + this.aiEnabled = data.aiEnabled === '1' || data.aiEnabled === true; + this.aiAgentSource = data.aiAgentSource || 'gapgpt'; + this.aiModel = data.aiModel || 'gpt-4o'; + this.aiApiKey = data.aiApiKey || ''; + this.localModelAddress = data.localModelAddress || ''; + this.inputTokenPrice = parseFloat(data.inputTokenPrice) || 0; + this.outputTokenPrice = parseFloat(data.outputTokenPrice) || 0; + this.aiPrompt = data.aiPrompt || ''; this.loading = false; }) }, @@ -130,7 +214,20 @@ export default defineComponent({ return; } - axios.post('/api/admin/settings/system/info/save', this.systemInfo).then((resp) => { + // ترکیب تنظیمات سیستم با تنظیمات جادوگر هوش مصنوعی + const submitData = { + ...this.systemInfo, + aiEnabled: this.aiEnabled, + aiAgentSource: this.aiAgentSource, + aiModel: this.aiModel, + aiApiKey: this.aiApiKey, + localModelAddress: this.localModelAddress, + inputTokenPrice: this.inputTokenPrice, + outputTokenPrice: this.outputTokenPrice, + aiPrompt: this.aiPrompt + }; + + axios.post('/api/admin/settings/system/info/save', submitData).then((resp) => { this.loading = false; if (resp.data.result == 1) { Swal.fire({ @@ -571,6 +668,307 @@ export default defineComponent({ + + + + + +
+
+ mdi-robot +
+

جادوگر هوش مصنوعی

+

مدیریت و تنظیم سرویس‌های هوش مصنوعی

+
+
+
+ + + + + + +
+
+ + {{ aiEnabled ? 'mdi-robot' : 'mdi-robot-off' }} + +
+

+ {{ aiEnabled ? 'هوش مصنوعی فعال است' : 'هوش مصنوعی غیرفعال است' }} +

+

+ {{ aiEnabled ? 'سرویس هوش مصنوعی در دسترس است' : 'سرویس هوش مصنوعی غیرفعال شده است' }} +

+
+
+ +
+
+
+
+
+ + + + + + + mdi-cog + تنظیمات ایجنت + + + + + + + +
+ mdi-information + انتخاب سرویس هوش مصنوعی مورد نظر +
+
+ + + + + + +
+ mdi-information + کلید دسترسی به سرویس هوش مصنوعی انتخاب شده +
+
+ + + + + + +
+ mdi-information + انتخاب مدل هوش مصنوعی مورد نظر +
+
+ + + + +
+ mdi-information + آدرس کامل مدل هوش مصنوعی لوکال +
+
+
+
+
+
+
+ + + + + + + mdi-message-text + پرامپ هوش مصنوعی + + + +
+ mdi-information + این متن قبل از هر سوال به هوش مصنوعی ارسال می‌شود تا رفتار و پاسخ‌دهی آن را کنترل کند +
+
+
+
+
+ + + + +
+
+ mdi-currency-usd +
+

قیمت‌گذاری توکن‌ها

+

تعیین قیمت برای استفاده از سرویس هوش مصنوعی

+
+
+
+ + + + +
+
+ mdi-arrow-down +
+
توکن ورودی
+

قیمت هر 1000 توکن ورودی

+
+
+
+ + + + +
+
+ + + +
+
+ mdi-arrow-up +
+
توکن خروجی
+

قیمت هر 1000 توکن خروجی

+
+
+
+ + + + +
+
+
+
+
+
+
@@ -646,4 +1044,88 @@ export default defineComponent({ .service-card:hover .v-icon { transform: scale(1.1); } + +/* استایل‌های جادوگر هوش مصنوعی */ +.ai-status-card { + transition: all 0.3s ease; + border: 2px solid transparent; + position: relative; + overflow: hidden; +} + +.ai-status-active { + border-color: var(--v-success-base); + background: linear-gradient(135deg, rgba(76, 175, 80, 0.05), rgba(76, 175, 80, 0.02)); +} + +.ai-status-inactive { + border-color: var(--v-grey-base); + background: linear-gradient(135deg, rgba(158, 158, 158, 0.05), rgba(158, 158, 158, 0.02)); +} + +.ai-status-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 3px; + background: linear-gradient(90deg, var(--v-success-base), var(--v-info-base)); + opacity: 0; + transition: opacity 0.3s ease; +} + +.ai-status-active::before { + opacity: 1; +} + +.ai-status-switch { + transform: scale(1.2); +} + +.token-price-card { + transition: all 0.3s ease; + border: 2px solid transparent; + position: relative; + overflow: hidden; +} + +.token-price-card:hover { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1) !important; +} + +.token-price-header { + border-bottom: 1px solid rgba(0, 0, 0, 0.05); + position: relative; +} + +.token-price-header::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 1px; + background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.1), transparent); +} + +/* انیمیشن برای کارت‌های قیمت */ +.token-price-card .v-icon { + transition: transform 0.3s ease; +} + +.token-price-card:hover .v-icon { + transform: scale(1.1); +} + +/* بهبود ظاهر فیلدهای غیرفعال */ +.opacity-50 { + transition: opacity 0.3s ease; +} + +.opacity-50 .v-text-field--disabled, +.opacity-50 .v-select--disabled { + opacity: 0.4; +} \ No newline at end of file diff --git a/webUI/src/views/wizard/home.vue b/webUI/src/views/wizard/home.vue index 8e1616a3..3fb78fc1 100644 --- a/webUI/src/views/wizard/home.vue +++ b/webUI/src/views/wizard/home.vue @@ -1,8 +1,95 @@