From d62e8e45c8012656047dc491f5e3372663cc20f6 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Sat, 22 Feb 2025 17:21:40 +0200 Subject: [PATCH 01/31] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0cd4746..6543f01 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,8 @@ $response = GrokAI::chat( new ChatOptions(model: Model::GROK_2, stream: true) ); ``` -Streaming is useful for chatbots, assistants, and real-time applications. + +> Streaming is useful for chatbots, assistants, and real-time applications. --- ## ๐Ÿงช Testing @@ -162,4 +163,4 @@ Want to improve this package? Check out [CONTRIBUTE.md](CONTRIBUTE.md) for contr ## ๐Ÿ“„ License -This package is open-source software licensed under the [MIT License](LICENSE). \ No newline at end of file +This package is open-source software licensed under the [MIT License](LICENSE). From c76c9208a27021704d095b8320c1a9967663b894 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Sat, 22 Feb 2025 17:45:30 +0200 Subject: [PATCH 02/31] chore: Add funding resource --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..54d42ac --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +github: thefeqy \ No newline at end of file From 60fafc24f5d61d2b79c538eb0fd9b2474814e97a Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Sat, 22 Feb 2025 22:53:51 +0200 Subject: [PATCH 03/31] fix licence URL issue --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6543f01..2b6910a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Leverage **powerful AI models** for **chat, automation, and NLP**, while maintai [![Latest Version](https://img.shields.io/packagist/v/grok-php/laravel)](https://packagist.org/packages/grok-php/laravel) [![PHP Version](https://img.shields.io/badge/PHP-8.1%2B-blue)](https://php.net) [![Laravel Version](https://img.shields.io/badge/Laravel-10%2B-red)](https://laravel.com) -[![License](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE.md) +[![License](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE) --- From ea8efcb50344e25c4ae854122dcb6b8fe5057887 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Mon, 24 Feb 2025 22:58:37 +0200 Subject: [PATCH 04/31] doc: rename CONTRIBUTE.md to CONTRIBUTING.md --- CONTRIBUTE.md => CONTRIBUTING.md | 0 README.md | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename CONTRIBUTE.md => CONTRIBUTING.md (100%) diff --git a/CONTRIBUTE.md b/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTE.md rename to CONTRIBUTING.md diff --git a/README.md b/README.md index 6543f01..c33d8d7 100644 --- a/README.md +++ b/README.md @@ -159,7 +159,7 @@ If you discover a security vulnerability, please report it via email: ## ๐Ÿค Contributing -Want to improve this package? Check out [CONTRIBUTE.md](CONTRIBUTE.md) for contribution guidelines. +Want to improve this package? Check out [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. ## ๐Ÿ“„ License From b75ca56357bae7abb75a6526d360e33754474c36 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Mon, 24 Feb 2025 22:59:06 +0200 Subject: [PATCH 05/31] chore: Ignore unnecessary files & directories --- .gitignore | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 3834427..81d7cc9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,33 @@ -vendor -.env -.env.example +# Composer Related composer.lock +/vendor + +# Frontend Assets +/node_modules + +# Logs +npm-debug.log +yarn-error.log + +# Caches +.phpunit.cache +.phpunit.result.cache +/build + +# Editors +/.idea +/.fleet +/.vscode + +# Code sniffer +.php_cs +.php_cs.cache +.php-cs-fixer.cache + +# Misc +phpunit.xml phpstan.neon -phpunit.xml \ No newline at end of file +psalm.xml +testbench.yaml +/docs +/coverage From 04f9d9053016f4c02e5257a1a8cd875862d722ba Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Mon, 24 Feb 2025 23:07:50 +0200 Subject: [PATCH 06/31] chore: Add default configurations for editor --- .editorconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a7c44dd --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 From d6c42feceb56d118b2338e54e448bdc47bec1359 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Mon, 24 Feb 2025 23:08:12 +0200 Subject: [PATCH 07/31] chore: Ignore exporting unnecessary files while installing --- .gitattributes | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b763db8 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +/.gitattributes export-ignore +/.gitignore export-ignore +/phpunit.xml export-ignore +/phpstan.neon export-ignore +/tests export-ignore +/.editorconfig export-ignore +/CONTRIBUTING.md export-ignore From ffdac5262ae819dc17f15a6037d6606124f56e86 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Mon, 24 Feb 2025 23:08:42 +0200 Subject: [PATCH 08/31] chore: Add laravel pint for formating style --- composer.json | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index e85a533..57304ed 100644 --- a/composer.json +++ b/composer.json @@ -68,15 +68,17 @@ } }, "require-dev": { - "orchestra/testbench": "^8.0", - "phpunit/phpunit": "^10.0", - "mockery/mockery": "^1.6.12", - "phpstan/phpstan": "^1.12" + "laravel/pint": "^1.20", + "phpstan/phpstan": "^1.12", + "mockery/mockery": "^1.6", + "orchestra/testbench": "^9.0", + "phpunit/phpunit": "^11" }, "minimum-stability": "stable", "prefer-stable": true, "scripts": { "test": "vendor/bin/phpunit", - "test:types": "phpstan analyse src --ansi" + "test:types": "phpstan analyse src --ansi", + "format": "vendor/bin/pint" } } From 2ae17c9ab79741d97fe5f05b7d31eb76d4fdeec6 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Mon, 24 Feb 2025 23:09:08 +0200 Subject: [PATCH 09/31] test: Add default configuration file for PHPUnit --- phpunit.xml.dist | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 phpunit.xml.dist diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..b6b887f --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,24 @@ + + + + + + + tests + + + + + + + + + + From 7c600d54f8dbcc047f9f34f3897547c5ce897a73 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Mon, 24 Feb 2025 23:11:23 +0200 Subject: [PATCH 10/31] chore: Update client version v1.3.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 57304ed..f0516c8 100644 --- a/composer.json +++ b/composer.json @@ -49,7 +49,7 @@ "require": { "php": ">=8.1", "laravel/framework": "^10.0|^11.0", - "grok-php/client": "^1.0" + "grok-php/client": "^1.3" }, "autoload": { "psr-4": { From 3c612652623e14dcd0423423505c98f80789ba90 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 00:50:53 +0200 Subject: [PATCH 11/31] chore: Remove version from composer.json --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index f0516c8..81f702b 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,6 @@ "description": "Seamlessly integrate Grok AI into Laravel applications with an elegant, developer-friendly package. Leverage powerful AI models for chat, automation, and NLP while maintaining Laravel's expressive simplicity.", "type": "library", "license": "MIT", - "version": "1.0.0", "homepage": "https://github.com/grok-php/laravel", "support": { "issues": "https://github.com/grok-php/laravel/issues", From 54522803cfed18f816dddb2d7f177c6d40c1d1de Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 00:53:35 +0200 Subject: [PATCH 12/31] fix: configurations file path --- src/Providers/GrokServiceProvider.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Providers/GrokServiceProvider.php b/src/Providers/GrokServiceProvider.php index c293482..69af5b3 100644 --- a/src/Providers/GrokServiceProvider.php +++ b/src/Providers/GrokServiceProvider.php @@ -2,6 +2,7 @@ namespace GrokPHP\Laravel\Providers; +use GrokPHP\Laravel\Commands\InstallGrokCommand; use Illuminate\Support\ServiceProvider; use GrokPHP\Client\Clients\GrokClient; use GrokPHP\Client\Config\GrokConfig; @@ -32,12 +33,12 @@ public function boot(): void { if ($this->app->runningInConsole()) { $this->commands([ - \GrokPHP\Laravel\Commands\InstallGrokCommand::class, + InstallGrokCommand::class, ]); $this->publishes([ - __DIR__ . '/../Config/grok.php' => config_path('grok.php'), - ], 'config'); + __DIR__ . '/../../config/grok.php' => config_path('grok.php'), + ], 'grok-config'); } } } From 0ca7dd52a55dd97ebec1f77f9c1af5d896f851f6 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 00:54:31 +0200 Subject: [PATCH 13/31] chore: add GrokAI Service --- src/Facades/GrokAI.php | 6 ++-- src/Providers/GrokServiceProvider.php | 5 +++ src/Services/GrokAI.php | 48 +++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/Services/GrokAI.php diff --git a/src/Facades/GrokAI.php b/src/Facades/GrokAI.php index 2224739..edcbd8a 100644 --- a/src/Facades/GrokAI.php +++ b/src/Facades/GrokAI.php @@ -2,15 +2,17 @@ namespace GrokPHP\Laravel\Facades; +use GrokPHP\Client\Clients\Vision; use Illuminate\Support\Facades\Facade; /** - * @method static array chat(array $messages, \GrokPHP\Client\Config\ChatOptions $options) + * @method static array chat(array $messages, ?\GrokPHP\Client\Config\ChatOptions $options = null) + * @method static Vision vision() */ class GrokAI extends Facade { protected static function getFacadeAccessor(): string { - return 'grok-ai'; + return \GrokPHP\Laravel\Services\GrokAI::class; } } diff --git a/src/Providers/GrokServiceProvider.php b/src/Providers/GrokServiceProvider.php index 69af5b3..8977aac 100644 --- a/src/Providers/GrokServiceProvider.php +++ b/src/Providers/GrokServiceProvider.php @@ -3,6 +3,7 @@ namespace GrokPHP\Laravel\Providers; use GrokPHP\Laravel\Commands\InstallGrokCommand; +use GrokPHP\Laravel\Services\GrokAI; use Illuminate\Support\ServiceProvider; use GrokPHP\Client\Clients\GrokClient; use GrokPHP\Client\Config\GrokConfig; @@ -26,6 +27,10 @@ public function register(): void return new GrokClient($app->make(GrokConfig::class)); }); + $this->app->singleton(GrokAI::class, function ($app) { + return new GrokAI($app->make(GrokClient::class)); + }); + $this->app->alias(GrokClient::class, 'grok-ai'); } diff --git a/src/Services/GrokAI.php b/src/Services/GrokAI.php new file mode 100644 index 0000000..ca6ebfb --- /dev/null +++ b/src/Services/GrokAI.php @@ -0,0 +1,48 @@ +client = $client; + } + + /** + * Send a chat completion request to Grok API. + * @param array $messages + * @param ChatOptions|null $options + * @return GrokResponse + * @throws GrokException + */ + public function chat(array $messages, ?ChatOptions $options = null): GrokResponse + { + $options = $options ?? new ChatOptions( + model: Model::GROK_2, + temperature: 0.7, + stream: false + ); + + $response = $this->client->chat($messages, $options); + + return new GrokResponse($response); + } + + /** + * Analyze an image using Grok Vision models. + * @return GrokVision + */ + public function vision(): GrokVision + { + return new GrokVision($this->client); + } +} From 68219a7d3794b0e4dbe5289d2c2535fa6637d9ac Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 00:58:40 +0200 Subject: [PATCH 14/31] chore: add Response wrapper --- src/Support/GrokResponse.php | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/Support/GrokResponse.php diff --git a/src/Support/GrokResponse.php b/src/Support/GrokResponse.php new file mode 100644 index 0000000..194dc1c --- /dev/null +++ b/src/Support/GrokResponse.php @@ -0,0 +1,46 @@ +response = $response; + } + + /** + * Get the full API response. + */ + public function full(): array + { + return $this->response; + } + + /** + * Get only the assistant's message content. + */ + public function content(): string + { + return $this->response['choices'][0]['message']['content'] ?? 'No response received.'; + } + + /** + * Get the usage statistics for the API response. + */ + public function usage(): array + { + return $this->response['usage'] ?? []; + } + + /** + * Allow the GrokResponse object to be serialized to JSON. + * @return array + */ + public function jsonSerialize(): array + { + return $this->response; + } +} From 6eea4db609f2b766e46a0e1038e00e1c498bd27f Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 00:59:06 +0200 Subject: [PATCH 15/31] chore: add support for vision models --- src/Services/GrokVision.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/Services/GrokVision.php diff --git a/src/Services/GrokVision.php b/src/Services/GrokVision.php new file mode 100644 index 0000000..b825ad6 --- /dev/null +++ b/src/Services/GrokVision.php @@ -0,0 +1,29 @@ +client = $client; + } + + /** + * Analyze an image using Grok Vision models. + * @throws GrokException + */ + public function analyze(string $imagePath, string $prompt, ?Model $model = null): GrokResponse + { + $response = $this->client->vision()->analyze($imagePath, $prompt, $model); + + return new GrokResponse($response); + } +} From c243f91b831ac617bdea5363a51e4e1847602f66 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 01:53:58 +0200 Subject: [PATCH 16/31] test: remove default apiKey from TestCase.php --- tests/TestCase.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index a6f8cb5..7a85969 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -19,9 +19,4 @@ protected function getPackageAliases($app): array 'GrokAI' => GrokAI::class, ]; } - - protected function defineEnvironment($app) - { - $app['config']->set('grok.api_key', 'test-api-key'); - } } From 27b4c555422fca3079d64ef3be88d0f85d42e7c9 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 01:54:29 +0200 Subject: [PATCH 17/31] test: remove InstallGrokCommandTest --- tests/Feature/InstallGrokCommandTest.php | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 tests/Feature/InstallGrokCommandTest.php diff --git a/tests/Feature/InstallGrokCommandTest.php b/tests/Feature/InstallGrokCommandTest.php deleted file mode 100644 index f25c1c5..0000000 --- a/tests/Feature/InstallGrokCommandTest.php +++ /dev/null @@ -1,22 +0,0 @@ - Date: Tue, 25 Feb 2025 01:55:11 +0200 Subject: [PATCH 18/31] test: GrokServiceProviderTest --- tests/Feature/GrokServiceProviderTest.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/Feature/GrokServiceProviderTest.php b/tests/Feature/GrokServiceProviderTest.php index 6a8b68b..b137e25 100644 --- a/tests/Feature/GrokServiceProviderTest.php +++ b/tests/Feature/GrokServiceProviderTest.php @@ -3,12 +3,15 @@ namespace Tests\Feature; use Tests\TestCase; -use GrokPHP\Client\Clients\GrokClient; +use GrokPHP\Laravel\Services\GrokAI; +use Illuminate\Support\Facades\App; class GrokServiceProviderTest extends TestCase { - public function test_it_registers_the_GrokClient_in_the_service_container() + public function test_it_registers_GrokAI_in_the_service_container() { - // soon ... + $grokAI = App::make(GrokAI::class); + + $this->assertInstanceOf(GrokAI::class, $grokAI); } } From ab77700b4b0796d1c53266db98bfa59146bd14ad Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 01:55:57 +0200 Subject: [PATCH 19/31] chore: Alias GrokAI instead of GrokClient --- src/Providers/GrokServiceProvider.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Providers/GrokServiceProvider.php b/src/Providers/GrokServiceProvider.php index 8977aac..f7a3a06 100644 --- a/src/Providers/GrokServiceProvider.php +++ b/src/Providers/GrokServiceProvider.php @@ -23,15 +23,11 @@ public function register(): void ); }); - $this->app->singleton(GrokClient::class, function ($app) { - return new GrokClient($app->make(GrokConfig::class)); - }); + $this->app->singleton(GrokClient::class, fn ($app) => new GrokClient($app->make(GrokConfig::class))); - $this->app->singleton(GrokAI::class, function ($app) { - return new GrokAI($app->make(GrokClient::class)); - }); + $this->app->singleton(GrokAI::class, fn ($app) => new GrokAI($app->make(GrokClient::class))); - $this->app->alias(GrokClient::class, 'grok-ai'); + $this->app->alias(GrokAI::class, 'grok-ai'); } public function boot(): void From df2e1f2720574a8f91ed98ecb8e22a5cb7d88da3 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 01:56:41 +0200 Subject: [PATCH 20/31] test: Resolve facade correctely --- tests/Feature/GrokFacadeTest.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/Feature/GrokFacadeTest.php b/tests/Feature/GrokFacadeTest.php index 117c688..53b6c6c 100644 --- a/tests/Feature/GrokFacadeTest.php +++ b/tests/Feature/GrokFacadeTest.php @@ -2,16 +2,13 @@ namespace Tests\Feature; +use GrokPHP\Laravel\Services\GrokAI; use Tests\TestCase; -use GrokPHP\Laravel\Facades\GrokAI; -use GrokPHP\Client\Config\ChatOptions; -use GrokPHP\Client\Enums\Model; -use Illuminate\Support\Facades\Http; class GrokFacadeTest extends TestCase { - public function test_it_sends_a_chat_request_and_receives_a_response() + public function test_facade_resolves_correctly() { - // soon ... + $this->assertInstanceOf(GrokAI::class, app('grok-ai')); } } From 4251f6e776eb7d7e54e53fe2ab0301840b748b82 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 01:57:13 +0200 Subject: [PATCH 21/31] test: Default configuration test --- tests/Unit/GrokConfigTest.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/Unit/GrokConfigTest.php b/tests/Unit/GrokConfigTest.php index a531492..fbec723 100644 --- a/tests/Unit/GrokConfigTest.php +++ b/tests/Unit/GrokConfigTest.php @@ -10,6 +10,23 @@ class GrokConfigTest extends TestCase { public function test_it_uses_default_values_when_not_overridden() { - // soon ... + $config = new GrokConfig(apiKey: 'test-api-key'); + + $this->assertEquals('test-api-key', $config->apiKey); + $this->assertEquals(DefaultConfig::BASE_URI->value, $config->baseUri); + $this->assertEquals((int) DefaultConfig::TIMEOUT->value, $config->timeout); + } + + public function test_it_allows_custom_values() + { + $customBaseUri = 'https://custom-api.grok.dev'; + + $config = new GrokConfig( + apiKey: 'test-api-key', + baseUri: $customBaseUri, + ); + + $this->assertEquals('test-api-key', $config->apiKey); + $this->assertEquals($customBaseUri, $config->baseUri); } } From caf8b296bcf894d98c3cea08d0d0b2b5d3c79fdc Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 01:57:42 +0200 Subject: [PATCH 22/31] test: GrokAI facade test --- tests/Feature/GrokAiTest.php | 101 +++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 tests/Feature/GrokAiTest.php diff --git a/tests/Feature/GrokAiTest.php b/tests/Feature/GrokAiTest.php new file mode 100644 index 0000000..d7bc1bf --- /dev/null +++ b/tests/Feature/GrokAiTest.php @@ -0,0 +1,101 @@ + 'user', 'content' => 'Tell me a joke!'] + ])->full(); + + $this->assertArrayHasKey('choices', $response); + $this->assertNotEmpty($response['choices']); + $this->assertEquals('assistant', $response['choices'][0]['message']['role']); + } + + /** + * Test getting only the AI content. + */ + public function test_it_returns_only_ai_response(): void + { + $content = GrokAI::chat([ + ['role' => 'user', 'content' => 'Tell me a joke!'] + ])->content(); + + $this->assertIsString($content); + $this->assertNotEmpty($content); + } + + /** + * Test image analysis using Vision. + */ + public function test_it_can_analyze_an_image(): void + { + $response = GrokAI::vision()->analyze( + 'https://www.shutterstock.com/image-photo/young-english-cocker-spaniel-puppy-600nw-2026045151.jpg', + 'Describe this image' + )->full(); + + $this->assertArrayHasKey('choices', $response); + $this->assertNotEmpty($response['choices']); + $this->assertEquals('assistant', $response['choices'][0]['message']['role']); + } + + /** + * Test exception handling when using an empty API key. + */ + public function test_it_throws_exception_for_empty_api_key(): void + { + config(['grok.api_key' => '']); + + $this->expectException(GrokException::class); + $this->expectExceptionMessage('No API key provided'); + + GrokAI::chat([ + ['role' => 'user', 'content' => 'Tell me a joke!'] + ]); + } + + /** + * Test exception handling when using an invalid API key. + * @return void + */ + public function test_it_throws_exception_for_invalid_api_key(): void + { + config(['grok.api_key' => 'invalid-key']); + + $this->expectException(GrokException::class); + $this->expectExceptionMessageMatches('/Incorrect API key/'); + + GrokAI::chat([ + ['role' => 'user', 'content' => 'Tell me a joke!'] + ]); + } + + /** + * Test exception when using an unsupported model with image input. + */ + public function test_it_throws_exception_for_invalid_model_with_image(): void + { + $this->expectException(GrokException::class); + $this->expectExceptionMessage('The model does not support image input but some images are present in the request.'); + + GrokAI::vision()->analyze( + 'https://www.shutterstock.com/image-photo/young-english-cocker-spaniel-puppy-600nw-2026045151.jpg', + 'What is in this image?', + model: \GrokPHP\Client\Enums\Model::GROK_2 + ); + } +} From 81bc305ea13fe7222ae5cee37634b52684c81a8f Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 01:59:43 +0200 Subject: [PATCH 23/31] ci: Add workflow to fix php code styles on push --- .../workflows/fix-php-code-style-issues.yml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/fix-php-code-style-issues.yml diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml new file mode 100644 index 0000000..1ec8dbf --- /dev/null +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -0,0 +1,28 @@ +name: Fix PHP code style issues + +on: + push: + paths: + - '**.php' + +permissions: + contents: write + +jobs: + php-code-styling: + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + + - name: Fix PHP code style issues + uses: aglipanci/laravel-pint-action@2.5 + + - name: Commit changes + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: Fix styling From 953c9982bf8ffd2465a3dbb1a0e31a43bb560a0d Mon Sep 17 00:00:00 2001 From: thefeqy <44809366+thefeqy@users.noreply.github.com> Date: Tue, 25 Feb 2025 00:01:33 +0000 Subject: [PATCH 24/31] Fix styling --- config/grok.php | 4 ++-- src/Commands/InstallGrokCommand.php | 15 ++++++++++----- src/Providers/GrokServiceProvider.php | 10 +++++----- src/Services/GrokAI.php | 5 +---- src/Services/GrokVision.php | 1 + src/Support/GrokResponse.php | 1 - tests/Feature/GrokAiTest.php | 11 +++++------ tests/Feature/GrokServiceProviderTest.php | 4 ++-- tests/TestCase.php | 4 ++-- tests/Unit/GrokConfigTest.php | 2 +- 10 files changed, 29 insertions(+), 28 deletions(-) diff --git a/config/grok.php b/config/grok.php index 49c04a7..e0089b7 100644 --- a/config/grok.php +++ b/config/grok.php @@ -44,7 +44,7 @@ | Default Temperature |-------------------------------------------------------------------------- | - | Controls the randomness of the AIโ€™s responses. + | Controls the randomness of the AIโ€™s responses. | Lower values (e.g., 0.1) make responses more deterministic, | while higher values (e.g., 1.5) make them more creative. | @@ -56,7 +56,7 @@ | Streaming Mode |-------------------------------------------------------------------------- | - | Enable or disable streaming responses. When enabled, responses + | Enable or disable streaming responses. When enabled, responses | will be returned in real-time as they are generated. | | Accepted values: true or false diff --git a/src/Commands/InstallGrokCommand.php b/src/Commands/InstallGrokCommand.php index 44a9960..5edec4d 100644 --- a/src/Commands/InstallGrokCommand.php +++ b/src/Commands/InstallGrokCommand.php @@ -8,6 +8,7 @@ class InstallGrokCommand extends Command { protected $signature = 'grok:install'; + protected $description = 'Prepares the Grok AI client for use in Laravel.'; private const REPO_URL = 'https://github.com/grok-php/laravel'; @@ -17,6 +18,7 @@ public function handle(): void // Check if the package is already installed if ($this->isAlreadyInstalled()) { $this->warn('โš ๏ธ Grok AI is already installed. No changes were made.'); + return; } @@ -60,6 +62,7 @@ private function copyConfig(): void { if (file_exists(config_path('grok.php'))) { $this->warn('โš ๏ธ Config file already exists: config/grok.php'); + return; } @@ -79,13 +82,14 @@ private function addEnvKeys(string $envFile): void if (! file_exists($filePath)) { $this->warn("โš ๏ธ Skipping: {$envFile} not found."); + return; } $fileContent = file_get_contents($filePath); // Grok AI environment variables with comments - $envSection = <<info("โœ… {$envFile} is already up to date."); + return; } // Append the section to the .env file - file_put_contents($filePath, PHP_EOL . $envSection . PHP_EOL, FILE_APPEND); + file_put_contents($filePath, PHP_EOL.$envSection.PHP_EOL, FILE_APPEND); $this->info("โœ… Added Grok AI environment variables to {$envFile}"); } @@ -133,11 +138,11 @@ private function openRepositoryInBrowser(): void $this->info('Opening GitHub repository... ๐ŸŒ'); if (PHP_OS_FAMILY === 'Darwin') { - exec('open ' . self::REPO_URL); + exec('open '.self::REPO_URL); } elseif (PHP_OS_FAMILY === 'Windows') { - exec('start ' . self::REPO_URL); + exec('start '.self::REPO_URL); } elseif (PHP_OS_FAMILY === 'Linux') { - exec('xdg-open ' . self::REPO_URL); + exec('xdg-open '.self::REPO_URL); } } } diff --git a/src/Providers/GrokServiceProvider.php b/src/Providers/GrokServiceProvider.php index f7a3a06..dfd9627 100644 --- a/src/Providers/GrokServiceProvider.php +++ b/src/Providers/GrokServiceProvider.php @@ -2,18 +2,18 @@ namespace GrokPHP\Laravel\Providers; -use GrokPHP\Laravel\Commands\InstallGrokCommand; -use GrokPHP\Laravel\Services\GrokAI; -use Illuminate\Support\ServiceProvider; use GrokPHP\Client\Clients\GrokClient; use GrokPHP\Client\Config\GrokConfig; use GrokPHP\Client\Enums\DefaultConfig; +use GrokPHP\Laravel\Commands\InstallGrokCommand; +use GrokPHP\Laravel\Services\GrokAI; +use Illuminate\Support\ServiceProvider; class GrokServiceProvider extends ServiceProvider { public function register(): void { - $this->mergeConfigFrom(__DIR__ . '/../../config/grok.php', 'grok'); + $this->mergeConfigFrom(__DIR__.'/../../config/grok.php', 'grok'); $this->app->singleton(GrokConfig::class, function () { return new GrokConfig( @@ -38,7 +38,7 @@ public function boot(): void ]); $this->publishes([ - __DIR__ . '/../../config/grok.php' => config_path('grok.php'), + __DIR__.'/../../config/grok.php' => config_path('grok.php'), ], 'grok-config'); } } diff --git a/src/Services/GrokAI.php b/src/Services/GrokAI.php index ca6ebfb..b97790b 100644 --- a/src/Services/GrokAI.php +++ b/src/Services/GrokAI.php @@ -19,9 +19,7 @@ public function __construct(GrokClient $client) /** * Send a chat completion request to Grok API. - * @param array $messages - * @param ChatOptions|null $options - * @return GrokResponse + * * @throws GrokException */ public function chat(array $messages, ?ChatOptions $options = null): GrokResponse @@ -39,7 +37,6 @@ public function chat(array $messages, ?ChatOptions $options = null): GrokRespons /** * Analyze an image using Grok Vision models. - * @return GrokVision */ public function vision(): GrokVision { diff --git a/src/Services/GrokVision.php b/src/Services/GrokVision.php index b825ad6..9071bac 100644 --- a/src/Services/GrokVision.php +++ b/src/Services/GrokVision.php @@ -18,6 +18,7 @@ public function __construct(GrokClient $client) /** * Analyze an image using Grok Vision models. + * * @throws GrokException */ public function analyze(string $imagePath, string $prompt, ?Model $model = null): GrokResponse diff --git a/src/Support/GrokResponse.php b/src/Support/GrokResponse.php index 194dc1c..2951fa5 100644 --- a/src/Support/GrokResponse.php +++ b/src/Support/GrokResponse.php @@ -37,7 +37,6 @@ public function usage(): array /** * Allow the GrokResponse object to be serialized to JSON. - * @return array */ public function jsonSerialize(): array { diff --git a/tests/Feature/GrokAiTest.php b/tests/Feature/GrokAiTest.php index d7bc1bf..ebd8bc6 100644 --- a/tests/Feature/GrokAiTest.php +++ b/tests/Feature/GrokAiTest.php @@ -2,10 +2,10 @@ namespace Tests\Feature; +use GrokPHP\Client\Exceptions\GrokException; use GrokPHP\Laravel\Facades\GrokAI; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; -use GrokPHP\Client\Exceptions\GrokException; class GrokAiTest extends TestCase { @@ -17,7 +17,7 @@ class GrokAiTest extends TestCase public function test_it_can_send_a_chat_request(): void { $response = GrokAI::chat([ - ['role' => 'user', 'content' => 'Tell me a joke!'] + ['role' => 'user', 'content' => 'Tell me a joke!'], ])->full(); $this->assertArrayHasKey('choices', $response); @@ -31,7 +31,7 @@ public function test_it_can_send_a_chat_request(): void public function test_it_returns_only_ai_response(): void { $content = GrokAI::chat([ - ['role' => 'user', 'content' => 'Tell me a joke!'] + ['role' => 'user', 'content' => 'Tell me a joke!'], ])->content(); $this->assertIsString($content); @@ -64,13 +64,12 @@ public function test_it_throws_exception_for_empty_api_key(): void $this->expectExceptionMessage('No API key provided'); GrokAI::chat([ - ['role' => 'user', 'content' => 'Tell me a joke!'] + ['role' => 'user', 'content' => 'Tell me a joke!'], ]); } /** * Test exception handling when using an invalid API key. - * @return void */ public function test_it_throws_exception_for_invalid_api_key(): void { @@ -80,7 +79,7 @@ public function test_it_throws_exception_for_invalid_api_key(): void $this->expectExceptionMessageMatches('/Incorrect API key/'); GrokAI::chat([ - ['role' => 'user', 'content' => 'Tell me a joke!'] + ['role' => 'user', 'content' => 'Tell me a joke!'], ]); } diff --git a/tests/Feature/GrokServiceProviderTest.php b/tests/Feature/GrokServiceProviderTest.php index b137e25..bf66abb 100644 --- a/tests/Feature/GrokServiceProviderTest.php +++ b/tests/Feature/GrokServiceProviderTest.php @@ -2,13 +2,13 @@ namespace Tests\Feature; -use Tests\TestCase; use GrokPHP\Laravel\Services\GrokAI; use Illuminate\Support\Facades\App; +use Tests\TestCase; class GrokServiceProviderTest extends TestCase { - public function test_it_registers_GrokAI_in_the_service_container() + public function test_it_registers_grok_a_i_in_the_service_container() { $grokAI = App::make(GrokAI::class); diff --git a/tests/TestCase.php b/tests/TestCase.php index 7a85969..ef4f30b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,9 +2,9 @@ namespace Tests; -use Orchestra\Testbench\TestCase as BaseTestCase; -use GrokPHP\Laravel\Providers\GrokServiceProvider; use GrokPHP\Laravel\Facades\GrokAI; +use GrokPHP\Laravel\Providers\GrokServiceProvider; +use Orchestra\Testbench\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase { diff --git a/tests/Unit/GrokConfigTest.php b/tests/Unit/GrokConfigTest.php index fbec723..ac239ac 100644 --- a/tests/Unit/GrokConfigTest.php +++ b/tests/Unit/GrokConfigTest.php @@ -2,9 +2,9 @@ namespace Tests\Unit; -use PHPUnit\Framework\TestCase; use GrokPHP\Client\Config\GrokConfig; use GrokPHP\Client\Enums\DefaultConfig; +use PHPUnit\Framework\TestCase; class GrokConfigTest extends TestCase { From 4095aefe616d0ca9263d46e0752e5f02422f5e97 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 02:09:53 +0200 Subject: [PATCH 25/31] chore: Remove support for PHP 8.1 & add support for 8.2, 8.3, and 8.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 81f702b..e52e1c0 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,7 @@ "AI Developer Tools" ], "require": { - "php": ">=8.1", + "php": "^8.2 || ^8.3 || ^8.4", "laravel/framework": "^10.0|^11.0", "grok-php/client": "^1.3" }, From d47b60b4695ed5cfbf52774c58fa9b66d331f30a Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 02:10:44 +0200 Subject: [PATCH 26/31] chore: Add support for Laravel v12 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e52e1c0..e2238b0 100644 --- a/composer.json +++ b/composer.json @@ -47,7 +47,7 @@ ], "require": { "php": "^8.2 || ^8.3 || ^8.4", - "laravel/framework": "^10.0|^11.0", + "laravel/framework": "^10.0|^11.0|^12.0", "grok-php/client": "^1.3" }, "autoload": { From f362eee7a1d53bbda178766ddefc50395b49c1ca Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 02:30:40 +0200 Subject: [PATCH 27/31] ci: Run PHPUnit tests on push --- .github/workflows/run-tests.yml | 59 +++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/run-tests.yml diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml new file mode 100644 index 0000000..7c5dd8e --- /dev/null +++ b/.github/workflows/run-tests.yml @@ -0,0 +1,59 @@ +name: run-tests + +on: + pull_request: + branches: + - main + push: + paths: + - '**.php' + - '.github/workflows/run-tests.yml' + - 'phpunit.xml.dist' + - 'composer.json' + - 'composer.lock' + +jobs: + test: + runs-on: ${{ matrix.os }} + timeout-minutes: 10 + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + php: [8.3, 8.4] + stability: [prefer-lowest, prefer-stable] + + name: PHP ${{ matrix.php }} - ${{ matrix.stability }} - Laravel Tests + + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Setup PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv, imagick, fileinfo + coverage: none + + - name: Install Dependencies (${{ matrix.stability }}) + run: composer update --${{ matrix.stability }} --prefer-dist --no-interaction + + - name: Configure PHPUnit + run: | + cp phpunit.xml.dist phpunit.xml + sed -i 's|||g' phpunit.xml + + - name: Cache Dependencies + uses: actions/cache@v3 + with: + path: vendor + key: composer-${{ matrix.php }}-${{ matrix.stability }}-${{ hashFiles('composer.lock') }} + restore-keys: | + composer-${{ matrix.php }}-${{ matrix.stability }}- + + - name: List Installed Dependencies + run: composer show -D + + - name: Run PHPUnit Tests + run: vendor/bin/phpunit From 90e768ef39e3d97906fab07184e09601f76219ef Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 02:31:34 +0200 Subject: [PATCH 28/31] doc: Update README.md --- README.md | 166 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 92 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index 40ebc40..bd90536 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,47 @@ -# ๐Ÿง  Grok AI Laravel +### **Grok AI Laravel** -![Grok AI Laravel](assets/images/grok-laravel.png) +**Effortlessly integrate Grok AI into Laravel applications with a clean, developer-friendly package.** +Leverage **powerful AI models** for **chat, automation, vision, and natural language processing (NLP)** while maintaining Laravel's expressive simplicity. -**Seamlessly integrate Grok AI into Laravel applications with an elegant, developer-friendly package.** -Leverage **powerful AI models** for **chat, automation, and NLP**, while maintaining Laravel's expressive simplicity. - -[![Latest Version](https://img.shields.io/packagist/v/grok-php/laravel)](https://packagist.org/packages/grok-php/laravel) -[![PHP Version](https://img.shields.io/badge/PHP-8.1%2B-blue)](https://php.net) -[![Laravel Version](https://img.shields.io/badge/Laravel-10%2B-red)](https://laravel.com) -[![License](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE) +[![Latest Version](https://img.shields.io/packagist/v/grok-php/laravel)](https://packagist.org/packages/grok-php/laravel) +[![PHP Version](https://img.shields.io/badge/PHP-8.2%2B-blue)](https://php.net) +[![Laravel Version](https://img.shields.io/badge/Laravel-10%2B-red)](https://laravel.com) +[![License](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE) +[![Tests](https://github.com/grok-php/laravel/actions/workflows/run-tests.yml/badge.svg)](https://github.com/grok-php/laravel/actions) --- -## ๐Ÿ“– Table of Contents -- [โœจ Features](#-features) -- [๐Ÿ“ฆ Installation](#-installation) -- [๐Ÿš€ Quick Start](#-quick-start) - - [Basic Usage](#basic-usage) - - [Advanced Configuration](#advanced-configuration) -- [๐Ÿ“Œ Available Grok AI Models](#-available-grok-ai-models) -- [โšก Streaming Responses](#-streaming-responses) -- [๐Ÿงช Testing](#-testing) -- [๐Ÿ”’ Security](#-security) -- [๐Ÿค Contributing](#-contributing) -- [๐Ÿ“„ License](#-license) +## Table of Contents + +- [Features](#features) +- [Installation](#installation) +- [Quick Start](#quick-start) + - [Chat API](#chat-api) + - [Vision Analysis](#vision-analysis-image-recognition) + - [Error Handling](#error-handling) +- [Available Grok AI Models](#available-grok-ai-models) +- [Streaming Responses](#streaming-responses) +- [Testing](#testing) +- [Security](#security) +- [Contributing](#contributing) +- [License](#license) --- -## โœจ Features +## Features -โœ… **Seamless Laravel Integration** โ€“ Works effortlessly with Laravel 10+ -โœ… **Simple API Client** โ€“ Access Grok AI models with a fluent, clean syntax -โœ… **Supports All Grok AI Models** โ€“ Choose from multiple **LLM & vision models** -โœ… **Streaming Capable** โ€“ Enable **real-time AI responses** for interactive experiences -โœ… **Configurable Defaults** โ€“ Set your preferred model, temperature, and more +- **Seamless Laravel Integration** โ€“ Works with Laravel 10, 11, and 12 +- **Simple API Client** โ€“ Access Grok AI models with a clean and intuitive API +- **Supports Chat & Vision** โ€“ Send both text and image-based requests +- **Streaming Capable** โ€“ Enable real-time AI responses +- **Configurable Defaults** โ€“ Set model, temperature, and timeout via config --- -## ๐Ÿ“ฆ Installation +## Installation + +Install via Composer: -Install via **Composer**: ```sh composer require grok-php/laravel ``` @@ -49,22 +51,23 @@ After installation, run the setup command: ```sh php artisan grok:install ``` + This command will: - Publish the configuration file (`config/grok.php`). -- Add necessary environment variables to `.env` and `.env.example`. +- Add necessary environment variables to `.env`. Add your API key in `.env`: + ```sh GROK_API_KEY=your-api-key ``` --- +## Quick Start -## ๐Ÿš€ Quick Start - -### Basic Usage +### Chat API ```php use GrokPHP\Laravel\Facades\GrokAI; @@ -76,45 +79,40 @@ $response = GrokAI::chat( new ChatOptions(model: Model::GROK_2) ); -echo $response['choices'][0]['message']['content']; +echo $response->content(); ``` -### ๐Ÿ“Œ Defaults Used: -Model: grok-2 -Temperature: 0.7 -Streaming: false - -### Advanced Configuration -Modify your `config/grok.php` file: +### Vision Analysis (Image Recognition) ```php -return [ - 'api_key' => env('GROK_API_KEY'), - 'base_uri' => env('GROK_BASE_URI', 'https://api.grok.com/v1'), - 'default_model' => env('GROK_DEFAULT_MODEL', 'grok-2'), - 'default_temperature' => env('GROK_DEFAULT_TEMPERATURE', 0.7), - 'enable_streaming' => env('GROK_ENABLE_STREAMING', false), - 'timeout' => env('GROK_API_TIMEOUT', 30), -]; +$response = GrokAI::vision()->analyze( + 'https://example.com/sample.jpg', + 'Describe this image' +); + +echo $response->content(); ``` -๐Ÿ“Œ You can override any setting dynamically: +### Error Handling + +All errors are wrapped in the `GrokException` class: ```php -$response = GrokAI::chat( - [['role' => 'user', 'content' => 'Explain black holes']], - new ChatOptions(model: Model::GROK_2_LATEST, temperature: 1.2, stream: true) -); +use GrokPHP\Client\Exceptions\GrokException; + +try { + $response = GrokAI::chat( + [['role' => 'user', 'content' => 'Hello!']] + ); + echo $response->content(); +} catch (GrokException $e) { + echo "Error: " . $e->getMessage(); +} ``` ---- - - +--- -## ๐Ÿ“Œ Available Grok AI Models -Grok AI offers multiple models, each optimized for different use cases. -These models are available in the Model enum inside our package: -๐Ÿ“„ `src/Enums/Model.php` +## Available Grok AI Models | Model Enum | API Model Name | Description | |-----------------------------|----------------------|-----------------------------------------------------| @@ -127,11 +125,12 @@ These models are available in the Model enum inside our package: | `Model::GROK_2_LATEST` | grok-2-latest | Latest iteration of Grok-2 | | `Model::GROK_BETA` | grok-beta | Experimental beta model | -#### ๐Ÿ“Œ Default model used: `Model::GROK_2` +Default model used: `Model::GROK_2` + --- +## Streaming Responses -## โšก Streaming Responses Enable real-time AI responses by setting `stream: true`: ```php @@ -141,26 +140,45 @@ $response = GrokAI::chat( ); ``` -> Streaming is useful for chatbots, assistants, and real-time applications. +Streaming is useful for chatbots, assistants, and real-time applications. + --- -## ๐Ÿงช Testing -Run tests using Pest PHP: +## Testing + +To run PHPUnit tests, copy the `phpunit.xml.dist` file to `phpunit.xml` and set your API key. + +```sh +cp phpunit.xml.dist phpunit.xml +``` + +```xml + + + +``` + +Now, run the tests: ```sh composer test -or -vendor/bin/phpunit ``` -## ๐Ÿ”’ Security -If you discover a security vulnerability, please report it via email: -๐Ÿ“ฉ [thefeqy@gmail.com](mailto:thefeqy@gmail.com) +--- + +## Security -## ๐Ÿค Contributing +If you discover a security vulnerability, please report it via email: +[thefeqy@gmail.com](mailto:thefeqy@gmail.com) + +--- -Want to improve this package? Check out [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. +## Contributing + +Check out [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on how to contribute. + +--- -## ๐Ÿ“„ License +## License This package is open-source software licensed under the [MIT License](LICENSE). From 2c1d38385cca755f992ac096401a26ac05239188 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 02:37:36 +0200 Subject: [PATCH 29/31] doc: Update CONTRIBUTING.md --- CONTRIBUTING.md | 122 ++++++++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 50 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a86ea7c..5e63e9d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,39 +1,38 @@ -# ๐Ÿ›  Contributing to Grok AI Laravel +# **Contributing to Grok AI Laravel** -First off, thanks for taking the time to contribute! ๐ŸŽ‰ -This guide outlines how you can help improve **Grok AI Laravel** and collaborate effectively. +Thank you for considering contributing to **Grok AI Laravel**. +This guide outlines how you can help improve the package and collaborate effectively. --- -## ๐Ÿ“– Table of Contents -- [๐Ÿš€ Getting Started](#-getting-started) -- [๐Ÿ› Reporting Bugs](#-reporting-bugs) -- [โœจ Feature Requests](#-feature-requests) -- [๐Ÿ›  Development Workflow](#-development-workflow) -- [๐Ÿงช Running Tests](#-running-tests) -- [๐Ÿ™Œ Acknowledgements](#-acknowledgements) +## **Table of Contents** +- [Getting Started](#getting-started) +- [Reporting Bugs](#reporting-bugs) +- [Feature Requests](#feature-requests) +- [Development Workflow](#development-workflow) +- [Running Tests](#running-tests) +- [Acknowledgements](#acknowledgements) --- -## ๐Ÿš€ Getting Started +## **Getting Started** -### 1๏ธโƒฃ Fork the Repository +### 1. Fork the Repository Click the **"Fork"** button at the top right of this repository to create your copy. -### 2๏ธโƒฃ Clone Your Fork +### 2. Clone Your Fork ```sh git clone https://github.com/your-username/laravel-grok.git cd laravel-grok ``` -### 3๏ธโƒฃ Install Dependencies - +### 3. Install Dependencies ```sh composer install ``` -### 4๏ธโƒฃ Link Your Local Package -If you're testing this package inside a Laravel project, you may use: +### 4. Link Your Local Package +If you're testing this package inside a Laravel project, use: ```sh composer remove grok-php/laravel @@ -42,75 +41,98 @@ composer require grok-php/laravel:@dev --prefer-source --- -## ๐Ÿ› Reporting Bugs -Found a bug? Please [open an issue](https://github.com/grok-php/laravel/issues) and include: +## **Reporting Bugs** +If you find a bug, please [open an issue](https://github.com/grok-php/laravel/issues) and include: -- A clear description of the bug. -- Steps to reproduce the issue. -- The expected vs. actual behavior. +- A clear description of the issue. +- Steps to reproduce the problem. +- Expected vs. actual behavior. - Any error messages or logs. -- Your Laravel and PHP version. +- Laravel and PHP versions used. + +Providing as much detail as possible helps resolve the issue faster. --- -## โœจ Feature Requests -Have an idea? We'd love to hear it! -Submit a [feature request](https://github.com/grok-php/laravel/issues) with: +## **Feature Requests** +If you have an idea for improving the package, [submit a feature request](https://github.com/grok-php/laravel/issues) including: -- A detailed explanation of your proposed feature. +- A detailed explanation of the proposed feature. - The problem it solves. - Example use cases. +Well-documented proposals have a higher chance of being implemented. + --- -## ๐Ÿ›  Development Workflow +## **Development Workflow** -1- Create a new branch for your feature or fix: +### 1. Create a New Branch +Before making changes, create a new branch: ```sh -git checkout -b feature/your-new-feature +git checkout -b feature/your-feature-name ``` -2- Make Your Changes & Add Tests -- Follow PSR-12 coding standards. -- Use typed properties, enums, and traits. -- Document your functions with PHPDoc. -- Always write unit tests for new features. - -3- Run tests before committing: +### 2. Implement Your Changes +- Follow **PSR-12** coding standards. +- Use **typed properties, enums, and traits** where applicable. +- Add PHPDoc comments for better readability. +- Ensure backward compatibility. +### 3. Run Tests Before Committing ```sh composer test ``` -4- Commit Your Changes +### 4. Commit Your Changes ```sh git add . -git commit -m "โœจ Added new feature X" +git commit -m "Add feature X" ``` -7- Push to Your Fork - +### 5. Push to Your Fork ```sh -git push origin feature/your-new-feature +git push origin feature/your-feature-name ``` -6- Open a Pull Request (PR) -- Go to [Grok PHP Client Repo](https://github.com/grok-php/laravel/pulls) -- Click "New Pull Request", select your branch, and submit ๐Ÿš€ +### 6. Open a Pull Request +- Navigate to [Grok AI Laravel Pull Requests](https://github.com/grok-php/laravel/pulls). +- Click "New Pull Request", select your branch, and submit. + +A clear and well-documented PR speeds up the review process. --- -## ๐Ÿงช Running Tests -We use PHPUnit for testing. Before submitting your PR, run: +## **Running Tests** +We use **PHPUnit** for testing. Before running tests, copy the PHPUnit configuration file: + +```sh +cp phpunit.xml.dist phpunit.xml +``` + +Then, update your API key inside `phpunit.xml`: + +```xml + + + +``` + +Once configured, run the tests: ```sh composer test +``` or +```sh vendor/bin/phpunit ``` -## ๐Ÿ™Œ Acknowledgements -A huge thank you to everyone contributing! โค๏ธ Your efforts help improve this package for the entire Laravel community. +Ensure all tests pass before submitting a PR. + +--- -๐Ÿš€ Happy coding! \ No newline at end of file +## **Acknowledgements** +Your contributions help make **Grok AI Laravel** better for the Laravel community. +Thank you for taking the time to improve this package. From 4d1a86728684bcd357a722ed71cc7dde6d4ba524 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 02:51:51 +0200 Subject: [PATCH 30/31] doc: Prepare v1.1.0 release --- CHANGELOG.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..173bf76 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog + +All notable changes to `GrokPHP/Laravel` will be documented in this file. +This project follows [Semantic Versioning](https://semver.org/). + +--- + +## [v1.1.0] - 2024-02-25 +### New Features +- **Added Vision API Support**: The package now supports analyzing images using Grok AI Vision models. + - New method: `GrokAI::vision()->analyze($imagePath, $prompt)`. + - Supports models: `grok-2-vision-1212`, `grok-2-vision`, and `grok-2-vision-latest`. + +### Improvements +- **Switched from Pest to PHPUnit** for better Laravel compatibility. +- **Introduced `GrokResponse`**: A response wrapper for easier result handling. +- **Enhanced Exception Handling**: + - Proper error handling for image inputs when used with non-vision models. + - Improved API key error handling. +- **Refactored Service Provider** for better maintainability. +- **Dropped Support for PHP 8.1**: Now requires **PHP 8.2+**. +- **Added Support for Laravel 12**: Compatible with **Laravel 10, 11, and 12**. + +### Internal Changes +- Improved test coverage for **chat and vision API features**. +- Refactored code to follow **SOLID principles**. +- Added GitHub Actions CI workflow to support **PHP 8.3, and 8.4**. + + +--- + +## [v1.0.0] - 2025-02-07 +### Initial Release +- Released `GrokPHP/Laravel` v1.0.0, a Laravel wrapper for **Grok AI Client**. +- Added support for **chat models** with a simple, fluent syntax. + +--- + +### Notes +- For detailed usage, refer to the [README.md](README.md). +- Found an issue? Report it on [GitHub Issues](https://github.com/grok-php/laravel/issues). From 119f91ce0d762938d16fb2263cb67bab06778f82 Mon Sep 17 00:00:00 2001 From: Muhammed ElFeqy Date: Tue, 25 Feb 2025 02:58:07 +0200 Subject: [PATCH 31/31] doc: Update README.md --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bd90536..f9259cf 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,14 @@ ### **Grok AI Laravel** -**Effortlessly integrate Grok AI into Laravel applications with a clean, developer-friendly package.** -Leverage **powerful AI models** for **chat, automation, vision, and natural language processing (NLP)** while maintaining Laravel's expressive simplicity. - -[![Latest Version](https://img.shields.io/packagist/v/grok-php/laravel)](https://packagist.org/packages/grok-php/laravel) -[![PHP Version](https://img.shields.io/badge/PHP-8.2%2B-blue)](https://php.net) -[![Laravel Version](https://img.shields.io/badge/Laravel-10%2B-red)](https://laravel.com) -[![License](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE) -[![Tests](https://github.com/grok-php/laravel/actions/workflows/run-tests.yml/badge.svg)](https://github.com/grok-php/laravel/actions) +A **Laravel integration for the [GrokPHP Client](https://github.com/grok-php/client)**, designed to effortlessly incorporate Grok AI into Laravel applications with a clean and intuitive API. +Utilize **advanced AI models** for **chat, automation, and natural language processing**, all while preserving Laravel's simplicity and elegance. + +[![Latest Version](https://img.shields.io/packagist/v/grok-php/laravel)](https://packagist.org/packages/grok-php/laravel) +[![PHP Version](https://img.shields.io/badge/PHP-8.2%2B-blue)](https://php.net) +[![Laravel Version](https://img.shields.io/badge/Laravel-10%2B-red)](https://laravel.com) +[![Total Downloads](https://img.shields.io/packagist/dt/grok-php/laravel)](https://packagist.org/packages/grok-php/laravel) +![GitHub Workflow Status](https://github.com/grok-php/laravel/actions/workflows/run-tests.yml/badge.svg) +[![License](https://img.shields.io/badge/license-MIT-brightgreen)](LICENSE) ---