Skip to main content
Tools are what a chat model can call while answering: search the web, read a page, generate an image, look something up in a knowledge base. A tool is a small class with a JSON schema and a call() method.
Read what the core will and won’t offer before you build. A brand-new tool key can be registered, but the built-in chat flow only offers tools whose key appears in the plan configuration, and that list is fixed. Your options are to replace an existing tool’s implementation, or to call your tool from your own plugin’s flows.

The interface

Implementation

src/Tools/WeatherTool.php
CallResponse takes the text result, the cost in credits, and optionally a library item when your tool produced something like an image.

Writing a good tool

  • Describe it for a model, not a human. Say when to use it and what it returns.
  • Keep the schema small. Few parameters, clear names, explicit required.
  • Return text. The content goes back into the conversation, so make it readable and compact.
  • Be fast, and time out. A slow tool stalls the whole answer.
  • Throw CallException for failures, so the model sees an error instead of a broken stream.
  • Charge for expensive work with CostCalculator, and return the amount in the response.

Register the tool

src/Plugin.php

What the core offers to models

When a message is generated, the tool collection decides which tools to expose. It checks, in order:
  1. isEnabled() on the tool.
  2. Whether the conversation is temporary, which disables context tools such as memory and canvas.
  3. Whether the plan’s tool configuration has the tool’s key enabled.
  4. Whether the user disabled that capability in their preferences.
Step 3 is the limit: Billing\Domain\ValueObjects\PlanConfig builds its tools map from a fixed list of keys. A key outside that list is never enabled on a plan, so the collection never yields it to the model.

What you can do instead

Register your class under an existing key, such as google_search, to swap the provider behind a capability administrators already control. Keep the same argument schema so existing prompts keep working.
If your plugin runs its own AI flow, for example an assistant of your own, you own the tool loop: build the definitions, call your tool when the model asks for it, and feed the result back. Nothing restricts which tools you offer there.
Some “tools” are better as context. Fetch what’s needed and add it to the system instructions rather than waiting for the model to ask.

Testing

With the capability enabled on the plan, the model calls your tool when it should.
The tool’s result appears in the answer, and the tool call is shown in the transcript.
A failure produces a graceful message rather than a broken response.
Credits are charged when the tool costs money.