From 653ef0304f2976dd3638cc61958ab1598f190031 Mon Sep 17 00:00:00 2001 From: Ashley Johnson <61059402+PapaRascal2020@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:34:40 +0100 Subject: [PATCH] bug(SK): Fixed issues with Utilities & Refactored --- src/Drivers/OpenAi.php | 11 ++- src/Utilities/GptUtilities.php | 127 --------------------------------- src/Utilities/OpenAiExtras.php | 43 +++++++++++ src/Utilities/Utilities.php | 101 +++++++++++++++++++++++--- tests/Unit/UtilitiesTest.php | 10 +-- 5 files changed, 144 insertions(+), 148 deletions(-) delete mode 100644 src/Utilities/GptUtilities.php create mode 100644 src/Utilities/OpenAiExtras.php diff --git a/src/Drivers/OpenAi.php b/src/Drivers/OpenAi.php index 44465fb..c0a8247 100644 --- a/src/Drivers/OpenAi.php +++ b/src/Drivers/OpenAi.php @@ -3,10 +3,9 @@ namespace PapaRascalDev\Sidekick\Drivers; use Generator; -use PapaRascalDev\Sidekick\Features\{Audio, Completion, Embedding, Image, Moderate, StreamedCompletion, Transcribe}; +use PapaRascalDev\Sidekick\Features\{Audio, Completion, Embedding, Image, Moderate, Transcribe}; use PapaRascalDev\Sidekick\SidekickDriverInterface; -use PapaRascalDev\Sidekick\Utilities\GptUtilities; -use Symfony\Component\HttpFoundation\StreamedResponse; +use PapaRascalDev\Sidekick\Utilities\OpenAiExtras; /** * Supported Models: @@ -193,11 +192,11 @@ public function moderate(): Moderate } /** - * @return GptUtilities + * @return OpenAiExtras */ - public function utilities(): GptUtilities + public function utilities(): OpenAiExtras { - return new GptUtilities($this); + return new OpenAiExtras($this); } /** diff --git a/src/Utilities/GptUtilities.php b/src/Utilities/GptUtilities.php deleted file mode 100644 index 5628366..0000000 --- a/src/Utilities/GptUtilities.php +++ /dev/null @@ -1,127 +0,0 @@ -sidekick->moderate()->text(model: $model, content: $content); - - if(!isset($response['results']['categories'])) return false; - - foreach($response['results']['categories'] as $category => $bool) { - if (!in_array($category, $exclusions) && $bool) return true; - } - - return false; - } - - /** - * @param string $data - * @param string|null $mimeType - * @return string - * @throws \Exception - */ - public function store(string $data, string $mimeType = null): string - { - // Determine the type of data - if ($this->isBase64($data) ) { - $data = base64_decode($data); - } elseif ($this->isUrl($data)) { - $data = file_get_contents($data); - } else { - if (!$this->isBinary($data)) { - throw new \Exception("Cannot create file. Invalid data passed."); - } - } - - // Determine the extension - $ext = $this->getExtensionFromMimeType($mimeType); - - // Generate a unique filename - $filename = uniqid() . '.' . $ext; - $filePath = public_path('uploads/' . $filename); - - // Ensure the uploads directory exists - if (!file_exists(public_path('uploads'))) { - mkdir(public_path('uploads'), 0777, true); - } - - // Store the file - file_put_contents($filePath, $data); - - // Return the local path of the stored file - return $filePath; - } - - /** - * @param $data - * @return bool - */ - private function isBase64($data): bool - { - // Check if the data is base64 encoded - return base64_encode(base64_decode($data, true)) === $data; - } - - /** - * @param $data - * @return bool - */ - private function isBinary($data): bool - { - // Check if the data is binary - return preg_match('~[^\x20-\x7E\t\r\n]~', $data) > 0; - } - - /** - * @param $data - * @return bool - */ - private function isUrl($data): bool - { - // Check if the data is a valid URL - return filter_var($data, FILTER_VALIDATE_URL) !== false; - } - - /** - * @param $mimeType - * @return string - * @throws \Exception - */ - private function getExtensionFromMimeType($mimeType): string - { - // Map MIME types to file extensions - $mimeTypes = [ - 'image/jpeg' => 'jpg', - 'image/png' => 'png', - 'image/gif' => 'gif', - 'audio/mpeg' => 'mp3' - ]; - - return $mimeTypes[$mimeType] ?? throw new \Exception("Mime-type $mimeType is not supported"); - } -} diff --git a/src/Utilities/OpenAiExtras.php b/src/Utilities/OpenAiExtras.php new file mode 100644 index 0000000..4dd8198 --- /dev/null +++ b/src/Utilities/OpenAiExtras.php @@ -0,0 +1,43 @@ +sidekick->moderate() + ->text( model: $model, + content: $content); + + if(!isset($response['results']['categories'])) return false; + + foreach($response['results']['categories'] as $category => $bool) { + if (!in_array($category, $exclusions) && $bool) return true; + } + + return false; + } +} diff --git a/src/Utilities/Utilities.php b/src/Utilities/Utilities.php index 59d4041..3385d3f 100644 --- a/src/Utilities/Utilities.php +++ b/src/Utilities/Utilities.php @@ -34,12 +34,12 @@ public function summarize ( { $systemPrompt = "Your task is to take the given text provided by the user and summarize it in under $maxCharLength characters."; - $response = $this->sidekick->complete()->sendMessage( + return $this->sidekick->complete( model: $this->sidekick->defaultCompleteModel, systemPrompt: $systemPrompt, - message: $content); + message: $content + ); - return $this->sidekick->getResponse($response) ?? throw new \Exception("Something went wrong, please try again later."); } /** @@ -52,13 +52,12 @@ public function extractKeywords( string $text, ): string { - $response = $this->sidekick->complete()->sendMessage( + return $this->sidekick->complete()->sendMessage( model: $this->sidekick->defaultCompleteModel, systemPrompt: "Extract important keywords from the following text and separate them by commas:", message: $text ); - return $this->sidekick->getResponse($response) ?? throw new \Exception("Something went wrong, please try again later."); } /** @@ -73,13 +72,11 @@ public function translateText( ): string { $systemPrompt = "Translate the following text to {$targetLanguage}:"; - $response = $this->sidekick->complete()->sendMessage( + return $this->sidekick->complete( model: $this->sidekick->defaultCompleteModel, systemPrompt: $systemPrompt, message: $text ); - - return $this->sidekick->getResponse($response) ?? throw new \Exception("Something went wrong, please try again later."); } /** @@ -93,13 +90,97 @@ public function generateContent( int $maxTokens = 1024 ): string { - $response = $this->sidekick->complete()->sendMessage( + return $this->sidekick->complete( model: $this->sidekick->defaultCompleteModel, systemPrompt: "Generate content based on the following prompt:", message: $prompt, maxTokens: $maxTokens ); + } + + /** + * @param string $data + * @param string|null $mimeType + * @return string + * @throws \Exception + */ + public function store(string $data, string $mimeType = null): string + { + // Determine the type of data + if ($this->isBase64($data) ) { + $data = base64_decode($data); + } elseif ($this->isUrl($data)) { + $data = file_get_contents($data); + } else { + if (!$this->isBinary($data)) { + throw new \Exception("Cannot create file. Invalid data passed."); + } + } + + // Determine the extension + $ext = $this->getExtensionFromMimeType($mimeType); + + // Generate a unique filename + $filename = uniqid() . '.' . $ext; + $filePath = public_path('uploads/' . $filename); + + // Ensure the uploads directory exists + if (!file_exists(public_path('uploads'))) { + mkdir(public_path('uploads'), 0777, true); + } + + // Store the file + file_put_contents($filePath, $data); + + // Return the local path of the stored file + return $filePath; + } + + /** + * @param $data + * @return bool + */ + private function isBase64($data): bool + { + // Check if the data is base64 encoded + return base64_encode(base64_decode($data, true)) === $data; + } - return $this->sidekick->getResponse($response) ?? throw new \Exception("Something went wrong, please try again later."); + /** + * @param $data + * @return bool + */ + private function isBinary($data): bool + { + // Check if the data is binary + return preg_match('~[^\x20-\x7E\t\r\n]~', $data) > 0; + } + + /** + * @param $data + * @return bool + */ + private function isUrl($data): bool + { + // Check if the data is a valid URL + return filter_var($data, FILTER_VALIDATE_URL) !== false; + } + + /** + * @param $mimeType + * @return string + * @throws \Exception + */ + private function getExtensionFromMimeType($mimeType): string + { + // Map MIME types to file extensions + $mimeTypes = [ + 'image/jpeg' => 'jpg', + 'image/png' => 'png', + 'image/gif' => 'gif', + 'audio/mpeg' => 'mp3' + ]; + + return $mimeTypes[$mimeType] ?? throw new \Exception("Mime-type $mimeType is not supported"); } } diff --git a/tests/Unit/UtilitiesTest.php b/tests/Unit/UtilitiesTest.php index d57a730..1050633 100644 --- a/tests/Unit/UtilitiesTest.php +++ b/tests/Unit/UtilitiesTest.php @@ -4,7 +4,7 @@ use PapaRascalDev\Sidekick\Drivers\OpenAi; use PapaRascalDev\Sidekick\Features\Completion; use PapaRascalDev\Sidekick\SidekickDriverInterface; -use PapaRascalDev\Sidekick\Utilities\GptUtilities; +use PapaRascalDev\Sidekick\Utilities\OpenAiExtras; use PHPUnit\Framework\TestCase; class UtilitiesTest extends TestCase @@ -23,7 +23,7 @@ public function testSummarize() $content = 'Some long content'; $expectedResponse = 'summary text'; - $gptUtilitiesMock = $this->createMock(GptUtilities::class); + $gptUtilitiesMock = $this->createMock(OpenAi::class); $gptUtilitiesMock->method('summarize')->willReturn($expectedResponse); $this->sidekickMock->method('utilities')->willReturn($gptUtilitiesMock); @@ -38,7 +38,7 @@ public function testExtractKeywords() $text = "This is a text with important keywords."; $expectedResponse = "text, important, keywords"; - $gptUtilitiesMock = $this->createMock(GptUtilities::class); + $gptUtilitiesMock = $this->createMock(OpenAi::class); $gptUtilitiesMock->method('extractKeywords')->willReturn($expectedResponse); $this->sidekickMock->method('utilities')->willReturn($gptUtilitiesMock); @@ -53,7 +53,7 @@ public function testTranslateText() $targetLanguage = "Spanish"; $expectedResponse = "Hola, mundo!"; - $gptUtilitiesMock = $this->createMock(GptUtilities::class); + $gptUtilitiesMock = $this->createMock(OpenAi::class); $gptUtilitiesMock->method('translateText')->willReturn($expectedResponse); $this->sidekickMock->method('utilities')->willReturn($gptUtilitiesMock); @@ -67,7 +67,7 @@ public function testGenerateContent() $prompt = "Write a story about a brave knight."; $expectedResponse = "Once upon a time, there was a brave knight..."; - $gptUtilitiesMock = $this->createMock(GptUtilities::class); + $gptUtilitiesMock = $this->createMock(OpenAi::class); $gptUtilitiesMock->method('generateContent')->willReturn($expectedResponse); $this->sidekickMock->method('utilities')->willReturn($gptUtilitiesMock);