Attaching Tools to Agents
Overview
Tools are standalone resources — you create them once and they live independently. An agent can only call the tools listed in its tools.items array. Attaching a tool means adding its ID to that list and updating the agent; every session started afterwards picks up the change.
The Attachment Shape
The agent's tools object holds a list of items — each item is a tool_id plus optional static_values (covered below). A top-level tool_choice controls whether the LLM is free to decide (auto) or must call a tool every turn (required).
{
"tools": {
"items": [
{ "tool_id": "tool_8f3kq2" },
{ "tool_id": "tool_orders_search", "static_values": { "tenant": "acme" } }
],
"tool_choice": "auto"
}
}Attaching a Tool
Use PATCH /agents/{agentId} and include the full tools object. The patch replaces the existing tools block — to add a tool to an agent that already has tools, send the combined list.
curl -X PATCH "https://api.d-id.com/agents/agt_xyz789" \
-H "Authorization: Basic <YOUR KEY>" \
-H "Content-Type: application/json" \
-d '{
"tools": {
"items": [
{ "tool_id": "tool_8f3kq2" },
{ "tool_id": "tool_orders_search" }
],
"tool_choice": "auto"
}
}'{
"id": "agt_xyz789",
"tools": {
"items": [
{ "tool_id": "tool_8f3kq2" },
{ "tool_id": "tool_orders_search" }
],
"tool_choice": "auto"
}
}Static Values
static_values lets you fix specific parameters that the LLM should not control. Common cases: tenant IDs, environment flags, locale, an account ID derived from the session.
{
"items": [
{
"tool_id": "tool_orders_search",
"static_values": {
"tenant": "acme",
"region": "eu-west-1"
}
}
]
}At call time, static_values are merged into whatever arguments the LLM produced. The LLM never sees these fields in its schema — keep them out of the tool's properties if you don't want the model to think about them. If a key appears in both the LLM's arguments and static_values, the static value wins.
Tool Choice
| Value | Behavior |
|---|---|
auto | The LLM decides whether to call a tool each turn. Use this for almost every agent. |
required | The LLM must call one of the available tools on every turn. Use for narrow agents whose entire job is to dispatch tool calls (e.g. a router or a structured-extraction agent). |
Triggers and End-of-Call Tools
Tools attached through tools.items are available to the LLM at every turn of the conversation. Sometimes you want a tool to run only at a specific point in the session — for example, when the chat ends — and not be available mid-conversation. That's what triggers are for.
A trigger binds a set of tools (and, optionally, an instruction prompt) to a session lifecycle event. When the event fires, the LLM is briefly given access to those tools and prompted to act.
The currently supported event is chat/end. Common use cases:
- Save a structured summary of the conversation to your CRM.
- File a ticket if the user expressed a complaint.
- Send a follow-up email through a third-party tool.
curl -X PATCH "https://api.d-id.com/agents/agt_xyz789" \
-H "Authorization: Basic <YOUR KEY>" \
-H "Content-Type: application/json" \
-d '{
"triggers": {
"chat/end": {
"tools": [
{ "tool_id": "tool_save_summary" },
{ "tool_id": "tool_open_ticket" }
],
"prompt_instructions": "Summarize the conversation in two sentences and save it. If the user reported a problem, open a ticket with the relevant details.",
"tool_choice": "auto"
}
}
}'prompt_instructions tells the LLM what to do when the event fires. The tools you list under a trigger do not have to also be listed in tools.items — they can be event-scoped only.
Webhooks: A Lighter Alternative
If your end-of-call action doesn't need the LLM — for example, just POST the raw transcript to your own service — use the webhooks field on the same chat/end trigger instead of tools. Webhooks fire as a direct HTTP call at event time with no LLM reasoning, no tool-choice decision, and no extra latency. Reach for trigger-tools when the LLM's judgment matters (deciding what to summarize, which ticket fields to fill, whether to act at all); reach for webhooks when you just need the data to leave the system on schedule.
Detaching a Tool
Send an updated list without the tool ID. To remove all tools, send items: [].
curl -X PATCH "https://api.d-id.com/agents/agt_xyz789" \
-H "Authorization: Basic <YOUR KEY>" \
-H "Content-Type: application/json" \
-d '{
"tools": {
"items": []
}
}'Deleting the tool itself with DELETE /tools/{toolId} does not automatically detach it from agents that reference it — clean up the agent first or expect the tool call to fail at runtime.
