| client | 2 months ago | ||
| docs | 2 months ago | ||
| manuals | 2 months ago | ||
| navi | 2 months ago | ||
| tools | 2 months ago | ||
| workspace | 2 months ago | ||
| .env.example | 2 months ago | ||
| .gitignore | 2 months ago | ||
| CLAUDE.md | 2 months ago | ||
| README.md | 2 months ago | ||
| persona.txt | 2 months ago | ||
| pyproject.toml | 2 months ago | ||
| ssh_hosts.json.example | 2 months ago | ||
Модульная агентная система с REST API и WebSocket. FastAPI бэкенд, Ollama LLM, vanilla JS клиент.
python3 -m venv .venv source .venv/bin/activate pip install -e ".[dev]" cp .env.example .env # настрой OLLAMA_HOST, NAVI_PERSONA_FILE и др. uvicorn navi.main:app --reload --reload-dir navi --port 8000
Клиент: http://localhost:8000
Swagger UI: http://localhost:8000/docs
Debug panel: http://localhost:8000/debug
# 1. Создать сессию с профилем "secretary"
curl -X POST http://localhost:8000/sessions \
-H "Content-Type: application/json" \
-d '{"profile_id": "secretary"}'
# 2. Отправить сообщение (замени <session_id>)
curl -X POST http://localhost:8000/sessions/<session_id>/messages \
-H "Content-Type: application/json" \
-d '{"content": "Найди последние новости про Python 3.13"}'
ws://localhost:8000/ws/sessions/<session_id>
Клиент отправляет:
{"type": "message", "content": "...", "images": [...], "files": [...]}
Сервер стримит события в порядке:
stream_start plan_ready (если profile.planning_enabled — план до начала выполнения) thinking_delta* (reasoning chunks) thinking_end turn_thinking (reasoning из tool-calling турна, целиком) tool_started (начало вызова инструмента — pending card в UI) tool_call (инструмент завершён — результат) stream_delta* (финальный текстовый ответ) stream_end context_compressed (опционально — после сжатия контекста)
Остановить генерацию: POST /sessions/<session_id>/stop
Полная спецификация: docs/websocket.md и docs/api.md
navi/ ├── main.py # FastAPI app, роутеры, startup hooks ├── config.py # настройки через .env (pydantic-settings) ├── exceptions.py # доменные исключения ├── llm/ # LLM бэкенды: ollama.py, openai_backend.py ├── tools/ # встроенные инструменты (18 шт.) ├── profiles/ # профили агентов: secretary, server_admin, smart_home ├── core/ # Agent, registry, session, compressor, events ├── memory/ # долгосрочная память (SQLite, extractor) ├── workers/ # post-turn workers (CompressionWorker) └── api/ # роуты и WebSocket handler tools/ # пользовательские инструменты (auto-discovered) ├── enabled.json # список инструментов, активных во всех профилях ├── _template.py # шаблон формата ├── get_current_datetime.py └── user_notes.py manuals/ # markdown-мануалы для tool_manual docs/ # архитектурная документация persona.txt # глобальная личность и инструкции агента
Все три профиля имеют одинаковый базовый набор инструментов:
todo, scratchpad, switch_profile, web_search, web_view, http_request, filesystem, code_exec, terminal, ssh_exec, image_view, memory_search, memory_forget, reload_tools, write_tool, list_tools, tool_manual, spawn_agent
| ID | Назначение | Температура | Планирование |
|---|---|---|---|
secretary |
Исследования, написание текстов, повседневные задачи | 0.7 | ✓ |
server_admin |
Администрирование серверов, мониторинг, инфраструктура | 0.2 | ✓ |
smart_home |
Home Assistant, IoT, автоматизации | 0.3 | ✓ |
Пользовательский инструмент — создай tools/my_tool.py в формате:
name = "my_tool"
description = "Когда и зачем использовать."
parameters = {"type": "object", "properties": {...}, "required": [...]}
async def execute(params: dict) -> str:
return "результат"
Перезагрузка без рестарта сервера: инструмент reload_tools или write_tool.
Добавить во все профили: занести имя в tools/enabled.json.
Новый профиль — создай navi/profiles/my_profile.py, добавь в ALL_PROFILES в __init__.py.
Новый LLM бэкенд — реализуй LLMBackend из navi/llm/base.py, зарегистрируй в build_default_registries() в navi/core/registry.py.
Ключевые переменные (полный список: docs/config.md):
OLLAMA_HOST=http://localhost:11434 OLLAMA_DEFAULT_MODEL=gemma4:e2b-it-q8_0 OLLAMA_NUM_CTX=65536 OLLAMA_THINK=true NAVI_PERSONA_FILE=persona.txt