Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.

Commit 14d14a7

Browse files
committed
feat: only render profiler bar section if used
1 parent 68d3bd2 commit 14d14a7

File tree

7 files changed

+114
-53
lines changed

7 files changed

+114
-53
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ composer require php-llm/llm-chain-bundle
1313
```yaml
1414
# config/packages/llm_chain.yaml
1515
llm_chain:
16-
platforms:
16+
platform:
1717
openai:
1818
api_key: '%env(OPENAI_API_KEY)%'
1919
azure:
@@ -23,13 +23,15 @@ llm_chain:
2323
version: '%env(AZURE_OPENAI_VERSION)%'
2424
anthropic:
2525
api_key: '%env(ANTHROPIC_API_KEY)%'
26-
chains:
26+
chain:
2727
default:
2828
model:
2929
name: 'gpt'
3030
version: 'gpt-3.5-turbo'
3131
options: []
32-
stores:
32+
tools:
33+
- 'PhpLlm\LlmChain\Chain\ToolBox\Tool\SimilaritySearch'
34+
store:
3335
azure_search:
3436
api_key: '%env(AZURE_SEARCH_KEY)%'
3537
endpoint: '%env(AZURE_SEARCH_ENDPOINT)%'

src/DependencyInjection/Configuration.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function getConfigTreeBuilder(): TreeBuilder
3333
->end()
3434
->end()
3535
->end()
36-
->arrayNode('chains')
36+
->arrayNode('chain')
3737
->normalizeKeys(false)
3838
->useAttributeAsKey('name')
3939
->arrayPrototype()
@@ -42,9 +42,14 @@ public function getConfigTreeBuilder(): TreeBuilder
4242
->children()
4343
->scalarNode('name')->isRequired()->end()
4444
->scalarNode('version')->defaultNull()->end()
45-
->arrayNode('options')->end()
45+
->arrayNode('options')
46+
->scalarPrototype()->end()
47+
->end()
4648
->end()
4749
->end()
50+
->arrayNode('tools')
51+
->scalarPrototype()->end()
52+
->end()
4853
->end()
4954
->end()
5055
->end()
@@ -63,7 +68,7 @@ public function getConfigTreeBuilder(): TreeBuilder
6368
->end()
6469
->end()
6570
->end()
66-
->arrayNode('stores')
71+
->arrayNode('store')
6772
->normalizeKeys(false)
6873
->useAttributeAsKey('name')
6974
->arrayPrototype()

src/DependencyInjection/LlmChainExtension.php

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,10 @@ public function load(array $configs, ContainerBuilder $container): void
5353
$this->processPlatformConfig($type[0], $config['platform'][$type[0]], $container);
5454
}
5555

56-
foreach ($config['chains'] as $chainName => $chain) {
56+
foreach ($config['chain'] as $chainName => $chain) {
5757
$this->processChainConfig($chainName, $chain, $container);
5858
}
59-
if (1 === count($config['chains']) && isset($chainName)) {
59+
if (1 === count($config['chain']) && isset($chainName)) {
6060
$container->setAlias(ChainInterface::class, 'llm_chain.chain.'.$chainName);
6161
}
6262

@@ -67,10 +67,10 @@ public function load(array $configs, ContainerBuilder $container): void
6767
$container->setAlias(Embedder::class, 'llm_chain.embedder.'.$embedderName);
6868
}
6969

70-
foreach ($config['stores'] as $storeName => $store) {
70+
foreach ($config['store'] as $storeName => $store) {
7171
$this->processStoreConfig($storeName, $store, $container);
7272
}
73-
if (1 === count($config['stores']) && isset($storeName)) {
73+
if (1 === count($config['store']) && isset($storeName)) {
7474
$container->setAlias(VectorStoreInterface::class, 'llm_chain.store.'.$storeName);
7575
$container->setAlias(StoreInterface::class, 'llm_chain.store.'.$storeName);
7676
}
@@ -123,6 +123,7 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
123123
*/
124124
private function processChainConfig(string $name, array $config, ContainerBuilder $container): void
125125
{
126+
// MODEL
126127
['name' => $modelName, 'version' => $version, 'options' => $options] = $config['model'];
127128

128129
$llmClass = match (strtolower($modelName)) {
@@ -138,10 +139,35 @@ private function processChainConfig(string $name, array $config, ContainerBuilde
138139
]);
139140
$container->setDefinition('llm_chain.chain.'.$name.'.llm', $llmDefinition);
140141

141-
$definition = (new ChildDefinition('llm_chain.chain.abstract'))
142+
// CHAIN
143+
$chainDefinition = (new ChildDefinition('llm_chain.chain.abstract'))
142144
->replaceArgument('$llm', new Reference('llm_chain.chain.'.$name.'.llm'));
143145

144-
$container->setDefinition('llm_chain.chain.'.$name, $definition);
146+
// TOOL & PROCESSOR
147+
if (isset($config['tools'])) {
148+
$tools = array_map(static fn (string $tool) => new Reference($tool), $config['tools']);
149+
$toolboxDefinition = (new ChildDefinition('llm_chain.toolbox.abstract'))
150+
->replaceArgument('$tools', $tools);
151+
$container->setDefinition('llm_chain.toolbox.'.$name, $toolboxDefinition);
152+
153+
if ($container->getParameter('kernel.debug')) {
154+
$traceableToolboxDefinition = (new Definition('llm_chain.traceable_toolbox.'.$name))
155+
->setClass(TraceableToolBox::class)
156+
->setAutowired(true)
157+
->setDecoratedService('llm_chain.toolbox.'.$name)
158+
->addTag('llm_chain.traceable_toolbox');
159+
$container->setDefinition('llm_chain.traceable_toolbox.'.$name, $traceableToolboxDefinition);
160+
}
161+
162+
$toolProcessorDefinition = (new ChildDefinition('llm_chain.tool.chain_processor.abstract'))
163+
->replaceArgument('$toolBox', new Reference('llm_chain.toolbox.'.$name));
164+
$container->setDefinition('llm_chain.tool.chain_processor.'.$name, $toolProcessorDefinition);
165+
166+
$chainDefinition->replaceArgument('$inputProcessor', [new Reference('llm_chain.tool.chain_processor.'.$name)]);
167+
$chainDefinition->replaceArgument('$outputProcessor', [new Reference('llm_chain.tool.chain_processor.'.$name)]);
168+
}
169+
170+
$container->setDefinition('llm_chain.chain.'.$name, $chainDefinition);
145171
}
146172

147173
/**

src/Profiler/DataCollector.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
namespace PhpLlm\LlmChainBundle\Profiler;
66

77
use PhpLlm\LlmChain\Chain\ToolBox\Metadata;
8+
use PhpLlm\LlmChain\Chain\ToolBox\ToolBoxInterface;
89
use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector;
10+
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
911
use Symfony\Component\HttpFoundation\Request;
1012
use Symfony\Component\HttpFoundation\Response;
1113

@@ -15,18 +17,29 @@
1517
*/
1618
final class DataCollector extends AbstractDataCollector
1719
{
20+
/**
21+
* @var TraceableToolBox[]
22+
*/
23+
private array $toolBoxes;
24+
25+
/**
26+
* @param TraceableToolBox[] $toolBoxes
27+
*/
1828
public function __construct(
1929
private readonly TraceablePlatform $platform,
20-
private readonly TraceableToolBox $toolBox,
30+
private readonly ToolBoxInterface $defaultToolBox,
31+
#[TaggedIterator('llm_chain.traceable_toolbox')]
32+
iterable $toolBoxes,
2133
) {
34+
$this->toolBoxes = $toolBoxes instanceof \Traversable ? iterator_to_array($toolBoxes) : $toolBoxes;
2235
}
2336

2437
public function collect(Request $request, Response $response, ?\Throwable $exception = null): void
2538
{
2639
$this->data = [
27-
'tools' => $this->toolBox->getMap(),
40+
'tools' => $this->defaultToolBox->getMap(),
2841
'platform_calls' => $this->platform->calls,
29-
'tool_calls' => $this->toolBox->calls,
42+
'tool_calls' => array_merge(...array_map(fn (TraceableToolBox $toolBox) => $toolBox->calls, $this->toolBoxes)),
3043
];
3144
}
3245

src/Profiler/TraceableToolBox.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,23 @@
1616
final class TraceableToolBox implements ToolBoxInterface
1717
{
1818
/**
19-
* @var list<ToolCallData>
19+
* @var ToolCallData[]
2020
*/
2121
public array $calls = [];
2222

2323
public function __construct(
24-
private ToolBoxInterface $toolRegistry,
24+
private ToolBoxInterface $toolBox,
2525
) {
2626
}
2727

2828
public function getMap(): array
2929
{
30-
return $this->toolRegistry->getMap();
30+
return $this->toolBox->getMap();
3131
}
3232

3333
public function execute(ToolCall $toolCall): string
3434
{
35-
$result = $this->toolRegistry->execute($toolCall);
35+
$result = $this->toolBox->execute($toolCall);
3636

3737
$this->calls[] = [
3838
'call' => $toolCall,

src/Resources/config/services.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
66

77
use PhpLlm\LlmChain\Chain;
8-
use PhpLlm\LlmChain\Chain\InputProcessor;
9-
use PhpLlm\LlmChain\Chain\OutputProcessor;
108
use PhpLlm\LlmChain\Chain\StructuredOutput\ChainProcessor as StructureOutputProcessor;
119
use PhpLlm\LlmChain\Chain\StructuredOutput\ResponseFormatFactory;
1210
use PhpLlm\LlmChain\Chain\StructuredOutput\ResponseFormatFactoryInterface;
@@ -29,11 +27,6 @@
2927
$container->services()
3028
->defaults()
3129
->autowire()
32-
->autoconfigure()
33-
->instanceof(InputProcessor::class)
34-
->tag('llm_chain.chain.input_processor')
35-
->instanceof(OutputProcessor::class)
36-
->tag('llm_chain.chain.output_processor')
3730
->instanceof(ModelClient::class)
3831
->tag('llm_chain.platform.model_client')
3932
->instanceof(ResponseConverter::class)
@@ -66,20 +59,39 @@
6659
->set(StructureOutputProcessor::class)
6760

6861
// tools
62+
->set('llm_chain.toolbox.abstract')
63+
->class(ToolBox::class)
64+
->abstract()
65+
->args([
66+
'$tools' => abstract_arg('Collection of tools'),
67+
])
6968
->set(ToolBox::class)
69+
->parent('llm_chain.toolbox.abstract')
7070
->args([
7171
'$tools' => tagged_iterator('llm_chain.tool'),
7272
])
7373
->alias(ToolBoxInterface::class, ToolBox::class)
7474
->set(ToolAnalyzer::class)
7575
->set(ParameterAnalyzer::class)
76+
->set('llm_chain.tool.chain_processor.abstract')
77+
->class(ToolProcessor::class)
78+
->abstract()
79+
->args([
80+
'$toolBox' => abstract_arg('Tool box'),
81+
])
7682
->set(ToolProcessor::class)
83+
->parent('llm_chain.tool.chain_processor.abstract')
84+
->args([
85+
'$toolBox' => service(ToolBoxInterface::class),
86+
])
7787

7888
// profiler
7989
->set(DataCollector::class)
90+
->tag('data_collector')
8091
->set(TraceablePlatform::class)
8192
->decorate(Platform::class)
8293
->set(TraceableToolBox::class)
83-
->decorate(ToolBox::class)
94+
->decorate(ToolBoxInterface::class)
95+
->tag('llm_chain.traceable_toolbox')
8496
;
8597
};

src/Resources/views/data_collector.html.twig

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,39 @@
11
{% extends '@WebProfiler/Profiler/layout.html.twig' %}
22

33
{% block toolbar %}
4-
{% set icon %}
5-
{{ include('@LlmChain/icon.svg', { y: 18 }) }}
6-
<span class="sf-toolbar-value">{{ collector.platformCalls|length }}</span>
7-
<span class="sf-toolbar-info-piece-additional-detail">
8-
<span class="sf-toolbar-label">calls</span>
9-
</span>
10-
{% endset %}
4+
{% if collector.platformCalls|length > 0 %}
5+
{% set icon %}
6+
{{ include('@LlmChain/icon.svg', { y: 18 }) }}
7+
<span class="sf-toolbar-value">{{ collector.platformCalls|length }}</span>
8+
<span class="sf-toolbar-info-piece-additional-detail">
9+
<span class="sf-toolbar-label">calls</span>
10+
</span>
11+
{% endset %}
1112

12-
{% set text %}
13-
<div class="sf-toolbar-info-piece">
13+
{% set text %}
1414
<div class="sf-toolbar-info-piece">
15-
<b class="label">Configured Platforms</b>
16-
<span class="sf-toolbar-status">1</span>
17-
</div>
18-
<div class="sf-toolbar-info-piece">
19-
<b class="label">Platform Calls</b>
20-
<span class="sf-toolbar-status">{{ collector.platformCalls|length }}</span>
21-
</div>
22-
<div class="sf-toolbar-info-piece">
23-
<b class="label">Registered Tools</b>
24-
<span class="sf-toolbar-status">{{ collector.tools|length }}</span>
25-
</div>
26-
<div class="sf-toolbar-info-piece">
27-
<b class="label">Tool Calls</b>
28-
<span class="sf-toolbar-status">{{ collector.toolCalls|length }}</span>
15+
<div class="sf-toolbar-info-piece">
16+
<b class="label">Configured Platforms</b>
17+
<span class="sf-toolbar-status">1</span>
18+
</div>
19+
<div class="sf-toolbar-info-piece">
20+
<b class="label">Platform Calls</b>
21+
<span class="sf-toolbar-status">{{ collector.platformCalls|length }}</span>
22+
</div>
23+
<div class="sf-toolbar-info-piece">
24+
<b class="label">Registered Tools</b>
25+
<span class="sf-toolbar-status">{{ collector.tools|length }}</span>
26+
</div>
27+
<div class="sf-toolbar-info-piece">
28+
<b class="label">Tool Calls</b>
29+
<span class="sf-toolbar-status">{{ collector.toolCalls|length }}</span>
30+
</div>
2931
</div>
30-
</div>
31-
{% endset %}
32+
{% endset %}
33+
34+
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': true }) }}
3235

33-
{{ include('@WebProfiler/Profiler/toolbar_item.html.twig', { 'link': true }) }}
36+
{% endif %}
3437
{% endblock %}
3538

3639
{% block menu %}

0 commit comments

Comments
 (0)