Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/1rubinasingla_flux-tool.json
T

1 line
156 KiB
JSON

{"repo": "1rubinasingla/flux-tool", "files": {"config/deepseek.php": {"c6bc91a204f43153c6c8eed18a4b92972e0f87b0": {"t": 1785745757.979034, "n": 900, "h": "01d87353efb463d7", "c": "<?php\n\nreturn [\n\n /*\n |--------------------------------------------------------------------------\n | Gemini API Key\n |--------------------------------------------------------------------------\n |\n | Here you may specify your Gemini API Key and organization. This will be\n | used to authenticate with the Gemini API - you can find your API key\n | on Google AI Studio, at https://makersuite.google.com.\n */\n\n 'api_key' => env('DEEPSEEK_API_KEY'),\n\n /*\n |--------------------------------------------------------------------------\n | Request Timeout\n |--------------------------------------------------------------------------\n |\n | The timeout may be used to specify the maximum number of seconds to wait\n | for a response. By default, the client will time out after 30 seconds.\n */\n\n 'request_timeout' => env('DEEPSEEK_REQUEST_TIMEOUT', 30),\n];\n"}, "9d64070cba48e79de70b11e34de05f90bc9721d4": {"t": 1785756225.3956876, "n": 900, "h": "01d87353efb463d7", "c": "<?php\n\nreturn [\n\n /*\n |--------------------------------------------------------------------------\n | Gemini API Key\n |--------------------------------------------------------------------------\n |\n | Here you may specify your Gemini API Key and organization. This will be\n | used to authenticate with the Gemini API - you can find your API key\n | on Google AI Studio, at https://makersuite.google.com.\n */\n\n 'api_key' => env('DEEPSEEK_API_KEY'),\n\n /*\n |--------------------------------------------------------------------------\n | Request Timeout\n |--------------------------------------------------------------------------\n |\n | The timeout may be used to specify the maximum number of seconds to wait\n | for a response. By default, the client will time out after 30 seconds.\n */\n\n 'request_timeout' => env('DEEPSEEK_REQUEST_TIMEOUT', 30),\n];\n"}}, "app/Services/Stream/StreamService.php": {"c6bc91a204f43153c6c8eed18a4b92972e0f87b0": {"t": 1785746171.483402, "n": 76132, "h": "7821fd0a05bee00c", "c": "<?php\n\nnamespace App\\Services\\Stream;\n\nuse App\\Domains\\Engine\\Enums\\EngineEnum;\nuse App\\Domains\\Engine\\Services\\AnthropicService;\nuse App\\Domains\\Engine\\Services\\GeminiService;\nuse App\\Domains\\Entity\\Enums\\EntityEnum;\nuse App\\Domains\\Entity\\Facades\\Entity;\nuse App\\Enums\\BedrockEngine;\nuse App\\Extensions\\OpenRouter\\System\\Services\\RouterAiService;\nuse App\\Helpers\\Classes\\ApiHelper;\nuse App\\Helpers\\Classes\\Helper;\nuse App\\Models\\Setting;\nuse App\\Models\\SettingTwo;\nuse App\\Models\\Usage;\nuse App\\Models\\UserOpenai;\nuse App\\Models\\UserOpenaiChat;\nuse App\\Models\\UserOpenaiChatMessage;\nuse App\\Services\\Ai\\OpenAI\\FileSearchService;\nuse App\\Services\\Assistant\\AssistantService;\nuse App\\Services\\Bedrock\\BedrockRuntimeService;\nuse Exception;\nuse GuzzleHttp\\Client;\nuse GuzzleHttp\\Exception\\GuzzleException;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse JsonException;\nuse OpenAI as OpenAIMain;\nuse OpenAI\\Laravel\\Facades\\OpenAI;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\nuse Throwable;\n\nclass StreamService\n{\n public function __construct(\n Setting $setting,\n SettingTwo $settingTwo,\n ) {\n match (setting('default_ai_engine', EngineEnum::OPEN_AI->value)) {\n EngineEnum::ANTHROPIC->value => ApiHelper::setAnthropicKey($setting),\n EngineEnum::GEMINI->value => ApiHelper::setGeminiKey($setting),\n EngineEnum::X_AI->value \t => ApiHelper::setXAiKey($setting),\n default => ApiHelper::setOpenAiKey($setting),\n };\n }\n\n /**\n * @throws Exception\n * @throws GuzzleException\n */\n public function ChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images, $ai_engine = null, $assistant = null, $openRouter = null, $responsesApi = false): ?StreamedResponse\n {\n if ($responsesApi) {\n return $this->responsesApiStream($chat_bot, $history, $main_message, $chat_type, $contain_images);\n }\n\n if (! $ai_engine) {\n $ai_engine = setting('default_ai_engine', EngineEnum::OPEN_AI->value);\n }\n\n if (! is_null($assistant)) {\n return $this->assistantStream($chat_bot, $history, $main_message, $assistant);\n }\n\n if (! is_null($openRouter) && setting('open_router_status') == 1) {\n return $this->openRouterChatStream($chat_bot, $history, $main_message, $contain_images, $openRouter);\n }\n\n return match ($ai_engine) {\n EngineEnum::OPEN_AI->value => $this->openaiChatStream($chat_bot, $history, $main_message, $chat_type, $contain_images),\n EngineEnum::ANTHROPIC->value => $this->anthropicChatStream($chat_bot, $history, $main_message, $chat_type, $contain_images),\n EngineEnum::GEMINI->value => $this->geminiChatStream($chat_bot, $history, $main_message, $chat_type, $contain_images),\n EngineEnum::DEEP_SEEK->value => $this->deepseekChatStream($chat_bot, $history, $main_message, $contain_images),\n EngineEnum::X_AI->value => $this->xAiChatStream($chat_bot, $history, $main_message, $chat_type, $contain_images),\n default => throw new Exception('Invalid AI Engine'),\n };\n }\n\n private function openRouterChatStream($chat_bot, $history, $main_message, $contain_images, $openRouter)\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($openRouter));\n }\n\n return response()->stream(function () use ($openRouter, $driver, $chat_bot, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n if (! $contain_images) {\n $historyMessages = array_filter($history, function ($item) {\n return $item['role'] != 'system';\n });\n\n $service = new RouterAiService;\n $response = $service->response(last($historyMessages)['content'], $openRouter);\n\n foreach (explode(\"\\n\", $response) as $line) {\n if (str_starts_with($line, 'data:')) {\n $data = trim(substr($line, 5));\n if ($data === '[DONE]') {\n break;\n }\n\n $json = json_decode($data, true);\n\n if (isset($json['choices'][0]['delta']['content'])) {\n $content = $json['choices'][0]['delta']['content'];\n\n if (! empty($content)) {\n $output .= $content;\n $responsedText .= $content;\n $total_used_tokens += str_word_count($content);\n\n $content = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $content);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $content;\n echo \"\\n\\n\";\n flush();\n\n if (connection_aborted()) {\n break;\n }\n }\n }\n }\n }\n } else {\n ApiHelper::setOpenAiKey();\n $chat_bot = 'gpt-4o';\n $stream = OpenAI::chat()->createStreamed([\n 'model' => $chat_bot,\n 'messages' => $history,\n 'max_tokens' => 2000,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n ]);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n public function fixMessageHistory(array $history): array\n {\n $fixedHistory = [];\n $firstMessage = null;\n foreach ($history as $message) {\n if ($firstMessage === null) {\n $firstMessage = $message;\n } else {\n if ($firstMessage['role'] === $message['role']) {\n if (is_array($message['content'])) {\n $firstMessage['content'] = $message['content'];\n } else {\n $firstMessage['content'] .= ' ' . $message['content'];\n }\n } else {\n // Add the current message to the fixed history\n $fixedHistory[] = $firstMessage;\n // Start a new message\n $firstMessage = $message;\n }\n }\n }\n if ($firstMessage !== null) {\n $fixedHistory[] = $firstMessage;\n }\n\n return $fixedHistory;\n }\n\n private function deepseekChatStream($chat_bot, $history, $main_message, $contain_images): StreamedResponse\n {\n ini_set('max_execution_time', 440);\n set_time_limit(0);\n\n $history = $this->fixMessageHistory($history);\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n }\n\n return response()->stream(\n function () use ($driver, $chat_bot, $history, $main_message, $contain_images, &$total_used_tokens, &$output, &$responsedText) {\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n if (! $contain_images) {\n ini_set('max_execution_time', 3000);\n set_time_limit(3000);\n $client = new Client;\n ApiHelper::setDeepseekKey();\n $url = 'https://api.deepseek.com/chat/completions';\n $apikey = config('deepseek.api_key');\n $headers = [\n 'Content-Type' => 'application/json',\n 'Accept' => 'application/json',\n 'Authorization' => \"Bearer $apikey\",\n ];\n\n $body = [\n 'messages' => $history,\n 'model' => $chat_bot,\n 'frequency_penalty' => 0,\n 'max_tokens' => (int) setting('deepseek_max_output_length', 200),\n 'presence_penalty' => 0,\n 'response_format' => [\n 'type' => 'text',\n ],\n 'stop' => null,\n 'stream' => true,\n 'stream_options' => null,\n 'temperature' => 1,\n 'top_p' => 1,\n 'tools' => null,\n 'tool_choice' => 'none',\n 'logprobs' => false,\n 'top_logprobs' => null,\n ];\n $response = $client->post($url, [\n 'headers' => $headers,\n 'json' => $body,\n ]);\n $bodyStream = $response->getBody();\n $buffer = '';\n $emptyLinesAdded = false;\n while (! $bodyStream->eof()) {\n $chunk = $bodyStream->read(1024);\n $buffer .= $chunk;\n\n while (($pos = strpos($buffer, \"\\n\")) !== false) {\n $line = substr($buffer, 0, $pos);\n $buffer = substr($buffer, $pos + 1);\n\n if (str_starts_with(trim($line), 'data: ')) {\n $json = trim(substr($line, 5)); // Remove \"data: \"\n if (! empty($json)) {\n $decoded = json_decode($json, true);\n if (json_last_error() === JSON_ERROR_NONE) {\n $delta = $decoded['choices'][0]['delta'] ?? [];\n\n // Handle reasoning content\n if (isset($delta['reasoning_content']) && $delta['reasoning_content'] !== null) {\n // Add start signal if this is the first reasoning content\n if (! isset($reasoningStarted)) {\n $reasoningStarted = true;\n $startSignal = '[START_REASONING]';\n $output .= $startSignal;\n $responsedText .= '[START_REASONING]';\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $startSignal;\n echo \"\\n\\n\";\n flush();\n }\n\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $delta['reasoning_content']);\n $output .= $messageFix;\n $responsedText .= $messageFix;\n // $total_used_tokens += countWords($messageFix); do we calculate reasoning content?\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n\n // Handle regular content\n if (isset($delta['content']) && $delta['content'] !== null) {\n // Add end signal if we were in reasoning mode\n if (isset($reasoningStarted)) {\n $endSignal = '[END_REASONING]<br/><br/>';\n $output .= $endSignal;\n $responsedText .= \"[END_REASONING]\\n\\n\";\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $endSignal;\n echo \"\\n\\n\";\n flush();\n\n unset($reasoningStarted);\n }\n\n if (! $emptyLinesAdded) {\n echo \"event: data\\n\";\n echo 'data: <br/><br/><br/>';\n echo \"\\n\\n\";\n flush();\n $emptyLinesAdded = true;\n }\n\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $delta['content']);\n $output .= $messageFix;\n $responsedText .= $messageFix;\n $total_used_tokens += countWords($messageFix);\n\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n }\n }\n\n if (connection_aborted()) {\n break;\n }\n }\n\n } else {\n ApiHelper::setOpenAiKey();\n $chat_bot = 'gpt-4o';\n $stream = OpenAI::chat()->createStreamed([\n 'model' => $chat_bot,\n 'messages' => $history,\n 'max_tokens' => 2000,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n ]);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n },\n 200,\n [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]\n );\n }\n\n private function deepseekOtherStream(Request $request, $chat_bot)\n {\n ini_set('max_execution_time', 440);\n set_time_limit(0);\n\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n\n $history[] = ['role' => 'user', 'content' => $prompt];\n\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n return response()->stream(function () use (&$total_used_tokens, &$output, &$responsedText, $driver, $message_id, $title, $openai_id, $prompt, $history, $chat_bot) {\n\n $user = Auth::user();\n $entry = UserOpenai::firstOrCreate(\n [\n 'id' => $message_id,\n ],\n [\n 'user_id' => $user->id,\n 'input' => $prompt,\n 'hash' => str()->random(256),\n 'team_id' => $user->team_id,\n 'slug' => str()->random(7) . str($user?->fullName())->slug() . '-workbook',\n 'openai_id' => $openai_id ?? 1,\n ]);\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $client = new Client;\n\n ApiHelper::setDeepseekKey();\n\n $url = 'https://api.deepseek.com/chat/completions';\n $apikey = config('deepseek.api_key');\n $headers = [\n 'Content-Type' => 'application/json',\n 'Accept' => 'application/json',\n 'Authorization' => \"Bearer $apikey\",\n ];\n\n $body = [\n 'messages' => $history,\n 'model' => $chat_bot,\n 'frequency_penalty' => 0,\n 'max_tokens' => (int) setting('deepseek_max_output_length', 200),\n 'presence_penalty' => 0,\n 'response_format' => [\n 'type' => 'text',\n ],\n 'stop' => null,\n 'stream' => true,\n 'stream_options' => null,\n 'temperature' => 1,\n 'top_p' => 1,\n 'tools' => null,\n 'tool_choice' => 'none',\n 'logprobs' => false,\n 'top_logprobs' => null,\n ];\n\n $response = $client->post($url, [\n 'headers' => $headers,\n 'json' => $body,\n ]);\n\n $bodyStream = $response->getBody();\n $buffer = '';\n $emptyLinesAdded = false;\n while (! $bodyStream->eof()) {\n $chunk = $bodyStream->read(1024);\n $buffer .= $chunk;\n\n while (($pos = strpos($buffer, \"\\n\")) !== false) {\n $line = substr($buffer, 0, $pos);\n $buffer = substr($buffer, $pos + 1);\n\n if (str_starts_with(trim($line), 'data: ')) {\n $json = trim(substr($line, 5)); // Remove \"data: \"\n if (! empty($json)) {\n $decoded = json_decode($json, true);\n if (json_last_error() === JSON_ERROR_NONE) {\n $delta = $decoded['choices'][0]['delta'] ?? [];\n if (isset($delta['reasoning_content']) && $delta['reasoning_content'] !== null) {\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $delta['reasoning_content']);\n $output .= $messageFix;\n $responsedText .= $messageFix;\n // $total_used_tokens += countWords($messageFix); do we calculate reasoning content?\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n\n if (isset($delta['content']) && $delta['content'] !== null) {\n if (! $emptyLinesAdded) {\n echo \"event: data\\n\";\n echo 'data: <br/><br/><br/>';\n echo \"\\n\\n\";\n flush();\n $emptyLinesAdded = true;\n }\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $delta['content']);\n\n $output .= $messageFix;\n $responsedText .= $messageFix;\n $total_used_tokens += countWords($messageFix);\n\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n }\n }\n\n if (connection_aborted()) {\n break;\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $entry->update([\n 'title' => $title ?: null,\n 'credits' => $total_used_tokens,\n 'words' => $total_used_tokens,\n 'response' => $responsedText,\n 'output' => $output,\n ]);\n\n $driver->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n /**\n * @throws GuzzleException\n * @throws JsonException\n * @throws Exception\n */\n public function assistantStream(string $chat_bot, $history, $main_message, $assistant): ?StreamedResponse\n {\n $chat = UserOpenaiChat::query()->where('id', $main_message->user_openai_chat_id)->first();\n $threadId = $chat?->thread_id;\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n $assistantService = new AssistantService;\n\n $tmp = $assistantService->createMessage($threadId, $history);\n\n return $assistantService->createRun($chat_bot, $assistant, $threadId, $main_message, $driver);\n }\n\n public function OtherStream(Request $request, string $chat_bot, $ai_engine = null): StreamedResponse\n {\n if (! $ai_engine) {\n $ai_engine = setting('default_ai_engine', EngineEnum::OPEN_AI->value);\n }\n\n if (setting('open_router_status') == 1 && $request->open_router_model !== 'undefined' && ! empty($request->open_router_model)) {\n return $this->openRouterStream($request);\n }\n\n return match ($ai_engine) {\n EngineEnum::ANTHROPIC->value => $this->anthropicOtherStream($request, $chat_bot),\n EngineEnum::GEMINI->value => $this->geminiOtherStream($request, $chat_bot),\n EngineEnum::DEEP_SEEK->value => $this->deepseekOtherStream($request, $chat_bot),\n EngineEnum::X_AI->value \t => $this->xAiOtherStream($request, $chat_bot),\n default => $this->openaiOtherStream($request, $chat_bot),\n };\n }\n\n private function openRouterStream(Request $request)\n {\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n $open_router_model = $request->get('open_router_model');\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $driver = Entity::driver(EntityEnum::fromSlug($open_router_model));\n\n return response()->stream(function () use ($driver, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt, $open_router_model) {\n $user = Auth::user();\n $entry = UserOpenai::find($message_id);\n if (! $entry) {\n $entry = new UserOpenai;\n $entry->user_id = $user?->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user?->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $service = new RouterAiService;\n $response = $service->response($entry->input, $open_router_model);\n\n foreach (explode(\"\\n\", $response) as $line) {\n if (str_starts_with($line, 'data:')) {\n $data = trim(substr($line, 5));\n if ($data === '[DONE]') {\n break;\n }\n\n $json = json_decode($data, true);\n\n if (isset($json['choices'][0]['delta']['content'])) {\n $content = $json['choices'][0]['delta']['content'];\n\n // Boş içerik varsa atla\n if (! empty($content)) {\n $output .= $content;\n $responsedText .= $content;\n $total_used_tokens += str_word_count($content);\n\n $content = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $content);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $content;\n echo \"\\n\\n\";\n flush();\n\n if (connection_aborted()) {\n break;\n }\n }\n }\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n public function reduceTokensWhenIntterruptStream(Request $request, $type): void\n {\n $model = Helper::setting('openai_default_model') ?: EntityEnum::GPT_3_5_TURBO_16K->value;\n $streamed_text = $request->get('streamed_text');\n $message_id = $request->get('streamed_message_id');\n if ($streamed_text) {\n $total_used_tokens = countWords($streamed_text);\n Entity::driver(EntityEnum::fromSlug($model))->input($streamed_text)->calculateCredit()->decreaseCredit();\n if (! empty($message_id)) {\n if ($type === 'writer') {\n $entry = UserOpenai::find($message_id);\n if ($entry) {\n $entry->title = null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $streamed_text;\n $entry->output = $streamed_text;\n $entry->save();\n }\n } else { // chat\n $main_message = UserOpenaiChatMessage::find($message_id);\n if ($main_message) {\n $chat = UserOpenaiChat::find($main_message->user_openai_chat_id);\n $main_message->response = $streamed_text;\n $main_message->output = $streamed_text;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n\n if ($chat) {\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n }\n }\n }\n }\n }\n }\n\n // X-AI Stream\n /**\n * @throws Exception\n */\n private function xAiChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): ?StreamedResponse\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n }\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $model = $driver->enum()->value;\n if ($contain_images) {\n $options = [\n 'model' => EntityEnum::GPT_4_O->value,\n 'messages' => $history,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n 'max_tokens' => 2000,\n ];\n $stream = OpenAI::chat()->createStreamed($options);\n } else {\n $api = ApiHelper::setXAiKey();\n\n try {\n $cli = OpenAIMain::factory()->withBaseUri('https://api.x.ai/v1')\n ->withHttpHeader('Authorization', 'Bearer ' . $api)\n ->withApiKey($api)\n ->make();\n $stream = $cli->chat()->createStreamed([\n 'model' => $model,\n 'messages' => $history,\n 'stream' => true,\n 'temperature' => 1.0,\n ]);\n } catch (Exception|Throwable $e) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('Something went wrong. Please try again later.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n }\n\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n private function xAiOtherStream(Request $request, $chat_bot): ?StreamedResponse\n {\n $apiKey = ApiHelper::setXAiKey();\n $xai = OpenAIMain::factory()\n ->withApiKey($apiKey)\n ->withBaseUri('https://api.x.ai/v1')\n ->make();\n\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n\n $history[] = ['role' => 'user', 'content' => $prompt];\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $user = Auth::user();\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n return response()->stream(static function () use ($user, $driver, $history, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt) {\n $entry = UserOpenai::find($message_id);\n if (! $entry) {\n $entry = new UserOpenai;\n $entry->user_id = $user->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $api = ApiHelper::setXAiKey();\n\n try {\n $cli = OpenAIMain::factory()->withBaseUri('https://api.x.ai/v1')\n ->withHttpHeader('Authorization', 'Bearer ' . $api)\n ->withApiKey($api)\n ->make();\n $stream = $cli->chat()->createStreamed([\n 'model' => $driver->enum()->value,\n 'messages' => $history,\n 'stream' => true,\n 'temperature' => 1.0,\n ]);\n } catch (Exception|Throwable $e) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('Something went wrong. Please try again later.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n // OpenAI Stream\n /**\n * @throws Exception\n */\n private function openaiChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): ?StreamedResponse\n {\n // @todo: in beta entites: EntityEnum::fromSlug($chat_bot)->isBetaEntity() then output without stream, stream not working\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n }\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $model = $driver->enum()->value;\n $options = [\n 'model' => $model,\n 'messages' => $history,\n 'stream' => true,\n ];\n\n if (! in_array($model, [EntityEnum::GPT_4_O_MINI_SEARCH_PREVIEW->value, EntityEnum::GPT_4_O_SEARCH_PREVIEW->value], true)) {\n $options['temperature'] = 1.0;\n $options['frequency_penalty'] = 0;\n $options['presence_penalty'] = 0;\n }\n\n if ($contain_images) {\n $options['max_tokens'] = 2000;\n $options['model'] = EntityEnum::GPT_4_O;\n }\n $stream = OpenAI::chat()->createStreamed($options);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n /**\n * @throws Exception\n */\n private function responsesApiStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): ?StreamedResponse\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n }\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $model = $driver->enum()->value;\n $options = [\n 'model' => $model,\n 'messages' => $history,\n 'stream' => true,\n ];\n\n if (! in_array($model, [EntityEnum::GPT_4_O_MINI_SEARCH_PREVIEW->value, EntityEnum::GPT_4_O_SEARCH_PREVIEW->value], true)) {\n $options['temperature'] = 1.0;\n $options['frequency_penalty'] = 0;\n $options['presence_penalty'] = 0;\n }\n\n if ($contain_images) {\n $options['max_tokens'] = 2000;\n $options['model'] = EntityEnum::GPT_4_O;\n\n $stream = OpenAI::chat()->createStreamed($options);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n } else {\n $fileSearchService = new FileSearchService;\n $responsedText = $output = $fileSearchService->searchInFile($options, $chat);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $responsedText;\n echo \"\\n\\n\";\n flush();\n\n $total_used_tokens = countWords($responsedText);\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n private function openaiOtherStream(Request $request, $chat_bot): ?StreamedResponse\n {\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n\n $history[] = ['role' => 'user', 'content' => $prompt];\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $user = Auth::user();\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n return response()->stream(static function () use ($user, $driver, $history, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt) {\n $entry = UserOpenai::find($message_id);\n if (! $entry) {\n $entry = new UserOpenai;\n $entry->user_id = $user->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $stream = OpenAI::chat()->createStreamed([\n 'model' => $driver->enum()->value,\n 'messages' => $history,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n ]);\n\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n // AnthropicService Stream\n private function anthropicChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): ?StreamedResponse\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $client = app(AnthropicService::class);\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n return response()->stream(static function () use ($driver, $client, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n\n if (! $contain_images) {\n $historyMessages = array_filter($history, function ($item) {\n return $item['role'] !== 'system';\n });\n $system = Arr::first(array_filter($history, function ($item) {\n return $item['role'] === 'system';\n }));\n $system = data_get($system, 'content');\n\n if (setting('anthropic_default_model') === BedrockEngine::BEDROCK->value) {\n $bedrockService = new BedrockRuntimeService([\n 'region' => config('filesystems.disks.s3.region'),\n 'version' => 'latest',\n 'credentials' => [\n 'key' => config('filesystems.disks.s3.key'),\n 'secret' => config('filesystems.disks.s3.secret'),\n ],\n ]);\n $responseBody = $bedrockService->invokeClaude($main_message->input);\n $driver = Entity::driver(EntityEnum::CLAUDE_2_1);\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n if ($responseBody) {\n $response = $this->anthropicBedrockResponse($responseBody);\n $output = $response['output'];\n $responsedText = $response['responsedText'];\n $total_used_tokens = $response['total_used_tokens'];\n }\n } else {\n $data = $client->setStream(true)\n ->setSystem($system)\n ->setMessages(array_values($historyMessages))\n ->stream()\n ->body();\n foreach (explode(\"\\n\", $data) as $chunk) {\n if (strlen($chunk) < 6) {\n continue;\n }\n if (! Str::contains($chunk, 'data: ')) {\n continue;\n }\n $chunk = str_replace('data: {', '{', $chunk);\n $jsonData = json_decode($chunk, false, 512, JSON_THROW_ON_ERROR);\n if (isset($jsonData->delta->text)) {\n $message = $jsonData->delta->text;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $message);\n $output .= $messageFix;\n $responsedText .= $message;\n $total_used_tokens += countWords($message);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n if (connection_aborted()) {\n break;\n }\n }\n }\n } else {\n ApiHelper::setOpenAiKey();\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n $stream = OpenAI::chat()->createStreamed([\n 'model' => $driver->enum()->value,\n 'messages' => $history,\n 'max_tokens' => 2000,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n ]);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n private function anthropicOtherStream(Request $request, $chat_bot): StreamedResponse\n {\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n $history[] = ['role' => 'user', 'content' => $prompt];\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt) {\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $user = Auth::user();\n $entry = UserOpenai::find($message_id);\n if (is_null($entry)) {\n $entry = new UserOpenai;\n $entry->user_id = $user?->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user?->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n $client = app(AnthropicService::class);\n $historyMessages = array_filter($history, function ($item) {\n return $item['role'] !== 'system';\n });\n $system = Arr::first(array_filter($history, function ($item) {\n return $item['role'] === 'system';\n }));\n\n $system = data_get($system, 'content');\n if (setting('anthropic_default_model') === BedrockEngine::BEDROCK->value) {\n $bedrockService = new BedrockRuntimeService([\n 'region' => config('filesystems.disks.s3.region'),\n 'version' => 'latest',\n 'credentials' => [\n 'key' => config('filesystems.disks.s3.key'),\n 'secret' => config('filesystems.disks.s3.secret'),\n ],\n ]);\n $driver = Entity::driver(EntityEnum::CLAUDE_2_1);\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n $responseBody = $bedrockService->invokeClaude($entry->input);\n if ($responseBody) {\n $response = self::anthropicBedrockResponse($responseBody);\n $output = $response['output'];\n $responsedText = $response['responsedText'];\n $total_used_tokens = $response['total_used_tokens'];\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n }\n\n } else {\n $data = $client->setStream(true)\n ->setSystem($system)\n ->setMessages(array_values($historyMessages))\n ->stream()\n ->body();\n foreach (explode(\"\\n\", $data) as $chunk) {\n if (strlen($chunk) < 6) {\n continue;\n }\n if (! Str::contains($chunk, 'data: ')) {\n continue;\n }\n $chunk = str_replace('data: {', '{', $chunk);\n if (isset(json_decode($chunk, false, 512, JSON_THROW_ON_ERROR)->delta->text)) {\n $message = json_decode($chunk, false, 512, JSON_THROW_ON_ERROR)->delta->text;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $message);\n $output .= $messageFix;\n $responsedText .= $message;\n $total_used_tokens += countWords($message);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n if (connection_aborted()) {\n break;\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n }\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n // GeminiService Stream\n private function geminiChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): StreamedResponse\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $newhistory = convertHistoryToGemini($history);\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n if ($contain_images) {\n // I will improve later\n $newhistory = $this->getLastMessageAndImage($newhistory);\n if (count($newhistory['parts']) === 1) {\n $newhistory['parts'][0] = [\n 'text' => $newhistory['parts'][0]['text'],\n ];\n\n $contain_images = false;\n }\n\n $newhistory = [$newhistory];\n }\n\n return response()->stream(static function () use ($driver, $newhistory, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GEMINI_1_5_FLASH);\n }\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $client = app(GeminiService::class);\n $response = $client\n ->setHistory($newhistory)\n ->streamGenerateContent($driver->enum()->value);\n\n while (! $response->getBody()->eof()) {\n\n $line = $client->readLine($response->getBody());\n\n try {\n $decodedLine = json_decode($line, true, 512, JSON_THROW_ON_ERROR);\n\n if ($decodedLine === null || ! isset($decodedLine['candidates'])) {\n Log::info('Decoded line does not contain expected data: ' . json_encode($decodedLine));\n\n continue;\n }\n } catch (JsonException $e) {\n Log::error('JSON decoding error: ' . $e->getMessage());\n Log::error('Offending line: ' . $line);\n\n continue;\n }\n\n if ($decodedLine === null || ! isset($decodedLine['candidates'])) {\n continue;\n }\n\n foreach ($decodedLine['candidates'] as $candidate) {\n $text = $candidate['content']['parts'][0]['text'];\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n\n if (connection_aborted()) {\n break;\n }\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n public function getLastMessageAndImage($newhistory)\n {\n return Arr::last($newhistory);\n }\n\n private function geminiOtherStream(Request $request, string $chat_bot): StreamedResponse\n {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n\n $history[] = [\n 'parts' => [\n [\n 'text' => $prompt,\n ],\n ],\n 'role' => 'user',\n ];\n\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt) {\n $user = Auth::user();\n $entry = UserOpenai::find($message_id);\n if (is_null($entry)) {\n $entry = new UserOpenai;\n $entry->user_id = $user->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n $client = app(GeminiService::class);\n $response = $client\n ->setHistory($history)\n ->streamGenerateContent($driver->enum()->value);\n\n while (! $response->getBody()->eof()) {\n\n $line = $client->readLine($response->getBody());\n\n try {\n $decodedLine = json_decode($line, true, 512, JSON_THROW_ON_ERROR);\n\n if ($decodedLine === null || ! isset($decodedLine['candidates'])) {\n Log::info('Decoded line does not contain expected data: ' . json_encode($decodedLine));\n\n continue;\n }\n } catch (JsonException $e) {\n Log::error('JSON decoding error: ' . $e->getMessage());\n Log::error('Offending line: ' . $line);\n\n continue;\n }\n if ($decodedLine === null || ! isset($decodedLine['candidates'])) {\n continue;\n }\n\n foreach ($decodedLine['candidates'] as $candidate) {\n $text = $candidate['content']['parts'][0]['text'];\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n private function anthropicBedrockResponse($responseBody): array\n {\n $completion = $responseBody['completion'];\n $parts = explode(':', $completion, 2);\n if (isset($parts[1])) {\n $completion = trim($parts[1]);\n }\n\n $words = explode(' ', $completion);\n $output = $completion;\n $responsedText = $completion;\n $total_used_tokens = count($words);\n foreach ($words as $word) {\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $word) . ' ';\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n\n if (connection_aborted()) {\n break;\n }\n }\n\n return [\n 'output' => $output,\n 'responsedText' => $responsedText,\n 'total_used_tokens' => $total_used_tokens,\n ];\n }\n}\n"}, "9d64070cba48e79de70b11e34de05f90bc9721d4": {"t": 1785756225.6138856, "n": 76132, "h": "7821fd0a05bee00c", "c": "<?php\n\nnamespace App\\Services\\Stream;\n\nuse App\\Domains\\Engine\\Enums\\EngineEnum;\nuse App\\Domains\\Engine\\Services\\AnthropicService;\nuse App\\Domains\\Engine\\Services\\GeminiService;\nuse App\\Domains\\Entity\\Enums\\EntityEnum;\nuse App\\Domains\\Entity\\Facades\\Entity;\nuse App\\Enums\\BedrockEngine;\nuse App\\Extensions\\OpenRouter\\System\\Services\\RouterAiService;\nuse App\\Helpers\\Classes\\ApiHelper;\nuse App\\Helpers\\Classes\\Helper;\nuse App\\Models\\Setting;\nuse App\\Models\\SettingTwo;\nuse App\\Models\\Usage;\nuse App\\Models\\UserOpenai;\nuse App\\Models\\UserOpenaiChat;\nuse App\\Models\\UserOpenaiChatMessage;\nuse App\\Services\\Ai\\OpenAI\\FileSearchService;\nuse App\\Services\\Assistant\\AssistantService;\nuse App\\Services\\Bedrock\\BedrockRuntimeService;\nuse Exception;\nuse GuzzleHttp\\Client;\nuse GuzzleHttp\\Exception\\GuzzleException;\nuse Illuminate\\Http\\Request;\nuse Illuminate\\Support\\Arr;\nuse Illuminate\\Support\\Facades\\Auth;\nuse Illuminate\\Support\\Facades\\Log;\nuse Illuminate\\Support\\Str;\nuse JsonException;\nuse OpenAI as OpenAIMain;\nuse OpenAI\\Laravel\\Facades\\OpenAI;\nuse Symfony\\Component\\HttpFoundation\\StreamedResponse;\nuse Throwable;\n\nclass StreamService\n{\n public function __construct(\n Setting $setting,\n SettingTwo $settingTwo,\n ) {\n match (setting('default_ai_engine', EngineEnum::OPEN_AI->value)) {\n EngineEnum::ANTHROPIC->value => ApiHelper::setAnthropicKey($setting),\n EngineEnum::GEMINI->value => ApiHelper::setGeminiKey($setting),\n EngineEnum::X_AI->value \t => ApiHelper::setXAiKey($setting),\n default => ApiHelper::setOpenAiKey($setting),\n };\n }\n\n /**\n * @throws Exception\n * @throws GuzzleException\n */\n public function ChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images, $ai_engine = null, $assistant = null, $openRouter = null, $responsesApi = false): ?StreamedResponse\n {\n if ($responsesApi) {\n return $this->responsesApiStream($chat_bot, $history, $main_message, $chat_type, $contain_images);\n }\n\n if (! $ai_engine) {\n $ai_engine = setting('default_ai_engine', EngineEnum::OPEN_AI->value);\n }\n\n if (! is_null($assistant)) {\n return $this->assistantStream($chat_bot, $history, $main_message, $assistant);\n }\n\n if (! is_null($openRouter) && setting('open_router_status') == 1) {\n return $this->openRouterChatStream($chat_bot, $history, $main_message, $contain_images, $openRouter);\n }\n\n return match ($ai_engine) {\n EngineEnum::OPEN_AI->value => $this->openaiChatStream($chat_bot, $history, $main_message, $chat_type, $contain_images),\n EngineEnum::ANTHROPIC->value => $this->anthropicChatStream($chat_bot, $history, $main_message, $chat_type, $contain_images),\n EngineEnum::GEMINI->value => $this->geminiChatStream($chat_bot, $history, $main_message, $chat_type, $contain_images),\n EngineEnum::DEEP_SEEK->value => $this->deepseekChatStream($chat_bot, $history, $main_message, $contain_images),\n EngineEnum::X_AI->value => $this->xAiChatStream($chat_bot, $history, $main_message, $chat_type, $contain_images),\n default => throw new Exception('Invalid AI Engine'),\n };\n }\n\n private function openRouterChatStream($chat_bot, $history, $main_message, $contain_images, $openRouter)\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($openRouter));\n }\n\n return response()->stream(function () use ($openRouter, $driver, $chat_bot, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n if (! $contain_images) {\n $historyMessages = array_filter($history, function ($item) {\n return $item['role'] != 'system';\n });\n\n $service = new RouterAiService;\n $response = $service->response(last($historyMessages)['content'], $openRouter);\n\n foreach (explode(\"\\n\", $response) as $line) {\n if (str_starts_with($line, 'data:')) {\n $data = trim(substr($line, 5));\n if ($data === '[DONE]') {\n break;\n }\n\n $json = json_decode($data, true);\n\n if (isset($json['choices'][0]['delta']['content'])) {\n $content = $json['choices'][0]['delta']['content'];\n\n if (! empty($content)) {\n $output .= $content;\n $responsedText .= $content;\n $total_used_tokens += str_word_count($content);\n\n $content = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $content);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $content;\n echo \"\\n\\n\";\n flush();\n\n if (connection_aborted()) {\n break;\n }\n }\n }\n }\n }\n } else {\n ApiHelper::setOpenAiKey();\n $chat_bot = 'gpt-4o';\n $stream = OpenAI::chat()->createStreamed([\n 'model' => $chat_bot,\n 'messages' => $history,\n 'max_tokens' => 2000,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n ]);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n public function fixMessageHistory(array $history): array\n {\n $fixedHistory = [];\n $firstMessage = null;\n foreach ($history as $message) {\n if ($firstMessage === null) {\n $firstMessage = $message;\n } else {\n if ($firstMessage['role'] === $message['role']) {\n if (is_array($message['content'])) {\n $firstMessage['content'] = $message['content'];\n } else {\n $firstMessage['content'] .= ' ' . $message['content'];\n }\n } else {\n // Add the current message to the fixed history\n $fixedHistory[] = $firstMessage;\n // Start a new message\n $firstMessage = $message;\n }\n }\n }\n if ($firstMessage !== null) {\n $fixedHistory[] = $firstMessage;\n }\n\n return $fixedHistory;\n }\n\n private function deepseekChatStream($chat_bot, $history, $main_message, $contain_images): StreamedResponse\n {\n ini_set('max_execution_time', 440);\n set_time_limit(0);\n\n $history = $this->fixMessageHistory($history);\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n }\n\n return response()->stream(\n function () use ($driver, $chat_bot, $history, $main_message, $contain_images, &$total_used_tokens, &$output, &$responsedText) {\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n if (! $contain_images) {\n ini_set('max_execution_time', 3000);\n set_time_limit(3000);\n $client = new Client;\n ApiHelper::setDeepseekKey();\n $url = 'https://api.deepseek.com/chat/completions';\n $apikey = config('deepseek.api_key');\n $headers = [\n 'Content-Type' => 'application/json',\n 'Accept' => 'application/json',\n 'Authorization' => \"Bearer $apikey\",\n ];\n\n $body = [\n 'messages' => $history,\n 'model' => $chat_bot,\n 'frequency_penalty' => 0,\n 'max_tokens' => (int) setting('deepseek_max_output_length', 200),\n 'presence_penalty' => 0,\n 'response_format' => [\n 'type' => 'text',\n ],\n 'stop' => null,\n 'stream' => true,\n 'stream_options' => null,\n 'temperature' => 1,\n 'top_p' => 1,\n 'tools' => null,\n 'tool_choice' => 'none',\n 'logprobs' => false,\n 'top_logprobs' => null,\n ];\n $response = $client->post($url, [\n 'headers' => $headers,\n 'json' => $body,\n ]);\n $bodyStream = $response->getBody();\n $buffer = '';\n $emptyLinesAdded = false;\n while (! $bodyStream->eof()) {\n $chunk = $bodyStream->read(1024);\n $buffer .= $chunk;\n\n while (($pos = strpos($buffer, \"\\n\")) !== false) {\n $line = substr($buffer, 0, $pos);\n $buffer = substr($buffer, $pos + 1);\n\n if (str_starts_with(trim($line), 'data: ')) {\n $json = trim(substr($line, 5)); // Remove \"data: \"\n if (! empty($json)) {\n $decoded = json_decode($json, true);\n if (json_last_error() === JSON_ERROR_NONE) {\n $delta = $decoded['choices'][0]['delta'] ?? [];\n\n // Handle reasoning content\n if (isset($delta['reasoning_content']) && $delta['reasoning_content'] !== null) {\n // Add start signal if this is the first reasoning content\n if (! isset($reasoningStarted)) {\n $reasoningStarted = true;\n $startSignal = '[START_REASONING]';\n $output .= $startSignal;\n $responsedText .= '[START_REASONING]';\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $startSignal;\n echo \"\\n\\n\";\n flush();\n }\n\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $delta['reasoning_content']);\n $output .= $messageFix;\n $responsedText .= $messageFix;\n // $total_used_tokens += countWords($messageFix); do we calculate reasoning content?\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n\n // Handle regular content\n if (isset($delta['content']) && $delta['content'] !== null) {\n // Add end signal if we were in reasoning mode\n if (isset($reasoningStarted)) {\n $endSignal = '[END_REASONING]<br/><br/>';\n $output .= $endSignal;\n $responsedText .= \"[END_REASONING]\\n\\n\";\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $endSignal;\n echo \"\\n\\n\";\n flush();\n\n unset($reasoningStarted);\n }\n\n if (! $emptyLinesAdded) {\n echo \"event: data\\n\";\n echo 'data: <br/><br/><br/>';\n echo \"\\n\\n\";\n flush();\n $emptyLinesAdded = true;\n }\n\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $delta['content']);\n $output .= $messageFix;\n $responsedText .= $messageFix;\n $total_used_tokens += countWords($messageFix);\n\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n }\n }\n\n if (connection_aborted()) {\n break;\n }\n }\n\n } else {\n ApiHelper::setOpenAiKey();\n $chat_bot = 'gpt-4o';\n $stream = OpenAI::chat()->createStreamed([\n 'model' => $chat_bot,\n 'messages' => $history,\n 'max_tokens' => 2000,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n ]);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n },\n 200,\n [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]\n );\n }\n\n private function deepseekOtherStream(Request $request, $chat_bot)\n {\n ini_set('max_execution_time', 440);\n set_time_limit(0);\n\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n\n $history[] = ['role' => 'user', 'content' => $prompt];\n\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n return response()->stream(function () use (&$total_used_tokens, &$output, &$responsedText, $driver, $message_id, $title, $openai_id, $prompt, $history, $chat_bot) {\n\n $user = Auth::user();\n $entry = UserOpenai::firstOrCreate(\n [\n 'id' => $message_id,\n ],\n [\n 'user_id' => $user->id,\n 'input' => $prompt,\n 'hash' => str()->random(256),\n 'team_id' => $user->team_id,\n 'slug' => str()->random(7) . str($user?->fullName())->slug() . '-workbook',\n 'openai_id' => $openai_id ?? 1,\n ]);\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $client = new Client;\n\n ApiHelper::setDeepseekKey();\n\n $url = 'https://api.deepseek.com/chat/completions';\n $apikey = config('deepseek.api_key');\n $headers = [\n 'Content-Type' => 'application/json',\n 'Accept' => 'application/json',\n 'Authorization' => \"Bearer $apikey\",\n ];\n\n $body = [\n 'messages' => $history,\n 'model' => $chat_bot,\n 'frequency_penalty' => 0,\n 'max_tokens' => (int) setting('deepseek_max_output_length', 200),\n 'presence_penalty' => 0,\n 'response_format' => [\n 'type' => 'text',\n ],\n 'stop' => null,\n 'stream' => true,\n 'stream_options' => null,\n 'temperature' => 1,\n 'top_p' => 1,\n 'tools' => null,\n 'tool_choice' => 'none',\n 'logprobs' => false,\n 'top_logprobs' => null,\n ];\n\n $response = $client->post($url, [\n 'headers' => $headers,\n 'json' => $body,\n ]);\n\n $bodyStream = $response->getBody();\n $buffer = '';\n $emptyLinesAdded = false;\n while (! $bodyStream->eof()) {\n $chunk = $bodyStream->read(1024);\n $buffer .= $chunk;\n\n while (($pos = strpos($buffer, \"\\n\")) !== false) {\n $line = substr($buffer, 0, $pos);\n $buffer = substr($buffer, $pos + 1);\n\n if (str_starts_with(trim($line), 'data: ')) {\n $json = trim(substr($line, 5)); // Remove \"data: \"\n if (! empty($json)) {\n $decoded = json_decode($json, true);\n if (json_last_error() === JSON_ERROR_NONE) {\n $delta = $decoded['choices'][0]['delta'] ?? [];\n if (isset($delta['reasoning_content']) && $delta['reasoning_content'] !== null) {\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $delta['reasoning_content']);\n $output .= $messageFix;\n $responsedText .= $messageFix;\n // $total_used_tokens += countWords($messageFix); do we calculate reasoning content?\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n\n if (isset($delta['content']) && $delta['content'] !== null) {\n if (! $emptyLinesAdded) {\n echo \"event: data\\n\";\n echo 'data: <br/><br/><br/>';\n echo \"\\n\\n\";\n flush();\n $emptyLinesAdded = true;\n }\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $delta['content']);\n\n $output .= $messageFix;\n $responsedText .= $messageFix;\n $total_used_tokens += countWords($messageFix);\n\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n }\n }\n\n if (connection_aborted()) {\n break;\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $entry->update([\n 'title' => $title ?: null,\n 'credits' => $total_used_tokens,\n 'words' => $total_used_tokens,\n 'response' => $responsedText,\n 'output' => $output,\n ]);\n\n $driver->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n /**\n * @throws GuzzleException\n * @throws JsonException\n * @throws Exception\n */\n public function assistantStream(string $chat_bot, $history, $main_message, $assistant): ?StreamedResponse\n {\n $chat = UserOpenaiChat::query()->where('id', $main_message->user_openai_chat_id)->first();\n $threadId = $chat?->thread_id;\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n $assistantService = new AssistantService;\n\n $tmp = $assistantService->createMessage($threadId, $history);\n\n return $assistantService->createRun($chat_bot, $assistant, $threadId, $main_message, $driver);\n }\n\n public function OtherStream(Request $request, string $chat_bot, $ai_engine = null): StreamedResponse\n {\n if (! $ai_engine) {\n $ai_engine = setting('default_ai_engine', EngineEnum::OPEN_AI->value);\n }\n\n if (setting('open_router_status') == 1 && $request->open_router_model !== 'undefined' && ! empty($request->open_router_model)) {\n return $this->openRouterStream($request);\n }\n\n return match ($ai_engine) {\n EngineEnum::ANTHROPIC->value => $this->anthropicOtherStream($request, $chat_bot),\n EngineEnum::GEMINI->value => $this->geminiOtherStream($request, $chat_bot),\n EngineEnum::DEEP_SEEK->value => $this->deepseekOtherStream($request, $chat_bot),\n EngineEnum::X_AI->value \t => $this->xAiOtherStream($request, $chat_bot),\n default => $this->openaiOtherStream($request, $chat_bot),\n };\n }\n\n private function openRouterStream(Request $request)\n {\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n $open_router_model = $request->get('open_router_model');\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $driver = Entity::driver(EntityEnum::fromSlug($open_router_model));\n\n return response()->stream(function () use ($driver, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt, $open_router_model) {\n $user = Auth::user();\n $entry = UserOpenai::find($message_id);\n if (! $entry) {\n $entry = new UserOpenai;\n $entry->user_id = $user?->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user?->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $service = new RouterAiService;\n $response = $service->response($entry->input, $open_router_model);\n\n foreach (explode(\"\\n\", $response) as $line) {\n if (str_starts_with($line, 'data:')) {\n $data = trim(substr($line, 5));\n if ($data === '[DONE]') {\n break;\n }\n\n $json = json_decode($data, true);\n\n if (isset($json['choices'][0]['delta']['content'])) {\n $content = $json['choices'][0]['delta']['content'];\n\n // Boş içerik varsa atla\n if (! empty($content)) {\n $output .= $content;\n $responsedText .= $content;\n $total_used_tokens += str_word_count($content);\n\n $content = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $content);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $content;\n echo \"\\n\\n\";\n flush();\n\n if (connection_aborted()) {\n break;\n }\n }\n }\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n public function reduceTokensWhenIntterruptStream(Request $request, $type): void\n {\n $model = Helper::setting('openai_default_model') ?: EntityEnum::GPT_3_5_TURBO_16K->value;\n $streamed_text = $request->get('streamed_text');\n $message_id = $request->get('streamed_message_id');\n if ($streamed_text) {\n $total_used_tokens = countWords($streamed_text);\n Entity::driver(EntityEnum::fromSlug($model))->input($streamed_text)->calculateCredit()->decreaseCredit();\n if (! empty($message_id)) {\n if ($type === 'writer') {\n $entry = UserOpenai::find($message_id);\n if ($entry) {\n $entry->title = null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $streamed_text;\n $entry->output = $streamed_text;\n $entry->save();\n }\n } else { // chat\n $main_message = UserOpenaiChatMessage::find($message_id);\n if ($main_message) {\n $chat = UserOpenaiChat::find($main_message->user_openai_chat_id);\n $main_message->response = $streamed_text;\n $main_message->output = $streamed_text;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n\n if ($chat) {\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n }\n }\n }\n }\n }\n }\n\n // X-AI Stream\n /**\n * @throws Exception\n */\n private function xAiChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): ?StreamedResponse\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n }\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $model = $driver->enum()->value;\n if ($contain_images) {\n $options = [\n 'model' => EntityEnum::GPT_4_O->value,\n 'messages' => $history,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n 'max_tokens' => 2000,\n ];\n $stream = OpenAI::chat()->createStreamed($options);\n } else {\n $api = ApiHelper::setXAiKey();\n\n try {\n $cli = OpenAIMain::factory()->withBaseUri('https://api.x.ai/v1')\n ->withHttpHeader('Authorization', 'Bearer ' . $api)\n ->withApiKey($api)\n ->make();\n $stream = $cli->chat()->createStreamed([\n 'model' => $model,\n 'messages' => $history,\n 'stream' => true,\n 'temperature' => 1.0,\n ]);\n } catch (Exception|Throwable $e) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('Something went wrong. Please try again later.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n }\n\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n private function xAiOtherStream(Request $request, $chat_bot): ?StreamedResponse\n {\n $apiKey = ApiHelper::setXAiKey();\n $xai = OpenAIMain::factory()\n ->withApiKey($apiKey)\n ->withBaseUri('https://api.x.ai/v1')\n ->make();\n\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n\n $history[] = ['role' => 'user', 'content' => $prompt];\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $user = Auth::user();\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n return response()->stream(static function () use ($user, $driver, $history, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt) {\n $entry = UserOpenai::find($message_id);\n if (! $entry) {\n $entry = new UserOpenai;\n $entry->user_id = $user->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $api = ApiHelper::setXAiKey();\n\n try {\n $cli = OpenAIMain::factory()->withBaseUri('https://api.x.ai/v1')\n ->withHttpHeader('Authorization', 'Bearer ' . $api)\n ->withApiKey($api)\n ->make();\n $stream = $cli->chat()->createStreamed([\n 'model' => $driver->enum()->value,\n 'messages' => $history,\n 'stream' => true,\n 'temperature' => 1.0,\n ]);\n } catch (Exception|Throwable $e) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('Something went wrong. Please try again later.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n // OpenAI Stream\n /**\n * @throws Exception\n */\n private function openaiChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): ?StreamedResponse\n {\n // @todo: in beta entites: EntityEnum::fromSlug($chat_bot)->isBetaEntity() then output without stream, stream not working\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n }\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $model = $driver->enum()->value;\n $options = [\n 'model' => $model,\n 'messages' => $history,\n 'stream' => true,\n ];\n\n if (! in_array($model, [EntityEnum::GPT_4_O_MINI_SEARCH_PREVIEW->value, EntityEnum::GPT_4_O_SEARCH_PREVIEW->value], true)) {\n $options['temperature'] = 1.0;\n $options['frequency_penalty'] = 0;\n $options['presence_penalty'] = 0;\n }\n\n if ($contain_images) {\n $options['max_tokens'] = 2000;\n $options['model'] = EntityEnum::GPT_4_O;\n }\n $stream = OpenAI::chat()->createStreamed($options);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n /**\n * @throws Exception\n */\n private function responsesApiStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): ?StreamedResponse\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n } else {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n }\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $model = $driver->enum()->value;\n $options = [\n 'model' => $model,\n 'messages' => $history,\n 'stream' => true,\n ];\n\n if (! in_array($model, [EntityEnum::GPT_4_O_MINI_SEARCH_PREVIEW->value, EntityEnum::GPT_4_O_SEARCH_PREVIEW->value], true)) {\n $options['temperature'] = 1.0;\n $options['frequency_penalty'] = 0;\n $options['presence_penalty'] = 0;\n }\n\n if ($contain_images) {\n $options['max_tokens'] = 2000;\n $options['model'] = EntityEnum::GPT_4_O;\n\n $stream = OpenAI::chat()->createStreamed($options);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n } else {\n $fileSearchService = new FileSearchService;\n $responsedText = $output = $fileSearchService->searchInFile($options, $chat);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $responsedText;\n echo \"\\n\\n\";\n flush();\n\n $total_used_tokens = countWords($responsedText);\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n private function openaiOtherStream(Request $request, $chat_bot): ?StreamedResponse\n {\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n\n $history[] = ['role' => 'user', 'content' => $prompt];\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $user = Auth::user();\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n return response()->stream(static function () use ($user, $driver, $history, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt) {\n $entry = UserOpenai::find($message_id);\n if (! $entry) {\n $entry = new UserOpenai;\n $entry->user_id = $user->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $stream = OpenAI::chat()->createStreamed([\n 'model' => $driver->enum()->value,\n 'messages' => $history,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n ]);\n\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n // AnthropicService Stream\n private function anthropicChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): ?StreamedResponse\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $client = app(AnthropicService::class);\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n return response()->stream(static function () use ($driver, $client, $history, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n\n if (! $contain_images) {\n $historyMessages = array_filter($history, function ($item) {\n return $item['role'] !== 'system';\n });\n $system = Arr::first(array_filter($history, function ($item) {\n return $item['role'] === 'system';\n }));\n $system = data_get($system, 'content');\n\n if (setting('anthropic_default_model') === BedrockEngine::BEDROCK->value) {\n $bedrockService = new BedrockRuntimeService([\n 'region' => config('filesystems.disks.s3.region'),\n 'version' => 'latest',\n 'credentials' => [\n 'key' => config('filesystems.disks.s3.key'),\n 'secret' => config('filesystems.disks.s3.secret'),\n ],\n ]);\n $responseBody = $bedrockService->invokeClaude($main_message->input);\n $driver = Entity::driver(EntityEnum::CLAUDE_2_1);\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n if ($responseBody) {\n $response = $this->anthropicBedrockResponse($responseBody);\n $output = $response['output'];\n $responsedText = $response['responsedText'];\n $total_used_tokens = $response['total_used_tokens'];\n }\n } else {\n $data = $client->setStream(true)\n ->setSystem($system)\n ->setMessages(array_values($historyMessages))\n ->stream()\n ->body();\n foreach (explode(\"\\n\", $data) as $chunk) {\n if (strlen($chunk) < 6) {\n continue;\n }\n if (! Str::contains($chunk, 'data: ')) {\n continue;\n }\n $chunk = str_replace('data: {', '{', $chunk);\n $jsonData = json_decode($chunk, false, 512, JSON_THROW_ON_ERROR);\n if (isset($jsonData->delta->text)) {\n $message = $jsonData->delta->text;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $message);\n $output .= $messageFix;\n $responsedText .= $message;\n $total_used_tokens += countWords($message);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n if (connection_aborted()) {\n break;\n }\n }\n }\n } else {\n ApiHelper::setOpenAiKey();\n $driver = Entity::driver(EntityEnum::GPT_4_O);\n $stream = OpenAI::chat()->createStreamed([\n 'model' => $driver->enum()->value,\n 'messages' => $history,\n 'max_tokens' => 2000,\n 'temperature' => 1.0,\n 'frequency_penalty' => 0,\n 'presence_penalty' => 0,\n 'stream' => true,\n ]);\n foreach ($stream as $response) {\n if (isset($response->choices[0]->delta->content)) {\n $text = $response->choices[0]->delta->content;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n\n $driver->input($responsedText)->calculateCredit()->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n private function anthropicOtherStream(Request $request, $chat_bot): StreamedResponse\n {\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n $history[] = ['role' => 'user', 'content' => $prompt];\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt) {\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $user = Auth::user();\n $entry = UserOpenai::find($message_id);\n if (is_null($entry)) {\n $entry = new UserOpenai;\n $entry->user_id = $user?->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user?->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n $client = app(AnthropicService::class);\n $historyMessages = array_filter($history, function ($item) {\n return $item['role'] !== 'system';\n });\n $system = Arr::first(array_filter($history, function ($item) {\n return $item['role'] === 'system';\n }));\n\n $system = data_get($system, 'content');\n if (setting('anthropic_default_model') === BedrockEngine::BEDROCK->value) {\n $bedrockService = new BedrockRuntimeService([\n 'region' => config('filesystems.disks.s3.region'),\n 'version' => 'latest',\n 'credentials' => [\n 'key' => config('filesystems.disks.s3.key'),\n 'secret' => config('filesystems.disks.s3.secret'),\n ],\n ]);\n $driver = Entity::driver(EntityEnum::CLAUDE_2_1);\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n $responseBody = $bedrockService->invokeClaude($entry->input);\n if ($responseBody) {\n $response = self::anthropicBedrockResponse($responseBody);\n $output = $response['output'];\n $responsedText = $response['responsedText'];\n $total_used_tokens = $response['total_used_tokens'];\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n }\n\n } else {\n $data = $client->setStream(true)\n ->setSystem($system)\n ->setMessages(array_values($historyMessages))\n ->stream()\n ->body();\n foreach (explode(\"\\n\", $data) as $chunk) {\n if (strlen($chunk) < 6) {\n continue;\n }\n if (! Str::contains($chunk, 'data: ')) {\n continue;\n }\n $chunk = str_replace('data: {', '{', $chunk);\n if (isset(json_decode($chunk, false, 512, JSON_THROW_ON_ERROR)->delta->text)) {\n $message = json_decode($chunk, false, 512, JSON_THROW_ON_ERROR)->delta->text;\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $message);\n $output .= $messageFix;\n $responsedText .= $message;\n $total_used_tokens += countWords($message);\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n if (connection_aborted()) {\n break;\n }\n }\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n }\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n // GeminiService Stream\n private function geminiChatStream(string $chat_bot, $history, $main_message, $chat_type, $contain_images): StreamedResponse\n {\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n $newhistory = convertHistoryToGemini($history);\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n\n if ($contain_images) {\n // I will improve later\n $newhistory = $this->getLastMessageAndImage($newhistory);\n if (count($newhistory['parts']) === 1) {\n $newhistory['parts'][0] = [\n 'text' => $newhistory['parts'][0]['text'],\n ];\n\n $contain_images = false;\n }\n\n $newhistory = [$newhistory];\n }\n\n return response()->stream(static function () use ($driver, $newhistory, &$total_used_tokens, &$output, &$responsedText, $main_message, $contain_images) {\n\n $chat_id = $main_message->user_openai_chat_id;\n $chat = UserOpenaiChat::whereId($chat_id)->first();\n echo \"event: message\\n\";\n echo 'data: ' . $main_message->id . \"\\n\\n\";\n\n if ($contain_images) {\n $driver = Entity::driver(EntityEnum::GEMINI_1_5_FLASH);\n }\n\n if (! $driver->hasCreditBalance()) {\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . __('You have no credits left. Please buy more credits to continue.');\n echo \"\\n\\n\";\n flush();\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n return null;\n }\n\n $client = app(GeminiService::class);\n $response = $client\n ->setHistory($newhistory)\n ->streamGenerateContent($driver->enum()->value);\n\n while (! $response->getBody()->eof()) {\n\n $line = $client->readLine($response->getBody());\n\n try {\n $decodedLine = json_decode($line, true, 512, JSON_THROW_ON_ERROR);\n\n if ($decodedLine === null || ! isset($decodedLine['candidates'])) {\n Log::info('Decoded line does not contain expected data: ' . json_encode($decodedLine));\n\n continue;\n }\n } catch (JsonException $e) {\n Log::error('JSON decoding error: ' . $e->getMessage());\n Log::error('Offending line: ' . $line);\n\n continue;\n }\n\n if ($decodedLine === null || ! isset($decodedLine['candidates'])) {\n continue;\n }\n\n foreach ($decodedLine['candidates'] as $candidate) {\n $text = $candidate['content']['parts'][0]['text'];\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n\n if (connection_aborted()) {\n break;\n }\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $main_message->response = $responsedText;\n $main_message->output = $output;\n $main_message->credits = $total_used_tokens;\n $main_message->words = $total_used_tokens;\n $main_message->save();\n $chat->total_credits += $total_used_tokens;\n $chat->save();\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n public function getLastMessageAndImage($newhistory)\n {\n return Arr::last($newhistory);\n }\n\n private function geminiOtherStream(Request $request, string $chat_bot): StreamedResponse\n {\n $driver = Entity::driver(EntityEnum::fromSlug($chat_bot));\n $prompt = $request->get('prompt');\n $message_id = $request->get('message_id');\n $openai_id = $request->get('openai_id');\n $title = $request->get('title');\n\n $history[] = [\n 'parts' => [\n [\n 'text' => $prompt,\n ],\n ],\n 'role' => 'user',\n ];\n\n $total_used_tokens = 0;\n $output = '';\n $responsedText = '';\n\n return response()->stream(static function () use ($driver, $history, &$total_used_tokens, &$output, &$responsedText, $message_id, $title, $openai_id, $prompt) {\n $user = Auth::user();\n $entry = UserOpenai::find($message_id);\n if (is_null($entry)) {\n $entry = new UserOpenai;\n $entry->user_id = $user->id;\n $entry->input = $prompt;\n $entry->hash = str()->random(256);\n $entry->team_id = $user->team_id;\n $entry->slug = str()->random(7) . str($user?->fullName())->slug() . '-workbook';\n $entry->openai_id = $openai_id ?? 1;\n }\n\n echo \"event: message\\n\";\n echo 'data: ' . $message_id . \"\\n\\n\";\n\n $client = app(GeminiService::class);\n $response = $client\n ->setHistory($history)\n ->streamGenerateContent($driver->enum()->value);\n\n while (! $response->getBody()->eof()) {\n\n $line = $client->readLine($response->getBody());\n\n try {\n $decodedLine = json_decode($line, true, 512, JSON_THROW_ON_ERROR);\n\n if ($decodedLine === null || ! isset($decodedLine['candidates'])) {\n Log::info('Decoded line does not contain expected data: ' . json_encode($decodedLine));\n\n continue;\n }\n } catch (JsonException $e) {\n Log::error('JSON decoding error: ' . $e->getMessage());\n Log::error('Offending line: ' . $line);\n\n continue;\n }\n if ($decodedLine === null || ! isset($decodedLine['candidates'])) {\n continue;\n }\n\n foreach ($decodedLine['candidates'] as $candidate) {\n $text = $candidate['content']['parts'][0]['text'];\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $text);\n $output .= $messageFix;\n $responsedText .= $text;\n $total_used_tokens += countWords($text);\n if (connection_aborted()) {\n break;\n }\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n }\n }\n\n echo \"event: stop\\n\";\n echo 'data: [DONE]';\n echo \"\\n\\n\";\n flush();\n\n $entry->title = $title ?: null;\n $entry->credits = $total_used_tokens;\n $entry->words = $total_used_tokens;\n $entry->response = $responsedText;\n $entry->output = $output;\n $entry->save();\n $driver\n ->input($responsedText)\n ->calculateCredit()\n ->decreaseCredit();\n Usage::getSingle()->updateWordCounts($driver->calculate());\n }, 200, [\n 'Cache-Control' => 'no-cache',\n 'X-Accel-Buffering' => 'no',\n 'Content-Type' => 'text/event-stream',\n ]);\n }\n\n private function anthropicBedrockResponse($responseBody): array\n {\n $completion = $responseBody['completion'];\n $parts = explode(':', $completion, 2);\n if (isset($parts[1])) {\n $completion = trim($parts[1]);\n }\n\n $words = explode(' ', $completion);\n $output = $completion;\n $responsedText = $completion;\n $total_used_tokens = count($words);\n foreach ($words as $word) {\n $messageFix = str_replace([\"\\r\\n\", \"\\r\", \"\\n\"], '<br/>', $word) . ' ';\n\n echo PHP_EOL;\n echo \"event: data\\n\";\n echo 'data: ' . $messageFix;\n echo \"\\n\\n\";\n flush();\n\n if (connection_aborted()) {\n break;\n }\n }\n\n return [\n 'output' => $output,\n 'responsedText' => $responsedText,\n 'total_used_tokens' => $total_used_tokens,\n ];\n }\n}\n"}}}}