Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,3 @@ ci-lowest: deps-low rector cs phpstan tests

ci-dev: deps-dev rector cs phpstan tests
git restore composer.json

coverage:
XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-html=coverage
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
],
"require": {
"php": ">=8.2",
"php-llm/llm-chain": "^0.21",
"php-llm/llm-chain": "^0.22",
"symfony/config": "^6.4 || ^7.0",
"symfony/dependency-injection": "^6.4 || ^7.0",
"symfony/framework-bundle": "^6.4 || ^7.0",
Expand Down
2 changes: 1 addition & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace PhpLlm\LlmChainBundle\DependencyInjection;

use PhpLlm\LlmChain\PlatformInterface;
use PhpLlm\LlmChain\Platform\PlatformInterface;
use PhpLlm\LlmChain\Store\StoreInterface;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
Expand Down
74 changes: 32 additions & 42 deletions src/DependencyInjection/LlmChainExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,38 @@

namespace PhpLlm\LlmChainBundle\DependencyInjection;

use PhpLlm\LlmChain\Bridge\Anthropic\Claude;
use PhpLlm\LlmChain\Bridge\Anthropic\PlatformFactory as AnthropicPlatformFactory;
use PhpLlm\LlmChain\Bridge\Azure\OpenAI\PlatformFactory as AzureOpenAIPlatformFactory;
use PhpLlm\LlmChain\Bridge\Azure\Store\SearchStore as AzureSearchStore;
use PhpLlm\LlmChain\Bridge\ChromaDB\Store as ChromaDBStore;
use PhpLlm\LlmChain\Bridge\Google\Gemini;
use PhpLlm\LlmChain\Bridge\Google\PlatformFactory as GooglePlatformFactory;
use PhpLlm\LlmChain\Bridge\Meta\Llama;
use PhpLlm\LlmChain\Bridge\MongoDB\Store as MongoDBStore;
use PhpLlm\LlmChain\Bridge\OpenAI\Embeddings;
use PhpLlm\LlmChain\Bridge\OpenAI\GPT;
use PhpLlm\LlmChain\Bridge\OpenAI\PlatformFactory as OpenAIPlatformFactory;
use PhpLlm\LlmChain\Bridge\Pinecone\Store as PineconeStore;
use PhpLlm\LlmChain\Bridge\Voyage\Voyage;
use PhpLlm\LlmChain\Chain;
use PhpLlm\LlmChain\Chain\InputProcessor;
use PhpLlm\LlmChain\Chain\Chain;
use PhpLlm\LlmChain\Chain\ChainInterface;
use PhpLlm\LlmChain\Chain\InputProcessor\SystemPromptInputProcessor;
use PhpLlm\LlmChain\Chain\OutputProcessor;
use PhpLlm\LlmChain\Chain\InputProcessorInterface;
use PhpLlm\LlmChain\Chain\OutputProcessorInterface;
use PhpLlm\LlmChain\Chain\StructuredOutput\ChainProcessor as StructureOutputProcessor;
use PhpLlm\LlmChain\Chain\Toolbox\Attribute\AsTool;
use PhpLlm\LlmChain\Chain\Toolbox\ChainProcessor as ToolProcessor;
use PhpLlm\LlmChain\Chain\Toolbox\FaultTolerantToolbox;
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\ChainFactory;
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\MemoryFactory;
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\ReflectionFactory;
use PhpLlm\LlmChain\Chain\Toolbox\Tool\Chain as ChainTool;
use PhpLlm\LlmChain\ChainInterface;
use PhpLlm\LlmChain\Embedder;
use PhpLlm\LlmChain\Model\EmbeddingsModel;
use PhpLlm\LlmChain\Model\LanguageModel;
use PhpLlm\LlmChain\Platform;
use PhpLlm\LlmChain\Platform\ModelClient;
use PhpLlm\LlmChain\Platform\ResponseConverter;
use PhpLlm\LlmChain\PlatformInterface;
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\ChainFactory;
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\MemoryToolFactory;
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\ReflectionToolFactory;
use PhpLlm\LlmChain\Platform\Bridge\Anthropic\Claude;
use PhpLlm\LlmChain\Platform\Bridge\Anthropic\PlatformFactory as AnthropicPlatformFactory;
use PhpLlm\LlmChain\Platform\Bridge\Azure\OpenAI\PlatformFactory as AzureOpenAIPlatformFactory;
use PhpLlm\LlmChain\Platform\Bridge\Google\Gemini;
use PhpLlm\LlmChain\Platform\Bridge\Google\PlatformFactory as GooglePlatformFactory;
use PhpLlm\LlmChain\Platform\Bridge\Meta\Llama;
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\Embeddings;
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\GPT;
use PhpLlm\LlmChain\Platform\Bridge\OpenAI\PlatformFactory as OpenAIPlatformFactory;
use PhpLlm\LlmChain\Platform\Bridge\Voyage\Voyage;
use PhpLlm\LlmChain\Platform\ModelClientInterface;
use PhpLlm\LlmChain\Platform\Platform;
use PhpLlm\LlmChain\Platform\PlatformInterface;
use PhpLlm\LlmChain\Platform\ResponseConverterInterface;
use PhpLlm\LlmChain\Store\Bridge\Azure\SearchStore as AzureSearchStore;
use PhpLlm\LlmChain\Store\Bridge\ChromaDB\Store as ChromaDBStore;
use PhpLlm\LlmChain\Store\Bridge\MongoDB\Store as MongoDBStore;
use PhpLlm\LlmChain\Store\Bridge\Pinecone\Store as PineconeStore;
use PhpLlm\LlmChain\Store\Embedder;
use PhpLlm\LlmChain\Store\StoreInterface;
use PhpLlm\LlmChain\Store\VectorStoreInterface;
use PhpLlm\LlmChainBundle\Profiler\DataCollector;
Expand Down Expand Up @@ -86,10 +84,6 @@ public function load(array $configs, ContainerBuilder $container): void
if (1 === count($config['chain']) && isset($chainName)) {
$container->setAlias(ChainInterface::class, 'llm_chain.chain.'.$chainName);
}
$llms = array_keys($container->findTaggedServiceIds('llm_chain.model.language_model'));
if (1 === count($llms)) {
$container->setAlias(LanguageModel::class, reset($llms));
}

foreach ($config['store'] ?? [] as $type => $store) {
$this->processStoreConfig($type, $store, $container);
Expand All @@ -106,10 +100,6 @@ public function load(array $configs, ContainerBuilder $container): void
if (1 === count($config['embedder']) && isset($embedderName)) {
$container->setAlias(Embedder::class, 'llm_chain.embedder.'.$embedderName);
}
$embeddings = array_keys($container->findTaggedServiceIds('llm_chain.model.embeddings_model'));
if (1 === count($embeddings)) {
$container->setAlias(EmbeddingsModel::class, reset($embeddings));
}

$container->registerAttributeForAutoconfiguration(AsTool::class, static function (ChildDefinition $definition, AsTool $attribute): void {
$definition->addTag('llm_chain.tool', [
Expand All @@ -119,13 +109,13 @@ public function load(array $configs, ContainerBuilder $container): void
]);
});

$container->registerForAutoconfiguration(InputProcessor::class)
$container->registerForAutoconfiguration(InputProcessorInterface::class)
->addTag('llm_chain.chain.input_processor');
$container->registerForAutoconfiguration(OutputProcessor::class)
$container->registerForAutoconfiguration(OutputProcessorInterface::class)
->addTag('llm_chain.chain.output_processor');
$container->registerForAutoconfiguration(ModelClient::class)
$container->registerForAutoconfiguration(ModelClientInterface::class)
->addTag('llm_chain.platform.model_client');
$container->registerForAutoconfiguration(ResponseConverter::class)
$container->registerForAutoconfiguration(ResponseConverterInterface::class)
->addTag('llm_chain.platform.response_converter');

if (false === $container->getParameter('kernel.debug')) {
Expand Down Expand Up @@ -253,10 +243,10 @@ private function processChainConfig(string $name, array $config, ContainerBuilde
if ($config['tools']['enabled']) {
// Create specific toolbox and process if tools are explicitly defined
if (0 !== count($config['tools']['services'])) {
$memoryFactoryDefinition = new Definition(MemoryFactory::class);
$memoryFactoryDefinition = new Definition(MemoryToolFactory::class);
$container->setDefinition('llm_chain.toolbox.'.$name.'.memory_factory', $memoryFactoryDefinition);
$chainFactoryDefinition = new Definition(ChainFactory::class, [
'$factories' => [new Reference('llm_chain.toolbox.'.$name.'.memory_factory'), new Reference(ReflectionFactory::class)],
'$factories' => [new Reference('llm_chain.toolbox.'.$name.'.memory_factory'), new Reference(ReflectionToolFactory::class)],
]);
$container->setDefinition('llm_chain.toolbox.'.$name.'.chain_factory', $chainFactoryDefinition);

Expand Down
6 changes: 3 additions & 3 deletions src/Profiler/DataCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace PhpLlm\LlmChainBundle\Profiler;

use PhpLlm\LlmChain\Chain\Toolbox\Metadata;
use PhpLlm\LlmChain\Chain\Toolbox\ToolboxInterface;
use PhpLlm\LlmChain\Platform\Tool\Tool;
use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector;
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
use Symfony\Component\HttpFoundation\Request;
Expand Down Expand Up @@ -45,7 +45,7 @@ public function __construct(
public function collect(Request $request, Response $response, ?\Throwable $exception = null): void
{
$this->data = [
'tools' => $this->defaultToolBox->getMap(),
'tools' => $this->defaultToolBox->getTools(),
'platform_calls' => array_merge(...array_map(fn (TraceablePlatform $platform) => $platform->calls, $this->platforms)),
'tool_calls' => array_merge(...array_map(fn (TraceableToolbox $toolbox) => $toolbox->calls, $this->toolboxes)),
];
Expand All @@ -65,7 +65,7 @@ public function getPlatformCalls(): array
}

/**
* @return Metadata[]
* @return Tool[]
*/
public function getTools(): array
{
Expand Down
10 changes: 5 additions & 5 deletions src/Profiler/TraceablePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

namespace PhpLlm\LlmChainBundle\Profiler;

use PhpLlm\LlmChain\Model\Message\Content\File;
use PhpLlm\LlmChain\Model\Model;
use PhpLlm\LlmChain\Model\Response\AsyncResponse;
use PhpLlm\LlmChain\Model\Response\ResponseInterface;
use PhpLlm\LlmChain\PlatformInterface;
use PhpLlm\LlmChain\Platform\Message\Content\File;
use PhpLlm\LlmChain\Platform\Model;
use PhpLlm\LlmChain\Platform\PlatformInterface;
use PhpLlm\LlmChain\Platform\Response\AsyncResponse;
use PhpLlm\LlmChain\Platform\Response\ResponseInterface;

/**
* @phpstan-type PlatformCallData array{
Expand Down
6 changes: 3 additions & 3 deletions src/Profiler/TraceableToolbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace PhpLlm\LlmChainBundle\Profiler;

use PhpLlm\LlmChain\Chain\Toolbox\ToolboxInterface;
use PhpLlm\LlmChain\Model\Response\ToolCall;
use PhpLlm\LlmChain\Platform\Response\ToolCall;

/**
* @phpstan-type ToolCallData array{
Expand All @@ -25,9 +25,9 @@ public function __construct(
) {
}

public function getMap(): array
public function getTools(): array
{
return $this->toolbox->getMap();
return $this->toolbox->getTools();
}

public function execute(ToolCall $toolCall): mixed
Expand Down
10 changes: 5 additions & 5 deletions src/Resources/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
use PhpLlm\LlmChain\Chain\StructuredOutput\ResponseFormatFactory;
use PhpLlm\LlmChain\Chain\StructuredOutput\ResponseFormatFactoryInterface;
use PhpLlm\LlmChain\Chain\Toolbox\ChainProcessor as ToolProcessor;
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory;
use PhpLlm\LlmChain\Chain\Toolbox\MetadataFactory\ReflectionFactory;
use PhpLlm\LlmChain\Chain\Toolbox\Toolbox;
use PhpLlm\LlmChain\Chain\Toolbox\ToolboxInterface;
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactory\ReflectionToolFactory;
use PhpLlm\LlmChain\Chain\Toolbox\ToolFactoryInterface;
use PhpLlm\LlmChainBundle\Profiler\DataCollector;
use PhpLlm\LlmChainBundle\Profiler\TraceableToolbox;

Expand All @@ -33,7 +33,7 @@
->autowire()
->abstract()
->args([
'$metadataFactory' => service(MetadataFactory::class),
'$metadataFactory' => service(ToolFactoryInterface::class),
'$tools' => abstract_arg('Collection of tools'),
])
->set(Toolbox::class)
Expand All @@ -42,8 +42,8 @@
'$tools' => tagged_iterator('llm_chain.tool'),
])
->alias(ToolboxInterface::class, Toolbox::class)
->set(ReflectionFactory::class)
->alias(MetadataFactory::class, ReflectionFactory::class)
->set(ReflectionToolFactory::class)
->alias(ToolFactoryInterface::class, ReflectionToolFactory::class)
->set('llm_chain.tool.chain_processor.abstract')
->class(ToolProcessor::class)
->abstract()
Expand Down
24 changes: 12 additions & 12 deletions tests/Profiler/TraceableToolboxTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

namespace PhpLlm\LlmChainBundle\Tests\Profiler;

use PhpLlm\LlmChain\Chain\Toolbox\ExecutionReference;
use PhpLlm\LlmChain\Chain\Toolbox\Metadata;
use PhpLlm\LlmChain\Chain\Toolbox\ToolboxInterface;
use PhpLlm\LlmChain\Model\Response\ToolCall;
use PhpLlm\LlmChain\Platform\Response\ToolCall;
use PhpLlm\LlmChain\Platform\Tool\ExecutionReference;
use PhpLlm\LlmChain\Platform\Tool\Tool;
use PhpLlm\LlmChainBundle\Profiler\TraceableToolbox;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Small;
Expand All @@ -21,19 +21,19 @@ final class TraceableToolboxTest extends TestCase
#[Test]
public function getMap(): void
{
$metadata = new Metadata(new ExecutionReference('Foo\Bar'), 'bar', 'description', null);
$metadata = new Tool(new ExecutionReference('Foo\Bar'), 'bar', 'description', null);
$toolbox = $this->createToolbox(['tool' => $metadata]);
$traceableToolbox = new TraceableToolbox($toolbox);

$map = $traceableToolbox->getMap();
$map = $traceableToolbox->getTools();

self::assertSame(['tool' => $metadata], $map);
}

#[Test]
public function execute(): void
{
$metadata = new Metadata(new ExecutionReference('Foo\Bar'), 'bar', 'description', null);
$metadata = new Tool(new ExecutionReference('Foo\Bar'), 'bar', 'description', null);
$toolbox = $this->createToolbox(['tool' => $metadata]);
$traceableToolbox = new TraceableToolbox($toolbox);
$toolCall = new ToolCall('foo', '__invoke');
Expand All @@ -47,19 +47,19 @@ public function execute(): void
}

/**
* @param Metadata[] $metadata
* @param Tool[] $tools
*/
private function createToolbox(array $metadata): ToolboxInterface
private function createToolbox(array $tools): ToolboxInterface
{
return new class($metadata) implements ToolboxInterface {
return new class($tools) implements ToolboxInterface {
public function __construct(
private readonly array $metadata,
private readonly array $tools,
) {
}

public function getMap(): array
public function getTools(): array
{
return $this->metadata;
return $this->tools;
}

public function execute(ToolCall $toolCall): string
Expand Down