Newer
Older
navi-1 / docs / api.md
@Eugene Sukhodolskiy Eugene Sukhodolskiy on 10 Apr 14 KB Add API reference documentation

Navi API Reference

Base URL: http://localhost:8000


REST API

Health

GET /health

Проверка доступности сервера.

Response 200

{ "status": "ok" }

Profiles & Tools

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." }
]

Sessions

Сессия — это контейнер для диалога с агентом. Каждая сессия привязана к профилю и хранит историю сообщений.

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}/context

LLM-контекст сессии (то, что модель реально видит). Может отличаться от 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.

Ограничения

  • Максимальный размер: 200 MB
  • Запрещённые расширения: .exe, .dll, .so, .sh, .bat, .cmd, .ps1, .vbs, .bin, .elf и другие исполняемые форматы
  • При совпадении имён файл переименовывается (file_1.txt, file_2.txt, ...)
  • Файлы удаляются автоматически через 24 часа неактивности сессии

Response 201

{
  "name": "report.pdf",
  "size": 102400,
  "path": "session_files/550e8400-.../report.pdf",
  "content_type": "application/pdf"
}

Errors

  • 400 — запрещённое расширение
  • 404 — сессия не найдена
  • 413 — файл превышает лимит

Messages (non-streaming)

POST /sessions/{session_id}/messages

Отправить сообщение и получить ответ синхронно (без стриминга). Блокирует до завершения всего цикла агента.

Request body

{ "content": "Сколько звёзд в галактике?" }

Response 200

{ "role": "assistant", "content": "По оценкам, от 100 до 400 миллиардов." }

Errors

  • 404 — сессия не найдена
  • 500 — ошибка агента или превышен лимит итераций

Для production-клиентов предпочтительнее WebSocket — он даёт стриминг, прогресс выполнения инструментов и мышление модели.


WebSocket

WS /ws/sessions/{session_id}

Основной канал для общения с агентом в реальном времени. Поддерживает стриминг текста, стриминг мышления, события инструментов, прикрепление файлов и изображений.

Подключение: если сессия не найдена, сервер закрывает соединение с кодом 4004.

Reconnect: если клиент переподключается во время активного стрима, сервер автоматически дошлёт пропущенные события — никаких дополнительных действий не требуется.


Client → Server

Все сообщения от клиента — 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. Сервер дописывает их пути в текст сообщения, чтобы агент знал об их существовании

Server → Client

Сервер присылает события последовательно в порядке их возникновения.

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 Сессия не найдена при подключении