Skip to content

Commit 93e20de

Browse files
committed
refactor: major structure refactoring
1 parent 1e113b0 commit 93e20de

File tree

377 files changed

+5124
-3753
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

377 files changed

+5124
-3753
lines changed

README.md

Lines changed: 39 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,7 @@ Those models are provided by different **platforms**, like OpenAI, Azure, Google
4545
#### Example Instantiation
4646

4747
```php
48-
use PhpLlm\LlmChain\Bridge\OpenAI\Embeddings;
49-
use PhpLlm\LlmChain\Bridge\OpenAI\GPT;
50-
use PhpLlm\LlmChain\Bridge\OpenAI\PlatformFactory;
48+
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Embeddings;use PhpLlm\LlmChain\Platform\Bridge\OpenAI\GPT;use PhpLlm\LlmChain\Platform\Bridge\OpenAI\PlatformFactory;
5149

5250
// Platform: OpenAI
5351
$platform = PlatformFactory::create($_ENV['OPENAI_API_KEY']);
@@ -90,13 +88,11 @@ have different content types, like `Text`, `Image` or `Audio`.
9088
#### Example Chain call with messages
9189

9290
```php
93-
use PhpLlm\LlmChain\Chain;
94-
use PhpLlm\LlmChain\Model\Message\Message;
95-
use PhpLlm\LlmChain\Model\Message\MessageBag;
91+
use PhpLlm\LlmChain\Chain\Chain;use PhpLlm\LlmChain\Platform\Message\Message;use PhpLlm\LlmChain\Platform\Message\MessageBag;
9692

9793
// Platform & LLM instantiation
9894

99-
$chain = new Chain($platform, $llm);
95+
$chain = new Chain($platform, $model);
10096
$messages = new MessageBag(
10197
Message::forSystem('You are a helpful chatbot answering questions about LLM Chain.'),
10298
Message::ofUser('Hello, how are you?'),
@@ -156,7 +152,7 @@ $yourTool = new YourTool();
156152
$toolbox = Toolbox::create($yourTool);
157153
$toolProcessor = new ChainProcessor($toolbox);
158154

159-
$chain = new Chain($platform, $llm, inputProcessor: [$toolProcessor], outputProcessor: [$toolProcessor]);
155+
$chain = new Chain($platform, $model, inputProcessor: [$toolProcessor], outputProcessor: [$toolProcessor]);
160156
```
161157

162158
Custom tools can basically be any class, but must configure by the `#[AsTool]` attribute.
@@ -219,8 +215,7 @@ partially support by LLMs like GPT.
219215
To leverage this, configure the `#[With]` attribute on the method arguments of your tool:
220216

221217
```php
222-
use PhpLlm\LlmChain\Chain\JsonSchema\Attribute\With;
223-
use PhpLlm\LlmChain\Chain\Toolbox\Attribute\AsTool;
218+
use PhpLlm\LlmChain\Chain\Toolbox\Attribute\AsTool;use PhpLlm\LlmChain\Platform\Contract\JsonSchema\Attribute\With;
224219

225220
#[AsTool('my_tool', 'Example tool with parameters requirements.')]
226221
final class MyTool
@@ -252,10 +247,10 @@ attribute to the class is not possible in those cases, but you can explicitly re
252247

253248
```php
254249
use PhpLlm\LlmChain\Chain\Toolbox\Toolbox;
255-
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\MemoryFactory;
250+
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\MemoryToolFactory;
256251
use Symfony\Component\Clock\Clock;
257252

258-
$metadataFactory = (new MemoryFactory())
253+
$metadataFactory = (new MemoryToolFactory())
259254
->addTool(Clock::class, 'clock', 'Get the current date and time', 'now');
260255
$toolbox = new Toolbox($metadataFactory, [new Clock()]);
261256
```
@@ -268,12 +263,12 @@ tools in the same chain - which even enables you to overwrite the pre-existing c
268263

269264
```php
270265
use PhpLlm\LlmChain\Chain\Toolbox\Toolbox;
271-
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\ChainFactory;
272-
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\MemoryFactory;
273-
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\ReflectionFactory;
266+
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\ChainFactory;
267+
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\MemoryToolFactory;
268+
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\ReflectionToolFactory;
274269

275-
$reflectionFactory = new ReflectionFactory(); // Register tools with #[AsTool] attribute
276-
$metadataFactory = (new MemoryFactory()) // Register or overwrite tools explicitly
270+
$reflectionFactory = new ReflectionToolFactory(); // Register tools with #[AsTool] attribute
271+
$metadataFactory = (new MemoryToolFactory()) // Register or overwrite tools explicitly
277272
->addTool(...);
278273
$toolbox = new Toolbox(new ChainFactory($metadataFactory, $reflectionFactory), [...]);
279274
```
@@ -287,14 +282,14 @@ Similar to third-party tools, you can also use a chain as a tool in another chai
287282
complex logic or to reuse a chain in multiple places or hide sub-chains from the LLM.
288283

289284
```php
290-
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\MemoryFactory;
285+
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\MemoryToolFactory;
291286
use PhpLlm\LlmChain\Chain\Toolbox\Toolbox;
292287
use PhpLlm\LlmChain\Chain\Toolbox\Tool\Chain;
293288

294289
// Chain was initialized before
295290

296291
$chainTool = new Chain($chain);
297-
$metadataFactory = (new MemoryFactory())
292+
$metadataFactory = (new MemoryToolFactory())
298293
->addTool($chainTool, 'research_agent', 'Meaningful description for sub-chain');
299294
$toolbox = new Toolbox($metadataFactory, [$chainTool]);
300295
```
@@ -314,7 +309,7 @@ use PhpLlm\LlmChain\Chain\Toolbox\FaultTolerantToolbox;
314309
$toolbox = new FaultTolerantToolbox($innerToolbox);
315310
$toolProcessor = new ChainProcessor($toolbox);
316311

317-
$chain = new Chain($platform, $llm, inputProcessor: [$toolProcessor], outputProcessor: [$toolProcessor]);
312+
$chain = new Chain($platform, $model, inputProcessor: [$toolProcessor], outputProcessor: [$toolProcessor]);
318313
```
319314

320315
#### Tool Filtering
@@ -362,12 +357,7 @@ For populating a vector store, LLM Chain provides the service `Embedder`, which
362357
`EmbeddingsModel` and one of `StoreInterface`, and works with a collection of `Document` objects as input:
363358

364359
```php
365-
use PhpLlm\LlmChain\Embedder;
366-
use PhpLlm\LlmChain\Bridge\OpenAI\Embeddings;
367-
use PhpLlm\LlmChain\Bridge\OpenAI\PlatformFactory;
368-
use PhpLlm\LlmChain\Bridge\Pinecone\Store;
369-
use Probots\Pinecone\Pinecone;
370-
use Symfony\Component\HttpClient\HttpClient;
360+
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Embeddings;use PhpLlm\LlmChain\Platform\Bridge\OpenAI\PlatformFactory;use PhpLlm\LlmChain\Store\Bridge\Pinecone\Store;use PhpLlm\LlmChain\Store\Embedder;use Probots\Pinecone\Pinecone;
371361

372362
$embedder = new Embedder(
373363
PlatformFactory::create($_ENV['OPENAI_API_KEY']),
@@ -380,8 +370,7 @@ $embedder->embed($documents);
380370
The collection of `Document` instances is usually created by text input of your domain entities:
381371

382372
```php
383-
use PhpLlm\LlmChain\Document\Metadata;
384-
use PhpLlm\LlmChain\Document\TextDocument;
373+
use PhpLlm\LlmChain\Store\Document\Metadata;use PhpLlm\LlmChain\Store\Document\TextDocument;
385374

386375
foreach ($entities as $entity) {
387376
$documents[] = new TextDocument(
@@ -399,19 +388,14 @@ In the end the chain is used in combination with a retrieval tool on top of the
399388
`SimilaritySearch` tool provided by the library:
400389

401390
```php
402-
use PhpLlm\LlmChain\Chain;
403-
use PhpLlm\LlmChain\Model\Message\Message;
404-
use PhpLlm\LlmChain\Model\Message\MessageBag;
405-
use PhpLlm\LlmChain\Chain\Toolbox\ChainProcessor;
406-
use PhpLlm\LlmChain\Chain\Toolbox\Tool\SimilaritySearch;
407-
use PhpLlm\LlmChain\Chain\Toolbox\Toolbox;
391+
use PhpLlm\LlmChain\Chain\Chain;use PhpLlm\LlmChain\Chain\Toolbox\ChainProcessor;use PhpLlm\LlmChain\Chain\Toolbox\Tool\SimilaritySearch;use PhpLlm\LlmChain\Chain\Toolbox\Toolbox;use PhpLlm\LlmChain\Platform\Message\Message;use PhpLlm\LlmChain\Platform\Message\MessageBag;
408392

409393
// Initialize Platform & Models
410394

411395
$similaritySearch = new SimilaritySearch($embeddings, $store);
412396
$toolbox = Toolbox::create($similaritySearch);
413397
$processor = new ChainProcessor($toolbox);
414-
$chain = new Chain($platform, $llm, [$processor], [$processor]);
398+
$chain = new Chain($platform, $model, [$processor], [$processor]);
415399

416400
$messages = new MessageBag(
417401
Message::forSystem(<<<PROMPT
@@ -450,22 +434,15 @@ LLM Chain supports that use-case by abstracting the hustle of defining and provi
450434
the response back to PHP objects.
451435
452436
To achieve this, a specific chain processor needs to be registered:
437+
453438
```php
454-
use PhpLlm\LlmChain\Chain;
455-
use PhpLlm\LlmChain\Model\Message\Message;
456-
use PhpLlm\LlmChain\Model\Message\MessageBag;
457-
use PhpLlm\LlmChain\Chain\StructuredOutput\ChainProcessor;
458-
use PhpLlm\LlmChain\Chain\StructuredOutput\ResponseFormatFactory;
459-
use PhpLlm\LlmChain\Tests\Chain\StructuredOutput\Data\MathReasoning;
460-
use Symfony\Component\Serializer\Encoder\JsonEncoder;
461-
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
462-
use Symfony\Component\Serializer\Serializer;
439+
use PhpLlm\LlmChain\Chain\Chain;use PhpLlm\LlmChain\Chain\StructuredOutput\ChainProcessor;use PhpLlm\LlmChain\Chain\StructuredOutput\ResponseFormatFactory;use PhpLlm\LlmChain\Platform\Message\Message;use PhpLlm\LlmChain\Platform\Message\MessageBag;use PhpLlm\LlmChain\Tests\Chain\StructuredOutput\Data\MathReasoning;use Symfony\Component\Serializer\Encoder\JsonEncoder;use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;use Symfony\Component\Serializer\Serializer;
463440
464441
// Initialize Platform and LLM
465442
466443
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
467444
$processor = new ChainProcessor(new ResponseFormatFactory(), $serializer);
468-
$chain = new Chain($platform, $llm, [$processor], [$processor]);
445+
$chain = new Chain($platform, $model, [$processor], [$processor]);
469446
470447
$messages = new MessageBag(
471448
Message::forSystem('You are a helpful math tutor. Guide the user through the solution step by step.'),
@@ -481,8 +458,7 @@ dump($response->getContent()); // returns an instance of `MathReasoning` class
481458
Also PHP array structures as `response_format` are supported, which also requires the chain processor mentioned above:
482459
483460
```php
484-
use PhpLlm\LlmChain\Model\Message\Message;
485-
use PhpLlm\LlmChain\Model\Message\MessageBag;
461+
use PhpLlm\LlmChain\Platform\Message\Message;use PhpLlm\LlmChain\Platform\Message\MessageBag;
486462
487463
// Initialize Platform, LLM and Chain with processors and Clock tool
488464
@@ -518,13 +494,11 @@ Since LLMs usually generate a response word by word, most of them also support s
518494
Events. LLM Chain supports that by abstracting the conversion and returning a Generator as content of the response.
519495
520496
```php
521-
use PhpLlm\LlmChain\Chain;
522-
use PhpLlm\LlmChain\Message\Message;
523-
use PhpLlm\LlmChain\Message\MessageBag;
497+
use PhpLlm\LlmChain\Chain\Chain;use PhpLlm\LlmChain\Message\Message;use PhpLlm\LlmChain\Message\MessageBag;
524498
525499
// Initialize Platform and LLM
526500
527-
$chain = new Chain($llm);
501+
$chain = new Chain($model);
528502
$messages = new MessageBag(
529503
Message::forSystem('You are a thoughtful philosopher.'),
530504
Message::ofUser('What is the purpose of an ant?'),
@@ -551,9 +525,7 @@ needs to be used.
551525
Some LLMs also support images as input, which LLM Chain supports as `Content` type within the `UserMessage`:
552526
553527
```php
554-
use PhpLlm\LlmChain\Model\Message\Content\Image;
555-
use PhpLlm\LlmChain\Model\Message\Message;
556-
use PhpLlm\LlmChain\Model\Message\MessageBag;
528+
use PhpLlm\LlmChain\Platform\Message\Content\Image;use PhpLlm\LlmChain\Platform\Message\Message;use PhpLlm\LlmChain\Platform\Message\MessageBag;
557529
558530
// Initialize Platform, LLM & Chain
559531
@@ -579,9 +551,7 @@ $response = $chain->call($messages);
579551
Similar to images, some LLMs also support audio as input, which is just another `Content` type within the `UserMessage`:
580552
581553
```php
582-
use PhpLlm\LlmChain\Model\Message\Content\Audio;
583-
use PhpLlm\LlmChain\Model\Message\Message;
584-
use PhpLlm\LlmChain\Model\Message\MessageBag;
554+
use PhpLlm\LlmChain\Platform\Message\Content\Audio;use PhpLlm\LlmChain\Platform\Message\Message;use PhpLlm\LlmChain\Platform\Message\MessageBag;
585555
586556
// Initialize Platform, LLM & Chain
587557
@@ -606,7 +576,7 @@ therefore LLM Chain implements a `EmbeddingsModel` interface with various models
606576
The standalone usage results in an `Vector` instance:
607577
608578
```php
609-
use PhpLlm\LlmChain\Bridge\OpenAI\Embeddings;
579+
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Embeddings;
610580
611581
// Initialize Platform
612582
@@ -655,11 +625,11 @@ The behavior of the Chain is extendable with services that implement `InputProce
655625
interface. They are provided while instantiating the Chain instance:
656626
657627
```php
658-
use PhpLlm\LlmChain\Chain;
628+
use PhpLlm\LlmChain\Chain\Chain;
659629
660630
// Initialize Platform, LLM and processors
661631
662-
$chain = new Chain($platform, $llm, $inputProcessors, $outputProcessors);
632+
$chain = new Chain($platform, $model, $inputProcessors, $outputProcessors);
663633
```
664634
665635
#### InputProcessor
@@ -668,11 +638,9 @@ $chain = new Chain($platform, $llm, $inputProcessors, $outputProcessors);
668638
able to mutate both on top of the `Input` instance provided.
669639
670640
```php
671-
use PhpLlm\LlmChain\Chain\Input;
672-
use PhpLlm\LlmChain\Chain\InputProcessor;
673-
use PhpLlm\LlmChain\Model\Message\AssistantMessage
641+
use PhpLlm\LlmChain\Chain\Input;use PhpLlm\LlmChain\Chain\InputProcessorInterface;use PhpLlm\LlmChain\Platform\Message\AssistantMessage;
674642
675-
final class MyProcessor implements InputProcessor
643+
final class MyProcessor implements InputProcessorInterface
676644
{
677645
public function processInput(Input $input): void
678646
{
@@ -693,11 +661,9 @@ final class MyProcessor implements InputProcessor
693661
mutate or replace the given response:
694662
695663
```php
696-
use PhpLlm\LlmChain\Chain\Output;
697-
use PhpLlm\LlmChain\Chain\OutputProcessor;
698-
use PhpLlm\LlmChain\Model\Message\AssistantMessage
664+
use PhpLlm\LlmChain\Chain\Output;use PhpLlm\LlmChain\Chain\OutputProcessorInterface;
699665
700-
final class MyProcessor implements OutputProcessor
666+
final class MyProcessor implements OutputProcessorInterface
701667
{
702668
public function processOutput(Output $out): void
703669
{
@@ -716,13 +682,9 @@ provided, in case the processor implemented the `ChainAwareProcessor` interface,
716682
`ChainAwareTrait`:
717683
718684
```php
719-
use PhpLlm\LlmChain\Chain\ChainAwareProcessor;
720-
use PhpLlm\LlmChain\Chain\ChainAwareTrait;
721-
use PhpLlm\LlmChain\Chain\Output;
722-
use PhpLlm\LlmChain\Chain\OutputProcessor;
723-
use PhpLlm\LlmChain\Model\Message\AssistantMessage
685+
use PhpLlm\LlmChain\Chain\ChainAwareProcessorInterface;use PhpLlm\LlmChain\Chain\ChainAwareTrait;use PhpLlm\LlmChain\Chain\Output;use PhpLlm\LlmChain\Chain\OutputProcessorInterface;
724686
725-
final class MyProcessor implements OutputProcessor, ChainAwareProcessor
687+
final class MyProcessor implements OutputProcessorInterface, ChainAwareProcessorInterface
726688
{
727689
use ChainAwareTrait;
728690
@@ -740,11 +702,9 @@ LLM Chain comes out of the box with an integration for [HuggingFace](https://hug
740702
hosting and sharing all kinds of models, including LLMs, embeddings, image generation, and classification models.
741703
742704
You can just instantiate the Platform with the corresponding HuggingFace bridge and use it with the `task` option:
705+
743706
```php
744-
use PhpLlm\LlmChain\Bridge\HuggingFace\Model;
745-
use PhpLlm\LlmChain\Bridge\HuggingFace\PlatformFactory;
746-
use PhpLlm\LlmChain\Bridge\HuggingFace\Task;
747-
use PhpLlm\LlmChain\Model\Message\Content\Image;
707+
use PhpLlm\LlmChain\Bridge\HuggingFace\Model;use PhpLlm\LlmChain\Platform\Bridge\HuggingFace\PlatformFactory;use PhpLlm\LlmChain\Platform\Bridge\HuggingFace\Task;use PhpLlm\LlmChain\Platform\Message\Content\Image;
748708
749709
$platform = PlatformFactory::create($apiKey);
750710
$model = new Model('facebook/detr-resnet-50');
@@ -788,9 +748,7 @@ and comes with an extra setup, see [TransformersPHP's Getting Starter](https://t
788748
The usage with LLM Chain is similar to the HuggingFace integration, and also requires the `task` option to be set:
789749

790750
```php
791-
use Codewithkyrian\Transformers\Pipelines\Task;
792-
use PhpLlm\LlmChain\Bridge\TransformersPHP\Model;
793-
use PhpLlm\LlmChain\Bridge\TransformersPHP\PlatformFactory;
751+
use Codewithkyrian\Transformers\Pipelines\Task;use PhpLlm\LlmChain\Bridge\TransformersPHP\Model;use PhpLlm\LlmChain\Platform\Bridge\TransformersPHP\PlatformFactory;
794752

795753
$platform = PlatformFactory::create();
796754
$model = new Model('Xenova/LaMini-Flan-T5-783M');

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"mongodb/mongodb": "^1.21",
4747
"php-cs-fixer/shim": "^3.70",
4848
"phpstan/phpstan": "^2.0",
49+
"phpstan/phpstan-symfony": "^2.0",
4950
"phpstan/phpstan-webmozart-assert": "^2.0",
5051
"phpunit/phpunit": "^11.5",
5152
"probots-io/pinecone-php": "^1.0",

examples/anthropic/chat.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<?php
22

3-
use PhpLlm\LlmChain\Bridge\Anthropic\Claude;
4-
use PhpLlm\LlmChain\Bridge\Anthropic\PlatformFactory;
5-
use PhpLlm\LlmChain\Chain;
6-
use PhpLlm\LlmChain\Model\Message\Message;
7-
use PhpLlm\LlmChain\Model\Message\MessageBag;
3+
use PhpLlm\LlmChain\Chain\Chain;
4+
use PhpLlm\LlmChain\Platform\Bridge\Anthropic\Claude;
5+
use PhpLlm\LlmChain\Platform\Bridge\Anthropic\PlatformFactory;
6+
use PhpLlm\LlmChain\Platform\Message\Message;
7+
use PhpLlm\LlmChain\Platform\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

1010
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
@@ -16,9 +16,9 @@
1616
}
1717

1818
$platform = PlatformFactory::create($_ENV['ANTHROPIC_API_KEY']);
19-
$llm = new Claude(Claude::SONNET_37);
19+
$model = new Claude(Claude::SONNET_37);
2020

21-
$chain = new Chain($platform, $llm);
21+
$chain = new Chain($platform, $model);
2222
$messages = new MessageBag(
2323
Message::forSystem('You are a pirate and you write funny.'),
2424
Message::ofUser('What is the Symfony framework?'),

examples/anthropic/stream.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<?php
22

3-
use PhpLlm\LlmChain\Bridge\Anthropic\Claude;
4-
use PhpLlm\LlmChain\Bridge\Anthropic\PlatformFactory;
5-
use PhpLlm\LlmChain\Chain;
6-
use PhpLlm\LlmChain\Model\Message\Message;
7-
use PhpLlm\LlmChain\Model\Message\MessageBag;
3+
use PhpLlm\LlmChain\Chain\Chain;
4+
use PhpLlm\LlmChain\Platform\Bridge\Anthropic\Claude;
5+
use PhpLlm\LlmChain\Platform\Bridge\Anthropic\PlatformFactory;
6+
use PhpLlm\LlmChain\Platform\Message\Message;
7+
use PhpLlm\LlmChain\Platform\Message\MessageBag;
88
use Symfony\Component\Dotenv\Dotenv;
99

1010
require_once dirname(__DIR__, 2).'/vendor/autoload.php';
@@ -16,9 +16,9 @@
1616
}
1717

1818
$platform = PlatformFactory::create($_ENV['ANTHROPIC_API_KEY']);
19-
$llm = new Claude();
19+
$model = new Claude();
2020

21-
$chain = new Chain($platform, $llm);
21+
$chain = new Chain($platform, $model);
2222
$messages = new MessageBag(
2323
Message::forSystem('You are a thoughtful philosopher.'),
2424
Message::ofUser('What is the purpose of an ant?'),

0 commit comments

Comments
 (0)