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

Commit d98a898

Browse files
committed
fix empty tool box chain processor is setting invalid tools option to input
1 parent 1116782 commit d98a898

File tree

2 files changed

+77
-1
lines changed

2 files changed

+77
-1
lines changed

src/ToolBox/ChainProcessor.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,13 @@ public function processInput(Input $input): void
2929
throw MissingModelSupport::forToolCalling($input->llm::class);
3030
}
3131

32+
$toolMap = $this->toolBox->getMap();
33+
if ([] === $toolMap) {
34+
return;
35+
}
36+
3237
$options = $input->getOptions();
33-
$options['tools'] = $this->toolBox->getMap();
38+
$options['tools'] = $toolMap;
3439
$input->setOptions($options);
3540
}
3641

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PhpLlm\LlmChain\Tests\ToolBox;
6+
7+
use PhpLlm\LlmChain\Chain\Input;
8+
use PhpLlm\LlmChain\Exception\MissingModelSupport;
9+
use PhpLlm\LlmChain\LanguageModel;
10+
use PhpLlm\LlmChain\Message\MessageBag;
11+
use PhpLlm\LlmChain\ToolBox\ChainProcessor;
12+
use PhpLlm\LlmChain\ToolBox\ToolBoxInterface;
13+
use PHPUnit\Framework\Attributes\CoversClass;
14+
use PHPUnit\Framework\Attributes\Test;
15+
use PHPUnit\Framework\Attributes\UsesClass;
16+
use PHPUnit\Framework\TestCase;
17+
18+
#[CoversClass(ChainProcessor::class)]
19+
#[UsesClass(Input::class)]
20+
#[UsesClass(MessageBag::class)]
21+
#[UsesClass(MissingModelSupport::class)]
22+
class ChainProcessorTest extends TestCase
23+
{
24+
#[Test]
25+
public function processInputWithoutRegisteredToolsWillResultInNoOptionChange(): void
26+
{
27+
$toolBox = $this->createStub(ToolBoxInterface::class);
28+
$toolBox->method('getMap')->willReturn([]);
29+
30+
$llm = $this->createMock(LanguageModel::class);
31+
$llm->method('supportsToolCalling')->willReturn(true);
32+
33+
$chainProcessor = new ChainProcessor($toolBox);
34+
$input = new Input($llm, new MessageBag(), []);
35+
36+
$chainProcessor->processInput($input);
37+
38+
self::assertSame([], $input->getOptions());
39+
}
40+
41+
#[Test]
42+
public function processInputWithRegisteredToolsWillResultInOptionChange(): void
43+
{
44+
$toolBox = $this->createStub(ToolBoxInterface::class);
45+
$toolBox->method('getMap')->willReturn(['tool1' => 'tool1', 'tool2' => 'tool2']);
46+
47+
$llm = $this->createMock(LanguageModel::class);
48+
$llm->method('supportsToolCalling')->willReturn(true);
49+
50+
$chainProcessor = new ChainProcessor($toolBox);
51+
$input = new Input($llm, new MessageBag(), []);
52+
53+
$chainProcessor->processInput($input);
54+
55+
self::assertSame(['tools' => ['tool1' => 'tool1', 'tool2' => 'tool2']], $input->getOptions());
56+
}
57+
58+
#[Test]
59+
public function processInputWithUnsupportedToolCallingWillThrowException(): void
60+
{
61+
$this->expectException(MissingModelSupport::class);
62+
63+
$llm = $this->createMock(LanguageModel::class);
64+
$llm->method('supportsToolCalling')->willReturn(false);
65+
66+
$chainProcessor = new ChainProcessor($this->createStub(ToolBoxInterface::class));
67+
$input = new Input($llm, new MessageBag(), []);
68+
69+
$chainProcessor->processInput($input);
70+
}
71+
}

0 commit comments

Comments
 (0)