Files

1 line
14 KiB
JSON

{"repo": "amongstudio/htdocs", "files": {"sp/app/Services/DeepSeekService.php": {"1f731a70e26c42caf9c83b3e2b3e30f043bbe4bd": {"t": 1785745767.8773782, "n": 6941, "h": "5c2388c41dccf311", "c": "<?php\n\nnamespace App\\Services;\n\nuse GuzzleHttp\\Client;\nuse App\\Models\\AIModel;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Log;\n\nclass DeepSeekService\n{\n protected Client $client;\n protected string $apiKey;\n protected array $cachedModels = [];\n\n protected array $fallbacks = [\n 'text' => 'deepseek-chat',\n 'reasoning' => 'deepseek-reasoner',\n ];\n\n public function __construct()\n {\n $this->apiKey = (string) get_option(\"ai_deepseek_api_key\", \"\");\n $this->client = new Client([\n 'base_uri' => 'https://api.deepseek.com/v1/',\n ]);\n }\n\n protected function getModel(string $category, ?string $default = null): string\n {\n $default ??= $this->fallbacks[$category] ?? 'deepseek-chat';\n\n if (empty($this->cachedModels)) {\n $this->cachedModels = array_keys($this->getModels());\n }\n\n $optionKey = \"ai_deepseek_model_{$category}\";\n $model = get_option($optionKey, $default);\n\n if (!in_array($model, $this->cachedModels, true)) {\n $model = $default;\n try {\n DB::table('options')->updateOrInsert(\n ['key' => $optionKey],\n ['value' => $default, 'updated_at' => now()]\n );\n } catch (\\Throwable $e) {\n Log::warning(\"Failed to update default DeepSeek model for {$category}: \" . $e->getMessage());\n }\n }\n\n return $model;\n }\n\n public function getModels(): array\n {\n try {\n $models = AIModel::query()\n ->where('provider', 'deepseek')\n ->where('is_active', 1)\n ->orderBy('category')\n ->orderBy('name')\n ->get(['model_key', 'name']);\n\n return $models->pluck('name', 'model_key')->toArray();\n } catch (\\Throwable $e) {\n Log::error(\"Error fetching DeepSeek models from DB: \" . $e->getMessage());\n return [];\n }\n }\n\n /** ---------------- Text ---------------- */\n public function generateText(\n string|array $content,\n int $maxLength,\n ?int $maxResult = null,\n string $category = 'text',\n array $options = []\n ): array {\n $model = $this->getModel($category);\n\n $messages = is_array($content)\n ? $content\n : [[\n \"role\" => \"user\",\n \"content\" => $content,\n ]];\n\n try {\n $response = $this->client->request('POST', 'chat/completions', [\n 'headers' => [\n 'Authorization' => 'Bearer ' . $this->apiKey,\n 'Content-Type' => 'application/json',\n ],\n 'json' => [\n 'model' => $model,\n 'messages' => $messages,\n 'max_tokens' => (int) $maxLength,\n 'temperature'=> $options['temperature'] ?? 0.7,\n 'top_p' => $options['top_p'] ?? 0.95,\n // 'n' => $maxResult ?? 1, // DeepSeek chưa chắc đã hỗ trợ nhiều completions\n ],\n 'timeout' => 60,\n ]);\n\n $body = json_decode($response->getBody(), true);\n\n $result = [];\n if (!empty($body['choices'])) {\n foreach ($body['choices'] as $choice) {\n $result[] = $choice['message']['content'] ?? '';\n }\n }\n\n return $this->successResponse($model, $result, [\n 'promptTokens' => $body['usage']['prompt_tokens'] ?? 0,\n 'completionTokens' => $body['usage']['completion_tokens'] ?? 0,\n 'totalTokens' => $body['usage']['total_tokens'] ?? 0,\n ]);\n\n } catch (\\Throwable $e) {\n return $this->errorResponse($model, $e, $category);\n }\n }\n\n /** ---------------- Image ---------------- */\n public function generateImage(string $prompt, array $options = [], string $category = 'image'): array\n {\n return $this->errorResponse('deepseek-image', new \\Exception(\"DeepSeek image generation not supported\"), $category);\n }\n\n /** ---------------- Video ---------------- */\n public function generateVideo(string $prompt, array $options = [], string $category = 'video'): array\n {\n return $this->errorResponse('deepseek-video', new \\Exception(\"DeepSeek video generation not supported\"), $category);\n }\n\n /** ---------------- Vision ---------------- */\n public function generateVision(string|array $prompt, array $options = [], string $category = 'vision'): array\n {\n return $this->errorResponse('deepseek-vision', new \\Exception(\"DeepSeek vision not supported\"), $category);\n }\n\n /** ---------------- Embedding ---------------- */\n public function generateEmbedding(string $prompt, array $options = [], string $category = 'embedding'): array\n {\n return $this->errorResponse('deepseek-embedding', new \\Exception(\"DeepSeek embedding not supported\"), $category);\n }\n\n /** ---------------- Speech ---------------- */\n public function textToSpeech(string $text, array $options = [], string $category = 'speech'): array\n {\n return $this->errorResponse('deepseek-tts', new \\Exception(\"DeepSeek TTS not supported\"), $category);\n }\n\n public function speechToText(string $filePath, array $options = [], string $category = 'speech_to_text'): array\n {\n return $this->errorResponse('deepseek-stt', new \\Exception(\"DeepSeek STT not supported\"), $category);\n }\n\n public function generateAudio(string $filePath, array $options = [], string $category = 'audio'): array\n {\n return $this->speechToText($filePath, $options, $category);\n }\n\n /** ---------------- Helpers ---------------- */\n protected function successResponse(string $model, array $data, array $usage = [], float $minutesUsed = 0): array\n {\n return [\n 'data' => $data,\n 'promptTokens' => $usage['promptTokens'] ?? 0,\n 'completionTokens' => $usage['completionTokens'] ?? 0,\n 'totalTokens' => $usage['totalTokens'] ?? 0,\n 'minutesUsed' => $minutesUsed,\n 'model' => $model,\n 'error' => null,\n ];\n }\n\n protected function errorResponse(string $model, \\Throwable $e, string $category = ''): array\n {\n Log::error(\"DeepSeek {$category} error with model {$model}: \" . $e->getMessage());\n\n return [\n 'data' => [],\n 'promptTokens' => 0,\n 'completionTokens' => 0,\n 'totalTokens' => 0,\n 'minutesUsed' => 0,\n 'model' => $model,\n 'error' => $e->getMessage(),\n ];\n }\n}\n"}}, "Next/app/Services/DeepSeekService.php": {"1f731a70e26c42caf9c83b3e2b3e30f043bbe4bd": {"t": 1785746176.0507784, "n": 6941, "h": "5c2388c41dccf311", "c": "<?php\n\nnamespace App\\Services;\n\nuse GuzzleHttp\\Client;\nuse App\\Models\\AIModel;\nuse Illuminate\\Support\\Facades\\DB;\nuse Illuminate\\Support\\Facades\\Log;\n\nclass DeepSeekService\n{\n protected Client $client;\n protected string $apiKey;\n protected array $cachedModels = [];\n\n protected array $fallbacks = [\n 'text' => 'deepseek-chat',\n 'reasoning' => 'deepseek-reasoner',\n ];\n\n public function __construct()\n {\n $this->apiKey = (string) get_option(\"ai_deepseek_api_key\", \"\");\n $this->client = new Client([\n 'base_uri' => 'https://api.deepseek.com/v1/',\n ]);\n }\n\n protected function getModel(string $category, ?string $default = null): string\n {\n $default ??= $this->fallbacks[$category] ?? 'deepseek-chat';\n\n if (empty($this->cachedModels)) {\n $this->cachedModels = array_keys($this->getModels());\n }\n\n $optionKey = \"ai_deepseek_model_{$category}\";\n $model = get_option($optionKey, $default);\n\n if (!in_array($model, $this->cachedModels, true)) {\n $model = $default;\n try {\n DB::table('options')->updateOrInsert(\n ['key' => $optionKey],\n ['value' => $default, 'updated_at' => now()]\n );\n } catch (\\Throwable $e) {\n Log::warning(\"Failed to update default DeepSeek model for {$category}: \" . $e->getMessage());\n }\n }\n\n return $model;\n }\n\n public function getModels(): array\n {\n try {\n $models = AIModel::query()\n ->where('provider', 'deepseek')\n ->where('is_active', 1)\n ->orderBy('category')\n ->orderBy('name')\n ->get(['model_key', 'name']);\n\n return $models->pluck('name', 'model_key')->toArray();\n } catch (\\Throwable $e) {\n Log::error(\"Error fetching DeepSeek models from DB: \" . $e->getMessage());\n return [];\n }\n }\n\n /** ---------------- Text ---------------- */\n public function generateText(\n string|array $content,\n int $maxLength,\n ?int $maxResult = null,\n string $category = 'text',\n array $options = []\n ): array {\n $model = $this->getModel($category);\n\n $messages = is_array($content)\n ? $content\n : [[\n \"role\" => \"user\",\n \"content\" => $content,\n ]];\n\n try {\n $response = $this->client->request('POST', 'chat/completions', [\n 'headers' => [\n 'Authorization' => 'Bearer ' . $this->apiKey,\n 'Content-Type' => 'application/json',\n ],\n 'json' => [\n 'model' => $model,\n 'messages' => $messages,\n 'max_tokens' => (int) $maxLength,\n 'temperature'=> $options['temperature'] ?? 0.7,\n 'top_p' => $options['top_p'] ?? 0.95,\n // 'n' => $maxResult ?? 1, // DeepSeek chưa chắc đã hỗ trợ nhiều completions\n ],\n 'timeout' => 60,\n ]);\n\n $body = json_decode($response->getBody(), true);\n\n $result = [];\n if (!empty($body['choices'])) {\n foreach ($body['choices'] as $choice) {\n $result[] = $choice['message']['content'] ?? '';\n }\n }\n\n return $this->successResponse($model, $result, [\n 'promptTokens' => $body['usage']['prompt_tokens'] ?? 0,\n 'completionTokens' => $body['usage']['completion_tokens'] ?? 0,\n 'totalTokens' => $body['usage']['total_tokens'] ?? 0,\n ]);\n\n } catch (\\Throwable $e) {\n return $this->errorResponse($model, $e, $category);\n }\n }\n\n /** ---------------- Image ---------------- */\n public function generateImage(string $prompt, array $options = [], string $category = 'image'): array\n {\n return $this->errorResponse('deepseek-image', new \\Exception(\"DeepSeek image generation not supported\"), $category);\n }\n\n /** ---------------- Video ---------------- */\n public function generateVideo(string $prompt, array $options = [], string $category = 'video'): array\n {\n return $this->errorResponse('deepseek-video', new \\Exception(\"DeepSeek video generation not supported\"), $category);\n }\n\n /** ---------------- Vision ---------------- */\n public function generateVision(string|array $prompt, array $options = [], string $category = 'vision'): array\n {\n return $this->errorResponse('deepseek-vision', new \\Exception(\"DeepSeek vision not supported\"), $category);\n }\n\n /** ---------------- Embedding ---------------- */\n public function generateEmbedding(string $prompt, array $options = [], string $category = 'embedding'): array\n {\n return $this->errorResponse('deepseek-embedding', new \\Exception(\"DeepSeek embedding not supported\"), $category);\n }\n\n /** ---------------- Speech ---------------- */\n public function textToSpeech(string $text, array $options = [], string $category = 'speech'): array\n {\n return $this->errorResponse('deepseek-tts', new \\Exception(\"DeepSeek TTS not supported\"), $category);\n }\n\n public function speechToText(string $filePath, array $options = [], string $category = 'speech_to_text'): array\n {\n return $this->errorResponse('deepseek-stt', new \\Exception(\"DeepSeek STT not supported\"), $category);\n }\n\n public function generateAudio(string $filePath, array $options = [], string $category = 'audio'): array\n {\n return $this->speechToText($filePath, $options, $category);\n }\n\n /** ---------------- Helpers ---------------- */\n protected function successResponse(string $model, array $data, array $usage = [], float $minutesUsed = 0): array\n {\n return [\n 'data' => $data,\n 'promptTokens' => $usage['promptTokens'] ?? 0,\n 'completionTokens' => $usage['completionTokens'] ?? 0,\n 'totalTokens' => $usage['totalTokens'] ?? 0,\n 'minutesUsed' => $minutesUsed,\n 'model' => $model,\n 'error' => null,\n ];\n }\n\n protected function errorResponse(string $model, \\Throwable $e, string $category = ''): array\n {\n Log::error(\"DeepSeek {$category} error with model {$model}: \" . $e->getMessage());\n\n return [\n 'data' => [],\n 'promptTokens' => 0,\n 'completionTokens' => 0,\n 'totalTokens' => 0,\n 'minutesUsed' => 0,\n 'model' => $model,\n 'error' => $e->getMessage(),\n ];\n }\n}\n"}}}}