From cd768e74bcf54207c836d478a2e0d98680b77721 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Sat, 5 Oct 2024 23:08:43 +0200 Subject: [PATCH 1/9] refactor: Remove superflous header (#127) --- src/Platform/Anthropic.php | 1 - src/Platform/OpenAI/Azure.php | 1 - src/Platform/OpenAI/OpenAI.php | 3 +-- src/Platform/Voyage.php | 1 - src/Store/Azure/SearchStore.php | 1 - 5 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Platform/Anthropic.php b/src/Platform/Anthropic.php index 2f2beff6..e64eb37a 100644 --- a/src/Platform/Anthropic.php +++ b/src/Platform/Anthropic.php @@ -30,7 +30,6 @@ public function request(array $body): iterable $response = $this->httpClient->request('POST', 'https://api.anthropic.com/v1/messages', [ 'headers' => [ 'x-api-key' => $this->apiKey, - 'Content-Type' => 'application/json', 'anthropic-version' => '2023-06-01', ], 'json' => $body, diff --git a/src/Platform/OpenAI/Azure.php b/src/Platform/OpenAI/Azure.php index 8226e7f0..c06d270f 100644 --- a/src/Platform/OpenAI/Azure.php +++ b/src/Platform/OpenAI/Azure.php @@ -29,7 +29,6 @@ protected function rawRequest(string $endpoint, array $body): ResponseInterface return $this->httpClient->request('POST', $url, [ 'headers' => [ 'api-key' => $this->apiKey, - 'Content-Type' => 'application/json', ], 'query' => ['api-version' => $this->apiVersion], 'json' => $body, diff --git a/src/Platform/OpenAI/OpenAI.php b/src/Platform/OpenAI/OpenAI.php index 0a93bdc9..af0252ac 100644 --- a/src/Platform/OpenAI/OpenAI.php +++ b/src/Platform/OpenAI/OpenAI.php @@ -25,8 +25,7 @@ protected function rawRequest(string $endpoint, array $body): ResponseInterface return $this->httpClient->request('POST', $url, [ 'auth_bearer' => $this->apiKey, - 'headers' => ['Content-Type' => 'application/json'], - 'body' => json_encode($body), + 'json' => $body, ]); } } diff --git a/src/Platform/Voyage.php b/src/Platform/Voyage.php index 18fc361d..0671596e 100644 --- a/src/Platform/Voyage.php +++ b/src/Platform/Voyage.php @@ -22,7 +22,6 @@ public function __construct( public function request(array $body): array { $response = $this->httpClient->request('POST', 'https://api.voyageai.com/v1/embeddings', [ - 'headers' => ['Content-Type' => 'application/json'], 'auth_bearer' => $this->apiKey, 'json' => $body, ]); diff --git a/src/Store/Azure/SearchStore.php b/src/Store/Azure/SearchStore.php index 8bfcb636..b8ac89e2 100644 --- a/src/Store/Azure/SearchStore.php +++ b/src/Store/Azure/SearchStore.php @@ -54,7 +54,6 @@ private function request(string $endpoint, array $payload): array $response = $this->httpClient->request('POST', $url, [ 'headers' => [ 'api-key' => $this->apiKey, - 'Content-Type' => 'application/json', ], 'query' => ['api-version' => $this->apiVersion], 'json' => $payload, From 7b72d93b8a93f6f7bbb0bda4da5e156315183462 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Sat, 5 Oct 2024 23:13:42 +0200 Subject: [PATCH 2/9] tests: Move classes to `Fixture` dir (#130) --- examples/structured-output-math.php | 2 +- .../Data => Fixture/StructuredOutput}/MathReasoning.php | 2 +- .../Data => Fixture/StructuredOutput}/Step.php | 2 +- .../Data => Fixture/StructuredOutput}/User.php | 2 +- tests/StructuredOutput/ResponseFormatFactoryTest.php | 2 +- tests/StructuredOutput/SchemaFactoryTest.php | 6 +++--- 6 files changed, 8 insertions(+), 8 deletions(-) rename tests/{StructuredOutput/Data => Fixture/StructuredOutput}/MathReasoning.php (79%) rename tests/{StructuredOutput/Data => Fixture/StructuredOutput}/Step.php (74%) rename tests/{StructuredOutput/Data => Fixture/StructuredOutput}/User.php (80%) diff --git a/examples/structured-output-math.php b/examples/structured-output-math.php index 28f8d680..c833f2ef 100644 --- a/examples/structured-output-math.php +++ b/examples/structured-output-math.php @@ -7,7 +7,7 @@ use PhpLlm\LlmChain\Platform\OpenAI\OpenAI; use PhpLlm\LlmChain\StructuredOutput\ChainProcessor; use PhpLlm\LlmChain\StructuredOutput\ResponseFormatFactory; -use PhpLlm\LlmChain\Tests\StructuredOutput\Data\MathReasoning; +use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\MathReasoning; use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\Serializer\Encoder\JsonEncoder; diff --git a/tests/StructuredOutput/Data/MathReasoning.php b/tests/Fixture/StructuredOutput/MathReasoning.php similarity index 79% rename from tests/StructuredOutput/Data/MathReasoning.php rename to tests/Fixture/StructuredOutput/MathReasoning.php index 1c74435a..f0f6c87d 100644 --- a/tests/StructuredOutput/Data/MathReasoning.php +++ b/tests/Fixture/StructuredOutput/MathReasoning.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpLlm\LlmChain\Tests\StructuredOutput\Data; +namespace PhpLlm\LlmChain\Tests\Fixture\StructuredOutput; final class MathReasoning { diff --git a/tests/StructuredOutput/Data/Step.php b/tests/Fixture/StructuredOutput/Step.php similarity index 74% rename from tests/StructuredOutput/Data/Step.php rename to tests/Fixture/StructuredOutput/Step.php index 4738ac47..028ecc5b 100644 --- a/tests/StructuredOutput/Data/Step.php +++ b/tests/Fixture/StructuredOutput/Step.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpLlm\LlmChain\Tests\StructuredOutput\Data; +namespace PhpLlm\LlmChain\Tests\Fixture\StructuredOutput; final class Step { diff --git a/tests/StructuredOutput/Data/User.php b/tests/Fixture/StructuredOutput/User.php similarity index 80% rename from tests/StructuredOutput/Data/User.php rename to tests/Fixture/StructuredOutput/User.php index 0e7d5161..50220df1 100644 --- a/tests/StructuredOutput/Data/User.php +++ b/tests/Fixture/StructuredOutput/User.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace PhpLlm\LlmChain\Tests\StructuredOutput\Data; +namespace PhpLlm\LlmChain\Tests\Fixture\StructuredOutput; final class User { diff --git a/tests/StructuredOutput/ResponseFormatFactoryTest.php b/tests/StructuredOutput/ResponseFormatFactoryTest.php index 29067c9f..bd9f736d 100644 --- a/tests/StructuredOutput/ResponseFormatFactoryTest.php +++ b/tests/StructuredOutput/ResponseFormatFactoryTest.php @@ -6,7 +6,7 @@ use PhpLlm\LlmChain\StructuredOutput\ResponseFormatFactory; use PhpLlm\LlmChain\StructuredOutput\SchemaFactory; -use PhpLlm\LlmChain\Tests\StructuredOutput\Data\User; +use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\User; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\UsesClass; diff --git a/tests/StructuredOutput/SchemaFactoryTest.php b/tests/StructuredOutput/SchemaFactoryTest.php index 3695a362..7069f8c9 100644 --- a/tests/StructuredOutput/SchemaFactoryTest.php +++ b/tests/StructuredOutput/SchemaFactoryTest.php @@ -5,9 +5,9 @@ namespace PhpLlm\LlmChain\Tests\StructuredOutput; use PhpLlm\LlmChain\StructuredOutput\SchemaFactory; -use PhpLlm\LlmChain\Tests\StructuredOutput\Data\MathReasoning; -use PhpLlm\LlmChain\Tests\StructuredOutput\Data\Step; -use PhpLlm\LlmChain\Tests\StructuredOutput\Data\User; +use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\MathReasoning; +use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\Step; +use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\User; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; From e41cedb70f8d0531bf7d3a3102225796d6d53151 Mon Sep 17 00:00:00 2001 From: Christopher Hertel Date: Sat, 5 Oct 2024 23:33:13 +0200 Subject: [PATCH 3/9] fix: remove clock suggestion since it is mandatory nowadays (#133) --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index cb95d2f4..002d70a2 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,6 @@ "codewithkyrian/chromadb-php": "For using the ChromaDB as retrieval vector store.", "mongodb/mongodb": "For using MongoDB Atlas as retrieval vector store.", "probots-io/pinecone-php": "For using the Pinecone as retrieval vector store.", - "symfony/clock": "For using the clock tool.", "symfony/css-selector": "For using the YouTube transcription tool.", "symfony/dom-crawler": "For using the YouTube transcription tool." }, From 59b442f5c76068f8f54e83879c809d486bd4bf5f Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Sat, 5 Oct 2024 22:40:53 +0200 Subject: [PATCH 4/9] LLama prompt --- src/Model/Language/Llama.php | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/Model/Language/Llama.php b/src/Model/Language/Llama.php index cd04186a..873abcea 100644 --- a/src/Model/Language/Llama.php +++ b/src/Model/Language/Llama.php @@ -5,7 +5,11 @@ namespace PhpLlm\LlmChain\Model\Language; use PhpLlm\LlmChain\LanguageModel; +use PhpLlm\LlmChain\Message\AssistantMessage; +use PhpLlm\LlmChain\Message\Message; use PhpLlm\LlmChain\Message\MessageBag; +use PhpLlm\LlmChain\Message\MessageInterface; +use PhpLlm\LlmChain\Message\UserMessage; use PhpLlm\LlmChain\Platform\Ollama; use PhpLlm\LlmChain\Platform\Replicate; use PhpLlm\LlmChain\Response\TextResponse; @@ -22,14 +26,37 @@ public function call(MessageBag $messages, array $options = []): TextResponse $systemMessage = $messages->getSystemMessage(); $endpoint = $this->platform instanceof Replicate ? 'predictions' : 'chat'; + $response = $this->platform->request('meta/meta-llama-3.1-405b-instruct', $endpoint, [ 'system' => $systemMessage?->content, - 'prompt' => $messages->withoutSystemMessage()->getIterator()->current()->content[0]->text, // @phpstan-ignore-line TODO: Multiple messages + 'prompt' => self::convertToPrompt($messages->withoutSystemMessage()), ]); return new TextResponse(implode('', $response['output'])); } + private static function convertToPrompt(MessageBag $messageBag): string + { + $messages = []; + + /** @var MessageInterface $message */ + foreach ($messageBag->getIterator() as $message) { + if ($message instanceof UserMessage) { + $content = $message->content[0]->text; + } + + elseif ($message instanceof AssistantMessage && $message->content !== null) { + $content = $message->content; + } else { + continue; + } + + $messages[] = sprintf('%s: %s', ucfirst($message->getRole()->value), $message->content[0]->text); + } + + return implode(PHP_EOL, $messages); + } + public function supportsToolCalling(): bool { return false; // it does, but implementation here is still open. From e57188b860bf270ce8d058a27a966d9cdf3fe9f2 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Sat, 5 Oct 2024 22:42:28 +0200 Subject: [PATCH 5/9] - --- src/Model/Language/Llama.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Model/Language/Llama.php b/src/Model/Language/Llama.php index 873abcea..cde192ca 100644 --- a/src/Model/Language/Llama.php +++ b/src/Model/Language/Llama.php @@ -6,7 +6,6 @@ use PhpLlm\LlmChain\LanguageModel; use PhpLlm\LlmChain\Message\AssistantMessage; -use PhpLlm\LlmChain\Message\Message; use PhpLlm\LlmChain\Message\MessageBag; use PhpLlm\LlmChain\Message\MessageInterface; use PhpLlm\LlmChain\Message\UserMessage; @@ -26,7 +25,6 @@ public function call(MessageBag $messages, array $options = []): TextResponse $systemMessage = $messages->getSystemMessage(); $endpoint = $this->platform instanceof Replicate ? 'predictions' : 'chat'; - $response = $this->platform->request('meta/meta-llama-3.1-405b-instruct', $endpoint, [ 'system' => $systemMessage?->content, 'prompt' => self::convertToPrompt($messages->withoutSystemMessage()), @@ -43,9 +41,7 @@ private static function convertToPrompt(MessageBag $messageBag): string foreach ($messageBag->getIterator() as $message) { if ($message instanceof UserMessage) { $content = $message->content[0]->text; - } - - elseif ($message instanceof AssistantMessage && $message->content !== null) { + } elseif ($message instanceof AssistantMessage && null !== $message->content) { $content = $message->content; } else { continue; From 76f32fc9e668fb6961c925b5969ee43d2023bbbb Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Sat, 5 Oct 2024 22:42:56 +0200 Subject: [PATCH 6/9] - --- src/Model/Language/Llama.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Model/Language/Llama.php b/src/Model/Language/Llama.php index cde192ca..e3343a9c 100644 --- a/src/Model/Language/Llama.php +++ b/src/Model/Language/Llama.php @@ -47,7 +47,7 @@ private static function convertToPrompt(MessageBag $messageBag): string continue; } - $messages[] = sprintf('%s: %s', ucfirst($message->getRole()->value), $message->content[0]->text); + $messages[] = sprintf('%s: %s', ucfirst($message->getRole()->value), $content); } return implode(PHP_EOL, $messages); From c3eb5f04d864e3eed497ca3f304fd3f194c94cfc Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Oct 2024 08:19:35 +0200 Subject: [PATCH 7/9] - --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 002d70a2..cb95d2f4 100644 --- a/composer.json +++ b/composer.json @@ -46,6 +46,7 @@ "codewithkyrian/chromadb-php": "For using the ChromaDB as retrieval vector store.", "mongodb/mongodb": "For using MongoDB Atlas as retrieval vector store.", "probots-io/pinecone-php": "For using the Pinecone as retrieval vector store.", + "symfony/clock": "For using the clock tool.", "symfony/css-selector": "For using the YouTube transcription tool.", "symfony/dom-crawler": "For using the YouTube transcription tool." }, From 38b133d249012ad3c4903786c47cf59a333f9196 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Oct 2024 08:20:18 +0200 Subject: [PATCH 8/9] - --- examples/structured-output-math.php | 2 +- src/Platform/Anthropic.php | 1 + src/Platform/OpenAI/Azure.php | 1 + src/Platform/OpenAI/OpenAI.php | 3 ++- src/Platform/Voyage.php | 1 + src/Store/Azure/SearchStore.php | 1 + tests/StructuredOutput/ResponseFormatFactoryTest.php | 2 +- tests/StructuredOutput/SchemaFactoryTest.php | 6 +++--- 8 files changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/structured-output-math.php b/examples/structured-output-math.php index c833f2ef..28f8d680 100644 --- a/examples/structured-output-math.php +++ b/examples/structured-output-math.php @@ -7,7 +7,7 @@ use PhpLlm\LlmChain\Platform\OpenAI\OpenAI; use PhpLlm\LlmChain\StructuredOutput\ChainProcessor; use PhpLlm\LlmChain\StructuredOutput\ResponseFormatFactory; -use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\MathReasoning; +use PhpLlm\LlmChain\Tests\StructuredOutput\Data\MathReasoning; use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\Serializer\Encoder\JsonEncoder; diff --git a/src/Platform/Anthropic.php b/src/Platform/Anthropic.php index e64eb37a..2f2beff6 100644 --- a/src/Platform/Anthropic.php +++ b/src/Platform/Anthropic.php @@ -30,6 +30,7 @@ public function request(array $body): iterable $response = $this->httpClient->request('POST', 'https://api.anthropic.com/v1/messages', [ 'headers' => [ 'x-api-key' => $this->apiKey, + 'Content-Type' => 'application/json', 'anthropic-version' => '2023-06-01', ], 'json' => $body, diff --git a/src/Platform/OpenAI/Azure.php b/src/Platform/OpenAI/Azure.php index c06d270f..8226e7f0 100644 --- a/src/Platform/OpenAI/Azure.php +++ b/src/Platform/OpenAI/Azure.php @@ -29,6 +29,7 @@ protected function rawRequest(string $endpoint, array $body): ResponseInterface return $this->httpClient->request('POST', $url, [ 'headers' => [ 'api-key' => $this->apiKey, + 'Content-Type' => 'application/json', ], 'query' => ['api-version' => $this->apiVersion], 'json' => $body, diff --git a/src/Platform/OpenAI/OpenAI.php b/src/Platform/OpenAI/OpenAI.php index af0252ac..0a93bdc9 100644 --- a/src/Platform/OpenAI/OpenAI.php +++ b/src/Platform/OpenAI/OpenAI.php @@ -25,7 +25,8 @@ protected function rawRequest(string $endpoint, array $body): ResponseInterface return $this->httpClient->request('POST', $url, [ 'auth_bearer' => $this->apiKey, - 'json' => $body, + 'headers' => ['Content-Type' => 'application/json'], + 'body' => json_encode($body), ]); } } diff --git a/src/Platform/Voyage.php b/src/Platform/Voyage.php index 0671596e..18fc361d 100644 --- a/src/Platform/Voyage.php +++ b/src/Platform/Voyage.php @@ -22,6 +22,7 @@ public function __construct( public function request(array $body): array { $response = $this->httpClient->request('POST', 'https://api.voyageai.com/v1/embeddings', [ + 'headers' => ['Content-Type' => 'application/json'], 'auth_bearer' => $this->apiKey, 'json' => $body, ]); diff --git a/src/Store/Azure/SearchStore.php b/src/Store/Azure/SearchStore.php index b8ac89e2..8bfcb636 100644 --- a/src/Store/Azure/SearchStore.php +++ b/src/Store/Azure/SearchStore.php @@ -54,6 +54,7 @@ private function request(string $endpoint, array $payload): array $response = $this->httpClient->request('POST', $url, [ 'headers' => [ 'api-key' => $this->apiKey, + 'Content-Type' => 'application/json', ], 'query' => ['api-version' => $this->apiVersion], 'json' => $payload, diff --git a/tests/StructuredOutput/ResponseFormatFactoryTest.php b/tests/StructuredOutput/ResponseFormatFactoryTest.php index bd9f736d..29067c9f 100644 --- a/tests/StructuredOutput/ResponseFormatFactoryTest.php +++ b/tests/StructuredOutput/ResponseFormatFactoryTest.php @@ -6,7 +6,7 @@ use PhpLlm\LlmChain\StructuredOutput\ResponseFormatFactory; use PhpLlm\LlmChain\StructuredOutput\SchemaFactory; -use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\User; +use PhpLlm\LlmChain\Tests\StructuredOutput\Data\User; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\Attributes\UsesClass; diff --git a/tests/StructuredOutput/SchemaFactoryTest.php b/tests/StructuredOutput/SchemaFactoryTest.php index 7069f8c9..3695a362 100644 --- a/tests/StructuredOutput/SchemaFactoryTest.php +++ b/tests/StructuredOutput/SchemaFactoryTest.php @@ -5,9 +5,9 @@ namespace PhpLlm\LlmChain\Tests\StructuredOutput; use PhpLlm\LlmChain\StructuredOutput\SchemaFactory; -use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\MathReasoning; -use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\Step; -use PhpLlm\LlmChain\Tests\Fixture\StructuredOutput\User; +use PhpLlm\LlmChain\Tests\StructuredOutput\Data\MathReasoning; +use PhpLlm\LlmChain\Tests\StructuredOutput\Data\Step; +use PhpLlm\LlmChain\Tests\StructuredOutput\Data\User; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; From fa181f58ddc0d2656f4974282ef6293ac0fc9742 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Oct 2024 08:20:43 +0200 Subject: [PATCH 9/9] - --- tests/StructuredOutput/Data/MathReasoning.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 tests/StructuredOutput/Data/MathReasoning.php diff --git a/tests/StructuredOutput/Data/MathReasoning.php b/tests/StructuredOutput/Data/MathReasoning.php new file mode 100644 index 00000000..1c74435a --- /dev/null +++ b/tests/StructuredOutput/Data/MathReasoning.php @@ -0,0 +1,17 @@ +