Remove Toolbox::create(...)

This commit is contained in:
Christopher Hertel
2025-07-19 16:04:52 +02:00
parent d15c3752a1
commit 5746ca61b6
26 changed files with 31 additions and 37 deletions

View File

@@ -32,7 +32,7 @@ $platform = PlatformFactory::create($_SERVER['ANTHROPIC_API_KEY']);
$model = new Claude();
$wikipedia = new Wikipedia(HttpClient::create());
$toolbox = Toolbox::create($wikipedia);
$toolbox = new Toolbox([$wikipedia]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -33,7 +33,7 @@ $platform = PlatformFactory::create();
$model = new Claude('claude-3-7-sonnet-20250219');
$wikipedia = new Wikipedia(HttpClient::create());
$toolbox = Toolbox::create($wikipedia);
$toolbox = new Toolbox([$wikipedia]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -33,7 +33,7 @@ $platform = PlatformFactory::create();
$model = new Nova();
$wikipedia = new Wikipedia(HttpClient::create());
$toolbox = Toolbox::create($wikipedia);
$toolbox = new Toolbox([$wikipedia]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -32,7 +32,7 @@ $platform = PlatformFactory::create($_SERVER['GEMINI_API_KEY']);
// Available server-side tools as of 2025-06-28: url_context, google_search, code_execution
$llm = new Gemini('gemini-2.5-pro-preview-03-25', ['server_tools' => ['url_context' => true], 'temperature' => 1.0]);
$toolbox = Toolbox::create(new Clock());
$toolbox = new Toolbox([new Clock()]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $llm);

View File

@@ -33,7 +33,7 @@ $platform = PlatformFactory::create($_SERVER['GEMINI_API_KEY']);
$model = new Gemini(Gemini::GEMINI_1_5_FLASH);
$clock = new Clock(new SymfonyClock());
$toolbox = Toolbox::create($clock);
$toolbox = new Toolbox([$clock]);
$toolProcessor = new ToolProcessor($toolbox);
$structuredOutputProcessor = new StructuredOutputProcessor();
$agent = new Agent($platform, $model, [$toolProcessor, $structuredOutputProcessor], [$toolProcessor, $structuredOutputProcessor]);

View File

@@ -30,7 +30,7 @@ if (!isset($_SERVER['GEMINI_API_KEY'])) {
$platform = PlatformFactory::create($_SERVER['GEMINI_API_KEY']);
$llm = new Gemini(Gemini::GEMINI_2_FLASH);
$toolbox = Toolbox::create(new Clock());
$toolbox = new Toolbox([new Clock()]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $llm, [$processor], [$processor]);

View File

@@ -32,7 +32,7 @@ $platform = PlatformFactory::create($_SERVER['MISTRAL_API_KEY']);
$model = new Mistral();
$transcriber = new YouTubeTranscriber(HttpClient::create());
$toolbox = Toolbox::create($transcriber);
$toolbox = new Toolbox([$transcriber]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -30,7 +30,7 @@ if (!isset($_SERVER['MISTRAL_API_KEY'])) {
$platform = PlatformFactory::create($_SERVER['MISTRAL_API_KEY']);
$model = new Mistral();
$toolbox = Toolbox::create(new Clock());
$toolbox = new Toolbox([new Clock()]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -33,7 +33,7 @@ $platform = PlatformFactory::create($_SERVER['OPENAI_API_KEY']);
$model = new GPT(GPT::GPT_4O_MINI);
$clock = new Clock(new SymfonyClock());
$toolbox = Toolbox::create($clock);
$toolbox = new Toolbox([$clock]);
$toolProcessor = new ToolProcessor($toolbox);
$structuredOutputProcessor = new StructuredOutputProcessor();
$agent = new Agent($platform, $model, [$toolProcessor, $structuredOutputProcessor], [$toolProcessor, $structuredOutputProcessor]);

View File

@@ -32,7 +32,7 @@ $platform = PlatformFactory::create($_SERVER['OPENAI_API_KEY']);
$model = new GPT(GPT::GPT_4O_MINI);
$wikipedia = new Wikipedia(HttpClient::create());
$toolbox = Toolbox::create($wikipedia);
$toolbox = new Toolbox([$wikipedia]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);
$messages = new MessageBag(Message::ofUser(<<<TXT

View File

@@ -32,7 +32,7 @@ $platform = PlatformFactory::create($_SERVER['OPENAI_API_KEY']);
$model = new GPT(GPT::GPT_4O_MINI);
$transcriber = new YouTubeTranscriber(HttpClient::create());
$toolbox = Toolbox::create($transcriber);
$toolbox = new Toolbox([$transcriber]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -67,7 +67,7 @@ $indexer->index($documents);
$model = new Gemini(Gemini::GEMINI_2_FLASH_LITE);
$similaritySearch = new SimilaritySearch($platform, $embeddings, $store);
$toolbox = Toolbox::create($similaritySearch);
$toolbox = new Toolbox([$similaritySearch]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -65,7 +65,7 @@ $indexer->index($documents);
$model = new GPT(GPT::GPT_4O_MINI);
$similaritySearch = new SimilaritySearch($platform, $embeddings, $store);
$toolbox = Toolbox::create($similaritySearch);
$toolbox = new Toolbox([$similaritySearch]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -66,7 +66,7 @@ $indexer->index($documents);
$model = new GPT(GPT::GPT_4O_MINI);
$similaritySearch = new SimilaritySearch($platform, $embeddings, $store);
$toolbox = Toolbox::create($similaritySearch);
$toolbox = new Toolbox([$similaritySearch]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -56,7 +56,7 @@ $indexer->index($documents);
$model = new GPT(GPT::GPT_4O_MINI);
$similaritySearch = new SimilaritySearch($platform, $embeddings, $store);
$toolbox = Toolbox::create($similaritySearch);
$toolbox = new Toolbox([$similaritySearch]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -66,7 +66,7 @@ $store->initialize();
$model = new GPT(GPT::GPT_4O_MINI);
$similaritySearch = new SimilaritySearch($platform, $embeddings, $store);
$toolbox = Toolbox::create($similaritySearch);
$toolbox = new Toolbox([$similaritySearch]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -57,7 +57,7 @@ $indexer->index($documents);
$model = new GPT(GPT::GPT_4O_MINI);
$similaritySearch = new SimilaritySearch($platform, $embeddings, $store);
$toolbox = Toolbox::create($similaritySearch);
$toolbox = new Toolbox([$similaritySearch]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -65,7 +65,7 @@ $indexer->index($documents);
$model = new GPT(GPT::GPT_4O_MINI);
$similaritySearch = new SimilaritySearch($platform, $embeddings, $store);
$toolbox = Toolbox::create($similaritySearch);
$toolbox = new Toolbox([$similaritySearch]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -65,7 +65,7 @@ $indexer->index($documents);
$model = new GPT(GPT::GPT_4O_MINI);
$similaritySearch = new SimilaritySearch($platform, $embeddings, $store);
$toolbox = Toolbox::create($similaritySearch);
$toolbox = new Toolbox([$similaritySearch]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -34,7 +34,7 @@ $model = new GPT(GPT::GPT_4O_MINI);
$httpClient = HttpClient::create();
$brave = new Brave($httpClient, $_SERVER['BRAVE_API_KEY']);
$crawler = new Crawler($httpClient);
$toolbox = Toolbox::create($brave, $crawler);
$toolbox = new Toolbox([$brave, $crawler]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -31,7 +31,7 @@ $platform = PlatformFactory::create($_SERVER['OPENAI_API_KEY']);
$model = new GPT(GPT::GPT_4O_MINI);
$serpApi = new SerpApi(HttpClient::create(), $_SERVER['SERP_API_KEY']);
$toolbox = Toolbox::create($serpApi);
$toolbox = new Toolbox([$serpApi]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -31,7 +31,7 @@ $platform = PlatformFactory::create($_SERVER['OPENAI_API_KEY']);
$model = new GPT(GPT::GPT_4O_MINI);
$tavily = new Tavily(HttpClient::create(), $_SERVER['TAVILY_API_KEY']);
$toolbox = Toolbox::create($tavily);
$toolbox = new Toolbox([$tavily]);
$processor = new AgentProcessor($toolbox);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -35,7 +35,7 @@ $platform = PlatformFactory::create($_SERVER['OPENAI_API_KEY']);
$model = new GPT(GPT::GPT_4O_MINI);
$openMeteo = new OpenMeteo(HttpClient::create());
$toolbox = Toolbox::create($openMeteo);
$toolbox = new Toolbox([$openMeteo]);
$eventDispatcher = new EventDispatcher();
$processor = new AgentProcessor($toolbox, eventDispatcher: $eventDispatcher);
$agent = new Agent($platform, $model, [$processor], [$processor]);

View File

@@ -51,6 +51,5 @@ CHANGELOG
- PSR-3 logger integration throughout
- Symfony EventDispatcher integration
* Add model capability detection before processing
* Add fluent API with `Toolbox::create()` for easy instantiation
* Add comprehensive type safety with full PHP type hints
* Add clear exception hierarchy for different error scenarios
* Add clear exception hierarchy for different error scenarios

View File

@@ -44,8 +44,8 @@ final class Toolbox implements ToolboxInterface
* @param iterable<mixed> $tools
*/
public function __construct(
private readonly ToolFactoryInterface $toolFactory,
iterable $tools,
private readonly ToolFactoryInterface $toolFactory = new ReflectionToolFactory(),
private readonly ToolCallArgumentResolver $argumentResolver = new ToolCallArgumentResolver(),
private readonly LoggerInterface $logger = new NullLogger(),
private readonly ?EventDispatcherInterface $eventDispatcher = null,
@@ -53,11 +53,6 @@ final class Toolbox implements ToolboxInterface
$this->tools = $tools instanceof \Traversable ? iterator_to_array($tools) : $tools;
}
public static function create(object ...$tools): self
{
return new self(new ReflectionToolFactory(), $tools);
}
public function getTools(): array
{
if (isset($this->map)) {

View File

@@ -56,13 +56,13 @@ final class ToolboxTest extends TestCase
protected function setUp(): void
{
$this->toolbox = new Toolbox(new ReflectionToolFactory(), [
$this->toolbox = new Toolbox([
new ToolRequiredParams(),
new ToolOptionalParam(),
new ToolNoParams(),
new ToolException(),
new ToolDate(),
]);
], new ReflectionToolFactory());
}
#[Test]
@@ -168,7 +168,7 @@ final class ToolboxTest extends TestCase
self::expectException(ToolConfigurationException::class);
self::expectExceptionMessage('Method "foo" not found in tool "Symfony\AI\Fixtures\Tool\ToolMisconfigured".');
$toolbox = new Toolbox(new ReflectionToolFactory(), [new ToolMisconfigured()]);
$toolbox = new Toolbox([new ToolMisconfigured()], new ReflectionToolFactory());
$toolbox->execute(new ToolCall('call_1234', 'tool_misconfigured'));
}
@@ -216,7 +216,7 @@ final class ToolboxTest extends TestCase
$memoryFactory = (new MemoryToolFactory())
->addTool(ToolNoAttribute1::class, 'happy_birthday', 'Generates birthday message');
$toolbox = new Toolbox($memoryFactory, [new ToolNoAttribute1()]);
$toolbox = new Toolbox([new ToolNoAttribute1()], $memoryFactory);
$expected = [
new Tool(
new ExecutionReference(ToolNoAttribute1::class, '__invoke'),
@@ -249,7 +249,7 @@ final class ToolboxTest extends TestCase
$memoryFactory = (new MemoryToolFactory())
->addTool(ToolNoAttribute1::class, 'happy_birthday', 'Generates birthday message');
$toolbox = new Toolbox($memoryFactory, [new ToolNoAttribute1()]);
$toolbox = new Toolbox([new ToolNoAttribute1()], $memoryFactory);
$response = $toolbox->execute(new ToolCall('call_1234', 'happy_birthday', ['name' => 'John', 'years' => 30]));
self::assertSame('Happy Birthday, John! You are 30 years old.', $response);
@@ -262,7 +262,7 @@ final class ToolboxTest extends TestCase
->addTool(ToolOptionalParam::class, 'optional_param', 'Tool with optional param', 'bar');
$factory2 = new ReflectionToolFactory();
$toolbox = new Toolbox(new ChainFactory([$factory1, $factory2]), [new ToolOptionalParam()]);
$toolbox = new Toolbox([new ToolOptionalParam()], new ChainFactory([$factory1, $factory2]));
$expected = [
new Tool(