Base URL: http://localhost:8000
GET /healthПроверка доступности сервера.
Response 200
{ "status": "ok" }
GET /agents/profilesСписок доступных профилей агента.
Response 200
[
{
"id": "secretary",
"name": "Secretary",
"description": "General-purpose assistant",
"enabled_tools": ["todo", "web_search", "filesystem", "..."],
"llm_backend": "ollama",
"model": "gemma4:e2b-it-q8_0"
}
]
GET /agents/toolsСписок всех зарегистрированных инструментов (built-in + user tools).
Response 200
[
{ "name": "web_search", "description": "Search the web using DuckDuckGo." },
{ "name": "filesystem", "description": "Read, write and list files." }
]
Сессия — это контейнер для диалога с агентом. Каждая сессия привязана к профилю и хранит историю сообщений.
POST /sessionsСоздать новую сессию.
Request body
{ "profile_id": "secretary" }
Response 201
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"profile_id": "secretary",
"created_at": "2026-04-10T18:00:00+00:00"
}
Errors
404 — профиль не найденGET /sessionsСписок всех сессий, отсортированных по активности (закреплённые первыми).
Response 200
[
{
"session_id": "550e8400-...",
"profile_id": "secretary",
"message_count": 12,
"preview": "Последние 60 символов последнего сообщения",
"pinned": false,
"created_at": "2026-04-10T15:00:00+00:00",
"last_active": "2026-04-10T18:00:00+00:00"
}
]
GET /sessions/{session_id}Полная информация о сессии с историей сообщений (display history — никогда не сжимается).
Response 200
{
"session_id": "550e8400-...",
"profile_id": "secretary",
"created_at": "...",
"last_active": "...",
"messages": [
{
"role": "user",
"content": "Привет",
"created_at": "2026-04-10T18:00:00+00:00"
},
{
"role": "assistant",
"content": "Привет. Чем помочь?",
"created_at": "2026-04-10T18:00:05+00:00"
},
{
"role": "assistant",
"tool_calls": [
{
"id": "abc123",
"name": "web_search",
"arguments": { "query": "..." }
}
]
},
{
"role": "tool",
"content": "результат инструмента",
"tool_call_id": "abc123",
"name": "web_search"
}
]
}
Поля сообщения (role всегда присутствует, остальные — по наличию):
| Поле | Тип | Описание | |||
|---|---|---|---|---|---|
role |
`user\ | assistant\ | tool\ | system` | Автор сообщения |
content |
`string\ | null` | Текст сообщения | ||
images |
string[] |
Base64-строки изображений (user/assistant) | |||
tool_calls |
ToolCall[] |
Вызовы инструментов (assistant) | |||
tool_call_id |
string |
ID вызова, к которому относится ответ (tool) | |||
name |
string |
Имя инструмента (tool) | |||
created_at |
string (ISO 8601) |
Время создания | |||
is_summary |
bool |
Сжатый блок истории (injected by compressor) |
Errors
404 — сессия не найденаDELETE /sessions/{session_id}Удалить сессию и её файлы.
Response 204 — нет тела
Errors
404 — сессия не найденаPATCH /sessions/{session_id}/pinЗакрепить или открепить сессию.
Request body
{ "pinned": true }
Response 200
{ "session_id": "...", "pinned": true }
GET /sessions/{session_id}/contextLLM-контекст сессии (то, что модель реально видит). Может отличаться от messages — сжатые истории заменяют часть сообщений. Endpoint для отладки.
Response 200
{
"session_id": "...",
"profile_id": "secretary",
"message_count": 8,
"total_chars": 4200,
"context": [ ...сообщения в том же формате, что и messages... ]
}
POST /sessions/{session_id}/filesЗагрузить файл для сессии. Используется перед отправкой сообщения, если нужно приложить файл.
Request: multipart/form-data, поле file.
Ограничения
.exe, .dll, .so, .sh, .bat, .cmd, .ps1, .vbs, .bin, .elf и другие исполняемые форматыfile_1.txt, file_2.txt, ...)Response 201
{
"name": "report.pdf",
"size": 102400,
"path": "session_files/550e8400-.../report.pdf",
"content_type": "application/pdf"
}
Errors
400 — запрещённое расширение404 — сессия не найдена413 — файл превышает лимитPOST /sessions/{session_id}/messagesОтправить сообщение и получить ответ синхронно (без стриминга). Блокирует до завершения всего цикла агента.
Request body
{ "content": "Сколько звёзд в галактике?" }
Response 200
{ "role": "assistant", "content": "По оценкам, от 100 до 400 миллиардов." }
Errors
404 — сессия не найдена500 — ошибка агента или превышен лимит итерацийДля production-клиентов предпочтительнее WebSocket — он даёт стриминг, прогресс выполнения инструментов и мышление модели.
WS /ws/sessions/{session_id}Основной канал для общения с агентом в реальном времени. Поддерживает стриминг текста, стриминг мышления, события инструментов, прикрепление файлов и изображений.
Подключение: если сессия не найдена, сервер закрывает соединение с кодом 4004.
Reconnect: если клиент переподключается во время активного стрима, сервер автоматически дошлёт пропущенные события — никаких дополнительных действий не требуется.
Все сообщения от клиента — JSON-объекты.
{
"type": "message",
"content": "Текст сообщения",
"images": ["base64string...", "..."],
"files": [
{ "name": "report.pdf", "size": 102400, "path": "session_files/.../report.pdf" }
]
}
| Поле | Обязательно | Описание |
|---|---|---|
type |
да | Всегда "message" |
content |
да | Текст сообщения (непустой) |
images |
нет | Список base64-строк изображений. Допускается как чистый base64, так и data:image/...;base64,... — сервер обрежет префикс автоматически |
files |
нет | Файлы, загруженные через POST /sessions/{id}/files. Сервер дописывает их пути в текст сообщения, чтобы агент знал об их существовании |
Сервер присылает события последовательно в порядке их возникновения.
stream_start{ "type": "stream_start" }
Начало обработки сообщения. Клиент должен заблокировать ввод.
thinking_delta{ "type": "thinking_delta", "delta": "фрагмент мышления..." }
Фрагмент внутреннего рассуждения модели (streaming). Приходит только если у модели включён режим thinking. Накапливайте delta до thinking_end.
thinking_end{ "type": "thinking_end" }
Мышление завершено. После этого начнётся либо стриминг текста (stream_delta), либо вызов инструментов.
turn_thinking{
"type": "turn_thinking",
"thinking": "полный текст рассуждения...",
"is_subagent": false
}
Блок мышления модели во время выбора инструмента. Приходит целиком (не по кускам). is_subagent: true означает, что мышление от субагента внутри spawn_agent.
tool_started{
"type": "tool_started",
"tool": "web_search",
"args": { "query": "погода в москве" },
"is_subagent": false
}
Агент начал выполнение инструмента. Приходит немедленно, до завершения вызова — для показа спиннера. is_subagent: true — вызов из субагента.
tool_call{
"type": "tool_call",
"tool": "web_search",
"args": { "query": "погода в москве" },
"result": "Сегодня в Москве +12°C, облачно.",
"success": true,
"is_subagent": false
}
Инструмент завершил работу. Приходит после tool_started с тем же tool и args. success: false — инструмент вернул ошибку.
stream_delta{ "type": "stream_delta", "delta": "фрагмент ответа..." }
Фрагмент финального текстового ответа агента (streaming). Накапливайте в строку.
stream_end{
"type": "stream_end",
"content": "полный текст ответа",
"context_tokens": 4913,
"max_context_tokens": 65536
}
Агент завершил ответ. content — полный накопленный текст (дублирует сумму stream_delta). context_tokens — сколько токенов использовано в контексте. Клиент должен разблокировать ввод.
context_compressed{
"type": "context_compressed",
"messages_before": 42,
"messages_after": 12
}
Контекст был автоматически сжат после ответа (компрессия срабатывает при заполнении ≥80% контекстного окна). Информационное событие.
error{ "type": "error", "message": "Session not found" }
Ошибка обработки. После некоторых ошибок стрим продолжается, после других — завершается.
Простой вопрос без инструментов:
stream_start thinking_delta × N (если модель думает) thinking_end stream_delta × N stream_end
Запрос с вызовом инструментов:
stream_start turn_thinking (мышление при выборе инструмента, если есть) tool_started tool_call turn_thinking (мышление перед следующим инструментом, если есть) tool_started tool_call thinking_delta × N (финальный ответ) thinking_end stream_delta × N stream_end context_compressed (опционально, если контекст переполнен)
Запрос с субагентом (spawn_agent):
stream_start tool_started (spawn_agent, is_subagent=false) turn_thinking (is_subagent=true) tool_started (инструмент субагента, is_subagent=true) tool_call (is_subagent=true) tool_call (spawn_agent завершён, is_subagent=false) stream_delta × N stream_end
Статика клиента: GET /static/** — раздаётся из директории client/. Заголовок Cache-Control: no-store.
Загруженные файлы сессии: хранятся в session_files/{session_id}/. Агент обращается к ним напрямую через инструмент filesystem. Удаляются через 24 часа неактивности сессии или при удалении сессии.
| HTTP | Причина |
|---|---|
400 |
Запрещённый тип файла |
404 |
Сессия или профиль не найдены |
413 |
Файл превышает 200 MB |
500 |
Внутренняя ошибка агента |
WS 4004 |
Сессия не найдена при подключении |