Клиентские инструменты
Клиентские инструменты выполняются на вашей стороне. Когда модель вызывает такой инструмент, задача переходит в interrupted, а вы возвращаете результат и обработка продолжается.
В отличие от инструментов ассистента (которые вызывает сервер), клиентские инструменты задаёте вы прямо в запросе. Их удобно использовать, когда данные или действие доступны только на вашей стороне: геолокация пользователя, доступ к вашей БД, интерактивное подтверждение.
1. Объявить инструменты
Добавьте client_tools в тело POST /api/tasks:
{
"assistant_id": 1,
"input": [{ "type": "text", "text": "Что рядом со мной?" }],
"client_tools": [
{
"name": "get_user_location",
"description": "Возвращает город пользователя",
"input_schema": {
"type": "object",
"properties": { "precision": { "type": "string" } }
}
}
]
}
Поля name и description обязательны, input_schema (JSON Schema) — опционально.
2. Дождаться прерывания
Если модель вызвала клиентский инструмент, опрос GET /api/tasks/{uuid} вернёт статус
interrupted и список ожидающих вызовов в pending_tool_calls:
{
"uuid": "550e8400-…",
"status": "interrupted",
"pending_tool_calls": [
{ "id": "call_abc", "name": "get_user_location", "arguments": { "precision": "city" } }
]
}
3. Вернуть результаты
Выполните инструменты у себя и отправьте результаты. Нужно покрыть все вызовы из pending_tool_calls.
{
"tool_results": [
{ "id": "call_abc", "content": "Берлин" }
]
}
Ошибку инструмента верните так:
{ "id": "call_abc", "error": "Location unavailable", "reason": "permission_denied" }
Каждый элемент несёт id (из pending_tool_calls) и либо content, либо error (+опциональный reason).
4. Продолжение
После отправки результатов задача возвращается в processing. Продолжайте опрашивать: цикл
interrupted → tool-results → processing может повториться несколько раз, пока задача не
достигнет completed или failed.
POST /api/tasks → pending
GET /api/tasks/{uuid} → interrupted # модель вызвала client-инструмент
POST …/tool-results → processing # вернули результат
GET /api/tasks/{uuid} → completed # готово (или снова interrupted)
Итоговый tool_call в output
После завершения вызов клиентского инструмента появляется в output как обычный tool_call (без префикса):
{
"type": "tool_call",
"tool_call": {
"name": "get_user_location",
"input": { "precision": "city" },
"output": { "type": "content", "content": [{ "type": "text", "text": "Берлин" }] }
}
}
tool_resultsдолжны покрывать все ожидающие вызовы, иначе422.POST /tool-resultsдля задачи не в статусеinterruptedвернёт409.- Прерванная задача считается активной и учитывается в лимите одновременных задач.
runTask сам проходит весь interrupt-цикл:
вызывает ваш обработчик, отправляет результат и продолжает — до завершения.