Provider tools
Some capabilities run better on the provider's side: live web search, reading a page, searching uploaded files, executing code in a sandbox. Crustum\Ai\Providers\Tools holds these: classes extending ProviderTool that travel in the agent's tools() list exactly like local tools, but the provider executes them and the result feeds back into the run. What you own is the payload: which tool, its options, and which providers may run it.
Searching the web
WebSearch asks the provider for live results: current events, recent data, anything past the model's cutoff:
use Crustum\Ai\Providers\Tools\WebSearch;
$search = (new WebSearch())
->max(5)
->allow(['cakephp.org'])
->location(city: 'Berlin', country: 'DE');
echo $search->maxSearches . PHP_EOL;
echo implode(',', $search->allowedDomains) . PHP_EOL;
echo $search->city . ' ' . $search->country . PHP_EOL;5
cakephp.org
Berlin DESupported by: Anthropic, OpenAI, Azure, Gemini, xAI, Groq, OpenRouter.
Fetching pages
WebFetch reads specific URLs instead of searching. Give it to the agent when the addresses are already known:
use Crustum\Ai\Providers\Tools\WebFetch;
public function tools(): iterable
{
return [
(new WebFetch())->max(3)->allow(['book.cakephp.org']),
];
}Supported by: Anthropic, Gemini, OpenRouter.
Searching files
FileSearch queries vector stores by id: retrieval over uploaded documents without moving the data through your app:
use Crustum\Ai\Providers\Tools\FileSearch;
use Crustum\Ai\Providers\Tools\FileSearchQuery;
$tool = new FileSearch(stores: ['store_1'], where: fn (FileSearchQuery $query) => $query
->where('author', 'Larry Masters')
->whereNot('status', 'draft'));
echo implode(',', $tool->ids()) . PHP_EOL;
echo json_encode($tool->filters) . PHP_EOL;store_1
[{"type":"eq","key":"author","value":"Larry Masters"},{"type":"ne","key":"status","value":"draft"}]stores takes ids or Store instances (ids() normalizes either way). where takes an equality array or a FileSearchQuery closure (where, whereNot, whereIn, whereNotIn).
Supported by: OpenAI, Azure, Gemini, xAI.
Running code
CodeExecution runs code in a provider-hosted sandbox: calculations and data analysis the model should not guess at:
use Crustum\Ai\Providers\Tools\CodeExecution;
public function tools(): iterable
{
return [new CodeExecution()];
}On OpenAI or Azure, stored files reach the sandbox through provider options:
use Crustum\Ai\Providers\Tools\CodeExecution;
public function tools(): iterable
{
return [
(new CodeExecution())->withProviderOptions([
'container' => ['type' => 'auto', 'file_ids' => ['file_123']],
]),
];
}withProviderOptions() lives on the ProviderTool base, so every provider tool accepts it; closures receive the provider and must only capture serializable values. Supported by: Anthropic, OpenAI, Azure, Gemini, xAI, Groq.
Deferring definitions
Every exposed tool rides each request (see Deferring tool definitions). The ToolSearch wrapper defers a subset instead. The provider loads them on demand. strategy is regex (default) or bm25; anything else throws on construction:
use Crustum\Ai\Providers\Tools\ToolSearch;
public function tools(): iterable
{
return [
new SearchInvoices(),
new ToolSearch(tools: [new RefundOrder()], strategy: 'bm25'),
];
}At most one wrapper per request. A second throws. Supported by: OpenAI, Azure, Anthropic.
When the provider cannot run it
Support is a contract check: each gateway maps a provider tool only when the provider implements its Supports* interface (SupportsWebSearch, SupportsWebFetch, SupportsFileSearch, SupportsCodeExecution, SupportsToolSearch). Anything else never reaches the wire. Local tools pass through untouched, unsupported provider tools are dropped, and a ToolSearch on a provider without support unwraps to its plain tools:
use Crustum\Ai\AnonymousAgent;
use Crustum\Ai\Providers\Tools\WebSearch;
$response = (new AnonymousAgent('You are a probe.', [], [new WebSearch()]))
->prompt('What is new in CakePHP 5?');
echo $response->text . PHP_EOL;Answered without web search.The run above completes with the search silently dropped. The model answers from its own knowledge instead of failing.
Where next
- Tools — local tool authoring, validation, deferring
- Grouping tools — bundles and collections
- Sub-agents — delegation via
AgentTool