From c193e482ac4af29e50cef81d3f4a4e2808df1bed Mon Sep 17 00:00:00 2001 From: boban Date: Sat, 16 May 2026 08:06:11 +0200 Subject: [PATCH] feat(ai): AiService (Anthropic adapter), GenerateSlug action Implement AI domain with Anthropic API integration for slug generation. Adds GenerateSlug action for URL-to-slug transformation and GenerateAbVariants for A/B test variants. Includes test coverage for GenerateSlug action with mocked AiService. Co-Authored-By: Claude Sonnet 4.6 --- app/Domains/Ai/Actions/GenerateAbVariants.php | 26 +++++++++++++++++ app/Domains/Ai/Actions/GenerateSlug.php | 19 ++++++++++++ app/Domains/Ai/Services/AiService.php | 29 +++++++++++++++++++ config/services.php | 4 +++ tests/Unit/Ai/GenerateSlugTest.php | 16 ++++++++++ 5 files changed, 94 insertions(+) create mode 100644 app/Domains/Ai/Actions/GenerateAbVariants.php create mode 100644 app/Domains/Ai/Actions/GenerateSlug.php create mode 100644 app/Domains/Ai/Services/AiService.php create mode 100644 tests/Unit/Ai/GenerateSlugTest.php diff --git a/app/Domains/Ai/Actions/GenerateAbVariants.php b/app/Domains/Ai/Actions/GenerateAbVariants.php new file mode 100644 index 0000000..c1b1c27 --- /dev/null +++ b/app/Domains/Ai/Actions/GenerateAbVariants.php @@ -0,0 +1,26 @@ +ai->complete($prompt); + + if (empty($result)) { + return []; + } + + return array_map( + fn($s) => preg_replace('/[^a-z0-9-]/', '', strtolower(trim($s))), + explode(',', $result) + ); + } +} diff --git a/app/Domains/Ai/Actions/GenerateSlug.php b/app/Domains/Ai/Actions/GenerateSlug.php new file mode 100644 index 0000000..7b0ce77 --- /dev/null +++ b/app/Domains/Ai/Actions/GenerateSlug.php @@ -0,0 +1,19 @@ +ai->complete($prompt); + + return preg_replace('/[^a-z0-9-]/', '', strtolower($slug)); + } +} diff --git a/app/Domains/Ai/Services/AiService.php b/app/Domains/Ai/Services/AiService.php new file mode 100644 index 0000000..786946a --- /dev/null +++ b/app/Domains/Ai/Services/AiService.php @@ -0,0 +1,29 @@ + $apiKey, + 'anthropic-version' => '2023-06-01', + 'content-type' => 'application/json', + ])->post('https://api.anthropic.com/v1/messages', [ + 'model' => $model, + 'max_tokens' => 256, + 'messages' => [['role' => 'user', 'content' => $prompt]], + ]); + + return trim($response->json('content.0.text') ?? ''); + } +} diff --git a/config/services.php b/config/services.php index 6a90eb8..6c78493 100644 --- a/config/services.php +++ b/config/services.php @@ -35,4 +35,8 @@ return [ ], ], + 'anthropic' => [ + 'api_key' => env('ANTHROPIC_API_KEY'), + ], + ]; diff --git a/tests/Unit/Ai/GenerateSlugTest.php b/tests/Unit/Ai/GenerateSlugTest.php new file mode 100644 index 0000000..abe4ee9 --- /dev/null +++ b/tests/Unit/Ai/GenerateSlugTest.php @@ -0,0 +1,16 @@ +shouldReceive('complete') + ->once() + ->andReturn('best-promo'); + + $action = new GenerateSlug($mockAi); + $slug = $action->handle('https://example.com/summer-sale-2026'); + + expect($slug)->toBe('best-promo'); +});