The capabilities
display is "fullscreen" or "overlay", and it is a schema enum rather than a list written into the description, because a model obeys a schema enum far more reliably than the same choice spelled out in prose. Vision and the avatar covers which to reach for.
The descriptions are written for a model. They say when to reach for a tool rather than what the code does, because that sentence is the only thing the model reads before deciding.
show_page is deliberately not in that list. It needs a renderer, and a deployment with none would still be telling every model it can show a web page, promising the caller and then apologising on every call. An absent tool is honest; a broken one is not. A plugin that does have a renderer registers SHOW_PAGE_TOOL itself.
More tools the SDK ships
None of these are built in either, for the same reason: an agent with nothing behind a tool should not be told it has one. Each is aToolSpec ready to register.
Declaring them
Every provider invented its own JSON for “here is a function you may call”, soschemas renders one list in the shape yours wants.
vision is the only option, and it is optional: leave it out and CallTools builds a VisionTools
of its own. Pass one when you want to give it a describer, a renderer or a budget, which is nearly
always, because a VisionTools with no describer can put pictures up but cannot say what it sees.
The instance is on tools.vision afterwards either way.
An unknown dialect falls back to
flat rather than throwing. A tool a model never sees is a worse outcome than a shape one provider happens to also accept, and a crash at connect time helps nobody.
Running them
Translate your provider’s tool-call frame into a name and an object, and hand it over:run instead:
ok is false only when the SDK knows the tool did not do what it was asked: a missing or malformed argument, a rejected value, a handler that threw, or a name no tool answers. It is not a verdict on the vision tools, which answer in sentences by design, so “there is nothing to look at” comes back as ok with the reason in the text.
Tools of your own
Your own tools go in the same place, so the model sees one list:end_call is an agent that has quietly lost the ability to hang up, and that is not something to discover mid-conversation.
The provider plugins already do all of this. Reach for
CallTools when you are writing a plugin of your own, or adding capabilities to a handler you wrote yourself.Whether to answer at all
A tool decides what an agent can do. In a meeting, the prior question is whether it should say anything at all, and the SDK ships that separately:GroupGate and the wake-phrase matching around
it. It is inert on a 1:1 call, so a plugin that never configures a phrase behaves exactly as it did
before. See Group calls.
Next
Vision and the avatar
What
look, look_back and show_image actually do.The avatar
What
express puts on the face, and the lip-sync beside it.Consulting
The two tools that hand real work to a second agent.
Call handler
The session every one of these tools is bound to.