“Created by a SysAdmin for developers. Focus on safety, portability, and zero-nonsense execution. No Docker, no heavy environments, just one binary.”
Десктопный AI-агент с runtime на LangGraph и графическим интерфейсом на PySide6.
Работает с файлами, shell-командами, системой, MCP-серверами и веб-поиском.
Запуск из исходников: python main.py.
Сборка в portable .exe для Windows: build.bat.
Это не AI IDE. Цель проекта — предоставить переносимого автономного помощника, которого можно скопировать на другой компьютер и сразу использовать с минимальной настройкой.
Основные приоритеты:
- переносимость;
- безопасность;
- локальные инструменты;
- автоматизация;
- работа с файлами и системой;
- поиск информации в интернете;
- надёжность.
Проект не стремится конкурировать с AI IDE по количеству функций и не пытается заменить специализированные инструменты для разработки. Фокус — практическое выполнение повседневных задач: работа с файлами, shell-командами, системой, веб-поиском, документацией, скриптами и автоматизацией в одном переносимом приложении без сложной инфраструктуры и дополнительных сервисов.
- Графовый runtime на
LangGraphс bounded recovery и self-correction - GUI: история чатов, streaming transcript, tool cards, approvals, вложения
- Инструменты: filesystem, shell, web search, system info, process management, MCP
- Approval-паузы перед мутирующими и деструктивными действиями
- Автосуммаризация контекста при длинных сессиях
- Несколько профилей моделей с переключением прямо в GUI
- Durable checkpoints — сессии сохраняются между запусками
- Опциональный image input, если модель его поддерживает
Требования: Python 3.10+, API-ключ Gemini или OpenAI.
python -m venv venv
venv\Scripts\pip.exe install -r requirements.txt
Copy-Item env_example.txt .env
# Открой .env и укажи API-ключ
python main.py.\build.batИспользует PyInstaller в режиме --onefile --windowed. Результат — один .exe без зависимостей.
START
→ summarize # сжать контекст если сессия стала большой
→ update_step
→ agent # LLM решает: ответить / вызвать tool / recovery
→ approval # пауза перед мутирующим действием
→ tools
→ tools # исполнить tool calls
→ recovery # если tool вернул ошибку
→ update_step
→ recovery # если агент вернул protocol error или loop
→ update_step
→ END
→ END
MAX_LOOPSи per-tool loop guards предотвращают бесконечные циклы.- Recovery использует stateful error tracking:
attempts_by_strategy,progress_markers,llm_replan_attempted_for— адаптивные повторы с учётом уникальных fingerprints ошибок. - При смене проблемы (новый fingerprint) retry-бюджет сбрасывается; для одной и той же проблемы разрешены несколько
llm_replanпопыток в рамкахSELF_CORRECTION_RETRY_LIMIT.
Transcript — streaming-ответы, tool cards с аргументами и результатами, summary-сообщения, статусные notice.
Composer:
- Вставка файлов через
Add files…, drag-and-drop или clipboard paste @-mention popup с файлами и директориями текущего workspace (обновляется динамически)- Нормализация текста перед отправкой:
\r\n→\n, удаление control-символов - Лимит 10 000 символов на запрос с inline-предупреждением при усечении
Горячие клавиши:
| Клавиша | Действие |
|---|---|
Enter |
Отправить сообщение |
Shift+Enter |
Новая строка |
Ctrl+N |
Новый чат |
Ctrl+B |
Показать / скрыть боковую панель |
Ctrl+I |
Info popup |
↑ / ↓ в пустом composer |
История отправленных сообщений |
- Approvals включены по умолчанию для write, delete, move и process-launch операций
- Shell-команды классифицируются перед выполнением (read-only / mutating / destructive)
- MCP tools требуют approval, если
policy.read_onlyявно не выставлен вtrue - Tool errors переводят выполнение в recovery, не игнорируются
- Workspace boundary check: мутирующие операции не могут выйти за пределы рабочей папки
- API keys, bearer tokens и query tokens редактируются из логов через
SensitiveDataFilter MAX_BACKGROUND_PROCESSESограничивает количество фоновых процессов
request_user_input — отдельный инструмент для блокирующего выбора пользователя:
- не более одного вызова за ход
- нельзя батчить с другими tool calls в одном ответе
- использовать только когда следующий шаг реально заблокирован одним конкретным выбором пользователя или отсутствующим внешним значением, которое нельзя получить из контекста или tools
- не использовать для approval рискованных действий: это отдельный flow
- задавать ровно один короткий вопрос
- передавать 2-5 коротких взаимоисключающих опций
- если один вариант явно лучший, указывать его через
recommended - после resume продолжать с выбранным ответом, а не спрашивать заново в том же ходе
Несколько профилей моделей хранятся через core/model_profiles.py и переключаются в GUI.
Каждый профиль содержит: провайдера, имя модели, API key, опциональный base_url для OpenAI-compatible бэкендов, флаг image input, статус enabled/disabled.
- Активный профиль выбирается в GUI;
.envиспользуется только для bootstrap начального набора - Legacy-ключи
MODEL,API_KEY,BASE_URLподдерживаются для import/совместимости - Для Gemini-профилей
base_urlигнорируется
При добавлении или редактировании профиля в Model Profiles список моделей загружается автоматически — вводить имя вручную не нужно.
Gemini: после ввода API Key список загружается автоматически (debounce 600 мс). Модели фильтруются: остаются только те, что поддерживают generateContent и принадлежат семействам gemini / gemma. Автоматически исключаются embedding-, audio-, image- и служебные модели. Список сгруппирован и отсортирован по убыванию версии.
OpenAI-compatible: список загружается при заполнении обоих полей — API Key и Base URL. Применяется базовая фильтрация по ключевым словам. Если загрузка не удалась — поле переходит в режим ручного ввода.
Логика реализована в core/model_fetcher.py. При переключении между профилями с одним ключом список берётся из кеша без повторного запроса.
Агент поддерживает автоматическую ротацию пула API-ключей для каждого профиля. Это позволяет обходить лимиты бесплатных тарифов (Rate Limits) и обеспечивать бесперебойную работу.
- Как это работает: вы можете указать несколько ключей для одной модели. Если текущий ключ исчерпал лимит или вернул ошибку, агент двигается к следующему ключу по кругу и повторяет попытку без прерывания сессии. После одного полного круга, если ни один ключ не сработал, выполнение останавливается с сообщением: "All API keys have been used without success. Please try again later or check your key limits and validity." — пользователь сам решает, что делать дальше (подождать, обновить ключи и т.д.).
- Управление: настройка доступна в GUI через кнопку «цикличные стрелки» рядом с полем API Key в редакторе профиля.
- Безопасность: ключи не помечаются как невалидные и не исключаются из пула. Любой ключ может стать рабочим через некоторое время (например, когда снимется rate-limit), поэтому пул остаётся неизменным.
- Graph checkpoints:
sqlite(по умолчанию) илиmemory .agent_state/checkpoints.sqlite— durable checkpoint store.agent_state/session.json— активная сессия.agent_state/session_index.json— индекс всех сессийlogs/runs/— JSONL-логи каждого запуска
mcp.json задаёт опциональные MCP-серверы. Все серверы выключены по умолчанию.
Поведение policy:
policy.read_only |
Поведение |
|---|---|
true |
Tool считается read-only, approval не требуется |
false |
Требует approval |
| не указан | Консервативный режим: approval по умолчанию |
Минимальный пример подключения удалённого сервера:
{
"context7": {
"type": "remote",
"url": "https://mcp.context7.com/mcp",
"transport": "http",
"enabled": true,
"policy": {
"read_only": true
}
}
}Промпт собирается из нескольких слоёв при каждом вызове агента:
| Слой | Файл / модуль | Содержимое |
|---|---|---|
| Базовый | prompt.txt |
Системный промпт агента |
| Runtime | core/runtime_prompt_policy.py |
OS, shell, workspace, дата, tool policy |
| Safety | core/context_builder.py |
Workspace boundary, shell warning |
| Recovery | core/recovery_manager.py |
Инструкции при активной ошибке |
| Memory | state: summary |
Автосуммаризованный контекст прошлых ходов |
Все настройки читаются из .env через core/config.py. Скопируй env_example.txt в .env и заполни нужные поля.
| Переменная | По умолчанию | Описание |
|---|---|---|
PROVIDER |
gemini |
gemini или openai |
GEMINI_API_KEY |
— | Обязателен для Gemini |
GEMINI_MODEL |
gemini-1.5-flash |
Имя модели Gemini |
OPENAI_API_KEY |
— | Обязателен для OpenAI (если нет OPENAI_BASE_URL) |
OPENAI_MODEL |
gpt-4o |
Имя модели OpenAI |
OPENAI_BASE_URL |
— | Для OpenAI-compatible бэкендов (Ollama и др.) |
ENABLE_MODEL_REASONING |
true |
Включает provider-side reasoning/thinking для поддерживаемых моделей |
MODEL_REASONING_EFFORT |
medium |
Усилие reasoning для OpenAI/OpenAI-compatible моделей (none, minimal, low, medium, high, xhigh) |
GEMINI_THINKING_BUDGET |
4096 |
Thinking budget для gemini-2.5* / gemini-3*; старые Gemini-модели получают запрос без этого параметра |
PROVIDER_REGISTRY_PATH |
provider_registry.json |
Реестр OpenAI-compatible агрегаторов и их reasoning-параметров |
ACTIVE_MODEL_PROFILE_ID |
— | ID активного профиля модели (для ротации ключей) |
SHOW_MODEL_THOUGHTS |
false |
Legacy-флаг отображения reasoning (runtime выставляет false) |
Подробная инструкция по provider_registry.json, полям схемы, matching rules и добавлению новых агрегаторов находится в ./docs/provider_registry_guide.md.
| Переменная | Описание |
|---|---|
TEMPERATURE |
Температура модели |
TOP_P |
Nucleus sampling (0.95 по умолчанию; none/пусто — не отправлять) |
TOP_K |
Candidate pool limit для Gemini/поддерживаемых SDK (40 по умолчанию; для OpenAI-compatible не отправляется) |
MAX_LOOPS |
Максимум шагов на один запрос (default: 50) |
TOOL_LOOP_WINDOW |
Окно истории для детекции дублей tool calls |
TOOL_LOOP_LIMIT_MUTATING |
Лимит повторов для мутирующих инструментов |
TOOL_LOOP_LIMIT_READONLY |
Лимит повторов для read-only инструментов |
SELF_CORRECTION_RETRY_LIMIT |
Потолок попыток self-correction |
| Переменная | Описание |
|---|---|
MODEL_SUPPORTS_TOOLS |
Включить tool calling |
ENABLE_TEXT_TOOL_CALL_RECOVERY |
Диагностический fallback для провайдеров, которые пишут `call:...<tool_call |
ENABLE_FILESYSTEM_TOOLS |
Инструменты для работы с файлами |
ENABLE_SHELL_TOOL |
Shell-выполнение команд |
ENABLE_SEARCH_TOOLS |
Web search через Tavily |
ENABLE_SYSTEM_TOOLS |
Информация о системе |
ENABLE_PROCESS_TOOLS |
Управление процессами |
ENABLE_APPROVALS |
Approval-паузы перед рискованными действиями |
ALLOW_EXTERNAL_PROCESS_CONTROL |
Разрешить управление внешними процессами |
TAVILY_API_KEY |
Ключ Tavily для web search |
| Переменная | Описание |
|---|---|
MAX_FILE_SIZE |
Максимальный размер файла (поддерживает 300MB, 4096) |
MAX_READ_LINES |
Лимит строк при чтении файла |
MAX_TOOL_OUTPUT |
Лимит символов в выводе инструмента |
MAX_SEARCH_CHARS |
Лимит символов в результатах поиска |
MAX_BACKGROUND_PROCESSES |
Лимит фоновых процессов |
STREAM_TEXT_MAX_CHARS |
Лимит символов streaming-текста |
STREAM_EVENTS_MAX |
Лимит streaming-событий |
STREAM_TOOL_BUFFER_MAX |
Буфер streaming tool output |
| Переменная | Описание |
|---|---|
SESSION_SIZE |
Порог токенов для запуска суммаризации |
SUMMARY_RESERVED_TOKENS |
Запас на системные инструкции, tool schemas и provider overhead |
SUMMARY_KEEP_LAST |
Сколько последних сообщений не трогать при суммаризации |
MAX_RETRIES |
Число попыток при ошибке LLM |
RETRY_DELAY |
Задержка между попытками (секунды) |
| Переменная | По умолчанию | Описание |
|---|---|---|
CHECKPOINT_BACKEND |
sqlite |
sqlite или memory |
CHECKPOINT_SQLITE_PATH |
.agent_state/checkpoints.sqlite |
Путь к БД |
SESSION_STATE_PATH |
.agent_state/session.json |
Активная сессия |
MODEL_PROFILE_CONFIG_PATH |
.agent_state/config.json |
Файл профилей моделей и активного профиля |
RUN_LOG_DIR |
logs/runs |
Директория JSONL-логов |
LOG_FILE |
logs/agent.log |
Файл лога |
PROMPT_PATH |
prompt.txt |
Путь к системному промпту |
MCP_CONFIG_PATH |
mcp.json |
Путь к конфигу MCP |
| Переменная | Описание |
|---|---|
DEBUG |
Включить debug-режим |
LOG_LEVEL |
Уровень логирования (INFO, DEBUG, WARNING) |
DEBUG_REASONING_STREAM |
Отдельный подробный лог reasoning/thinking stream для диагностики провайдеров |
STRICT_MODE |
Строгий режим: без догадок, точное выполнение |
Подробная карта модулей находится в docs/PROJECT_STRUCTURE.md. Ниже — краткая рабочая схема.
.
├── main.py # Точка входа GUI
├── agent.py # Сборка LLM, tools и LangGraph workflow
├── prompt.txt # Основной системный промпт
├── prompt_dev.txt # Дополнительный dev/devops-промпт
├── mcp.json # Конфигурация MCP-серверов
├── env_example.txt # Шаблон .env
├── provider_registry.json # Reasoning kwargs для OpenAI-compatible провайдеров
├── ./docs/provider_registry_guide.md
├── build.bat # Сборка portable .exe
├── requirements.txt
├── core/ # Ядро агента: config, state, policies, recovery, provider registry
│ └── nodes/ # Узлы LangGraph: context, llm, agent, tools, approval, recovery
├── tools/ # Filesystem, shell, search, system, process, user input, MCP registry
│ └── filesystem_impl/ # Низкоуровневые filesystem helpers
├── ui/ # PySide6 GUI, runtime worker, streaming/status handling
│ ├── window_components/ # Главное окно, sidebar, inspector, menu, status bar
│ └── widgets/ # Transcript, composer, messages, tool cards, dialogs, panels
├── docs/
│ └── PROJECT_STRUCTURE.md
├── tests/ # Runtime, UI, tools, provider registry, logging, policies
├── .agent_state/ # Локальное состояние, профили, checkpoints
└── logs/ # JSONL/runtime/debug logs
20 тестовых файлов:
| Файл | Что покрывает |
|---|---|
test_model_fetcher.py |
Фильтрация моделей, нормализация имён, коды ошибок API, fallback-логика |
test_api_key_rotation.py |
Circular key-pool rotation, exhaustion handling, auth/rate-limit error classification |
test_cli_ux.py |
GUI: composer, transcript, tool cards, streaming, sidebar, attachments, history, mentions, approvals |
test_stream_and_filesystem.py |
Streaming events, filesystem tools, tool output, cli_exec |
test_runtime_refactor.py |
Runtime payloads, transcript restore, tool group logic, run lifecycle |
test_critic_graph.py |
LangGraph workflow, node orchestration, tool batching |
test_self_correction_engine.py |
Recovery strategies, fingerprinting, loop detection |
test_policy_engine.py |
Shell command classification, tool metadata, approval rules |
test_model_profiles.py |
Profile CRUD, switching, validation, serialization |
test_session_utils.py |
Session ID generation, index management |
test_runtime_session_coordination.py |
Session state coordination, load/save |
test_tooling_refactor.py |
Tool registry, MCP loading, tool metadata |
test_provider_registry.py |
Matching OpenAI-compatible провайдеров и reasoning kwargs |
test_input_sanitizer.py |
Input sanitization, truncation, control chars |
test_logging_config.py |
Log configuration, sensitive data filtering |
test_intent_engine.py |
Intent parsing, routing |
test_main_window_facade.py |
MainWindow facade behavior |
test_ui_helpers.py |
UI helper utilities |
test_refactor_services.py |
Service refactoring, internal APIs |
test_runtime_payloads.py |
Payload builders, serialization |
Запуск:
venv\Scripts\python.exe -m pytestДля более эффективного поиска по файлам, логам, конфигурациям и кодовым базам рекомендуется установить ripgrep (rg). Агент может использовать его для быстрого поиска файлов, символов, строк и других данных вместо последовательного чтения большого количества файлов.
Официальный репозиторий: BurntSushi/ripgrep. Готовые сборки для Windows доступны в Releases. Обычно нужен архив x86_64-pc-windows-msvc.zip.
Варианты установки:
- Добавить папку с
rg.exeв системныйPATHи проверить командойrg --version. - Для portable-сборки скопировать
rg.exeрядом с исполняемым файлом агента. Если командаrgне находится автоматически, используйте путь.\rg.exeили добавьте папку агента вPATH.
Пример portable-папки:
PortableAgent/
├── Agent.exe
├── rg.exe
├── .env
├── prompt.txt
└── ...
Если rg отсутствует, агент продолжит работать в обычном режиме, используя стандартные инструменты файловой системы.
| Пакет | Назначение |
|---|---|
langgraph |
Граф агента и state management |
langchain |
LLM abstraction, tool calling |
langchain-google-genai |
Gemini provider |
langchain-openai |
OpenAI / compatible provider |
langchain-mcp-adapters |
MCP интеграция |
PySide6 |
GUI |
pydantic-settings |
Конфигурация через .env |
tiktoken |
Подсчёт токенов для суммаризации |
tavily-python |
Web search |
psutil |
Системные инструменты и процессы |
httpx |
HTTP для MCP и fetch |
aiofiles |
Async файловые операции |
mcp |
Model Context Protocol |
requests |
HTTP-клиент (Google API, Tavily) |
sqlite-vec |
Vector-расширение для SQLite checkpoints |
