Use this file to discover all available pages before exploring further.
Tool calling lets a model request the execution of PHP functions you define. The model signals which tool to call and with what arguments; aisdk/core validates the input, invokes your handler, feeds the result back into the conversation, and repeats until the model produces a final answer — or until maxSteps is reached.
Tool::make() creates a tool in one fluent expression. Pass the tool name and description, declare inputs with ->input() or ->inputs(), then attach a handler with ->run():
use AiSdk\Schema;use AiSdk\Tool;$weather = Tool::make('weather', 'Get current weather for a city') ->input(Schema::string(name: 'city', description: 'City name')->required()) ->run(fn (string $city): string => "Sunny, 28 °C in {$city}");
For tools that accept more than one parameter, use ->inputs() with an array of named schemas:
$distance = Tool::make('distance', 'Calculate driving distance between two cities') ->inputs([ Schema::string(name: 'from', description: 'Origin city')->required(), Schema::string(name: 'to', description: 'Destination city')->required(), ]) ->run(fn (string $from, string $to): string => "320 km from {$from} to {$to}");
Extend Tool when the handler requires injected services, has significant logic, or benefits from being tested in isolation. Configure the tool in __construct() using the same fluent methods (->as(), ->for(), ->input()), and implement __invoke() as the handler:
use AiSdk\Schema;use AiSdk\Tool;final class WeatherTool extends Tool{ public function __construct() { $this->as('weather') ->for('Get current weather for a city') ->input(Schema::string(name: 'city')->required()); } public function __invoke(string $city): string { // Call a real weather API here return "Sunny, 28 °C in {$city}"; }}
Resolve a class-based tool with Tool::make(WeatherTool::class), or pass the class name string directly to ->tool() on the request — the SDK resolves it automatically:
$result = Generate::text('What is the weather in Lahore?') ->model(OpenAI::model('gpt-4o')) ->tool(WeatherTool::class) ->run();
If a PSR-11 container is registered via Generate::configure(), Tool::make(SomeClass::class) pulls the instance from the container. This lets you inject services into class-based tools transparently.
->toolChoice() controls whether and how the model uses tools. It accepts a ToolChoice instance or a plain string shorthand:
use AiSdk\ToolChoice;// Let the model decide (default)->toolChoice(ToolChoice::auto())// Model must call at least one tool->toolChoice(ToolChoice::required())// Model must not call any tools->toolChoice(ToolChoice::none())// Force a specific tool by name->toolChoice(ToolChoice::tool('weather'))// String shorthands->toolChoice('auto')->toolChoice('required')->toolChoice('none')
By default (maxSteps(1)) the SDK runs the model once. If that response contains tool calls, they are executed, but the model does not see the results — the tool output is part of the returned TextResult only.Set ->maxSteps() to allow the model to loop: after each step that produces tool calls, the results are appended to the conversation and the model is called again, up to the limit:
$result = Generate::text('What is the weather in Lahore, and is it good for cycling?') ->model(OpenAI::model('gpt-4o')) ->tool($weather) ->maxSteps(5) ->run();// The model may have called $weather multiple times before producing $result->textecho $result->text;
The loop terminates early as soon as a step produces a response with no tool calls.
When a tool handler declares a ToolExecutionContext as its last parameter, aisdk/core injects it automatically. The context carries the call ID, tool name, decoded arguments, and the full conversation history at the point of execution:
ToolExecutionContext is detected by PHP reflection. It is only injected when the handler’s last parameter is type-hinted as ToolExecutionContext — no additional configuration is needed.
use AiSdk\Generate;use AiSdk\OpenAI;use AiSdk\Schema;use AiSdk\Tool;$weather = Tool::make('weather', 'Get current weather') ->input(Schema::string(name: 'city')->required()) ->run(fn (string $city): string => "Sunny, 28 °C in {$city}");$result = Generate::text('What should I wear in Lahore today?') ->model(OpenAI::model('gpt-4o')) ->tool($weather) ->maxSteps(3) ->run();echo $result->text;