zot

by patriceckhart (community) · Go, Linux, macOS, Windows, Ollama

Assistant AI Assistants Open Source v0.3.48 · 22.08.2026 активный

Ещё один харнесс для coding-агента — лёгкий, написан на Go.

v0.3.48
22.08.2026 current

Установка
go install github.com/patriceckhart/zot/cmd/zot@latest
показать оригинал переведено ИИ

zot coding agent harness


license Go 1.25+ 30+ providers

zot.sh

Что это?

Ещё один харнесс для coding-агента, лёгкий и написанный на go.

  • один статический бинарник.
  • встроенные провайдеры для Anthropic, OpenAI/Codex/Responses, Kimi, DeepSeek, Google Gemini/Vertex, GitHub Copilot, Bedrock, Azure OpenAI, OpenRouter, Groq, Cerebras, xAI, Together, Hugging Face, Mistral, Moonshot, Z.AI, Xiaomi, MiniMax, Fireworks, Vercel AI Gateway, OpenCode, Cloudflare AI и Ollama/локальных моделей.
  • четыре инструмента (read, write, edit, bash).
  • три режима запуска (интерактивный tui, print, json).
  • встроенный telegram-бот.
  • расширения на любом языке через subprocess + json-rpc. По умолчанию ничего не установлено; подключается через zot ext install или zot --ext. См. docs/extensions.md.
  • пользовательские и расширенные темы через JSON; см. docs/themes.md.
  • постоянные инструкции через файлы AGENTS.md (глобальные и по-проектные); см. Постоянные инструкции.
  • переиспользуемые инструкции через файлы SKILL.md; см. docs/skills.md.
  • переносимые агенты из локальных директорий, файлов .zot или временных публичных загрузок с GitHub; см. docs/zotfiles.md.

Установка

Однострочник (macOS, Linux)

curl -fsSL https://www.zot.sh/install.sh | bash

Определяет вашу ОС и архитектуру, скачивает последний релиз с GitHub, проверяет SHA-256 по checksums.txt релиза, распаковывает бинарник и кладёт в /usr/local/bin, ~/.local/bin или ~/bin — какая доступна для записи первой. Можно передать версию или префикс для закрепления:

curl -fsSL https://www.zot.sh/install.sh | bash -s -- v0.0.1 ~/bin

Однострочник (Windows, PowerShell)

iwr -useb https://www.zot.sh/install.ps1 | iex

Кладёт zot.exe в $HOME\bin и добавляет в пользовательский PATH, если его там нет. После этого откройте новый терминал.

go install

go install github.com/patriceckhart/zot/cmd/zot@latest

Установленный бинарник сообщает версию тегированного модуля и поддерживает zot update.

Из исходников

git clone https://github.com/patriceckhart/zot
cd zot
make build        # собирает ./bin/zot
make install      # в $GOPATH/bin

Готовые бинарники

Каждый релиз на странице релизов поставляет архивы для Linux, macOS и Windows на amd64 и arm64 (кроме windows/arm64), плюс файл checksums.txt. Скачайте, проверьте, chmod +x и положите в $PATH.

Аутентификация

Проще всего просто запустить zot и ввести /login. TUI открывается даже без учётных данных и проводит вас через flow логина через браузер.

Порядок поиска учётных данных

  1. флаг --api-key
  2. специфичная для провайдера переменная окружения (ANTHROPIC_API_KEY, OPENAI_API_KEY, KIMI_API_KEY, MOONSHOT_API_KEY, DEEPSEEK_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY, GROQ_API_KEY, OPENROUTER_API_KEY, MISTRAL_API_KEY, XAI_API_KEY, CEREBRAS_API_KEY, TOGETHER_API_KEY, HF_TOKEN, ZAI_API_KEY, XIAOMI_API_KEY, MINIMAX_API_KEY, FIREWORKS_API_KEY, AI_GATEWAY_API_KEY, COPILOT_GITHUB_TOKEN, GITHUB_COPILOT_TOKEN и другие для специфичных бэкендов провайдеров)
  3. $ZOT_HOME/auth.json (API-ключ или OAuth-токен; режим доступа 0600)

$ZOT_HOME по умолчанию: - Все платформы: $XDG_STATE_HOME/zot, если задан XDG_STATE_HOME - macOS резерв: ~/Library/Application Support/zot - Linux резерв: ~/.local/state/zot - Windows резерв: %LOCALAPPDATA%\zot

API-ключи из команд

Чтобы хранить API-ключ в менеджере паролей вместо auth.json, настройте api_key_command для провайдера:

{
  "anthropic": {
    "api_key_command": {
      "program": "op",
      "args": ["read", "op://Work/Anthropic/credential"],
      "timeout_ms": 120000
    }
  }
}

Для провайдера, добавленного через models.json, положите такой же объект учётных данных под additional_api_key_creds по его ID провайдера. program выполняется напрямую, без shell, поэтому каждый аргумент должен быть отдельной записью args. timeout_ms опционален, по умолчанию 120 секунд.

zot запускает команду только когда выбран этот провайдер, а не при проверке статуса логина или фоновом обновлении каталогов моделей. Успешный вывод кешируется в памяти до конца процесса zot и никогда не записывается на диск. Команда должна вывести одну непустую строку в stdout; zot удаляет завершающие символы CR/LF, ограничивает вывод 64 КиБ и не включает вывод команды в ошибки. Сохранение обычного ключа через /login заменяет конфигурацию команды, а /logout удаляет её.

Относитесь к auth.json как к исполняемой конфигурации: любой, кто может его изменить, может заставить zot запустить программу от вашего имени пользователя. zot не интерпретирует префиксы ! и не выполняет командные строки через shell.

Flow /login

Запустите zot и введите /login. Выберите один из двух методов:

  • API-ключ: небольшой локальный веб-сервер запускается на 127.0.0.1:<свободный-порт>, браузер открывает форму, вы выбираете провайдера из полного списка провайдеров с API-ключом, вставляете ключ, и zot сохраняет его в auth.json, если он принят. Провайдеры с лёгким эндпоинтом списка моделей проверяются перед сохранением; бэкенды, требующие дополнительных переменных проекта/аккаунта, сохраняются напрямую.
  • Подписка: используйте вашу подписку Claude Pro/Max, ChatGPT Plus/Pro, Kimi Code, SuperGrok/X Premium или GitHub Copilot. DeepSeek и Google Gemini не имеют пути логина по подписке. Для них используйте flow с API-ключом.
    • Anthropic и OpenAI закрепляют callback браузера на фиксированные специфичные для провайдера порты (localhost:53692 для Anthropic, localhost:1455 для OpenAI), потому что только на эти порты редиректят их auth-серверы.
    • Anthropic использует OAuth-flow Claude Code. Сообщения идут на api.anthropic.com с bearer-токеном и заголовками идентичности Claude Code.
    • OpenAI использует OAuth-flow Codex CLI. Сообщения идут на chatgpt.com/backend-api/codex/responses с chatgpt-account-id, извлечённым из возвращённого id_token.
    • Kimi использует device-code OAuth-flow Kimi Code. zot открывает URL верификации, опрашивает пока вы не подтвердите в браузере, затем отправляет сообщения на api.kimi.com/coding/v1 с заголовками идентичности Kimi Code.
    • xAI использует device-code OAuth-flow. zot открывает предзаполненный URL авторизации, опрашивает подтверждение и использует полученный токен с API xAI.
    • GitHub Copilot использует device-code flow логина GitHub. zot хранит GitHub access token и обменивает его на короткоживущие токены вывода Copilot по требованию.

Заметка о логине по подписке. Используемые OAuth client ID — те же, что опубликованы в Claude Code CLI Anthropic, Codex CLI OpenAI, Kimi Code CLI, device flow xAI и device-code flow GitHub Copilot. Их повторное использование сторонним инструментом может нарушать условия обслуживания и может быть отозвано в любой момент. Используйте на свой риск; flow с API-ключом — безопасный вариант по умолчанию.

Обновление токенов

OAuth access-токены короткоживущие (Anthropic ~8ч, OpenAI ~30д; Kimi, xAI и GitHub Copilot также используют refresh/exchange flow). zot обновляет или обменивает их автоматически:

  • При каждом поиске учётных данных zot проверяет сохранённый expiry и, если он истёк (с запасом 60с), обращается к эндпоинту oauth/token провайдера с сохранённым refresh_token, сохраняет новый access_token, refresh_token и expiry обратно в auth.json и передаёт свежий токен клиенту.
  • Мост Telegram дополнительно обновляет токен раз за ход, чтобы бот, работающий днями, продолжал функционировать без ручного вмешательства.
  • Если само обновление не удаётся (refresh_token был отозван, или аккаунт разлогинен везде), ошибка всплывает к вызывающему коду: TUI показывает её в статус-строке, бот отвечает ей в личных сообщениях. Запустите /login, чтобы получить свежую пару токенов.

Все данные хранятся в $ZOT_HOME:

$ZOT_HOME/
├── config.json         # последний используемый провайдер/модель/тема, сохраняется автоматически
├── auth.json           # api-ключи и oauth-токены (режим 0600)
├── sessions/           # jsonl-транскрипты, одна директория на cwd
├── models-cache.json   # кеш живого обнаружения /v1/models (ttl 6ч)
├── AGENTS.md           # опционально: глобальные инструкции, добавляемые к промпту
├── SYSTEM.md           # опционально: заменяет системный промпт по умолчанию
├── skills/             # опционально: пользовательские файлы SKILL.md
├── themes/             # опционально: пользовательские JSON-файлы тем
├── extensions/         # установленные расширения, одна директория на расширение
└── logs/               # файлы логов приложения

Положите SYSTEM.md в $ZOT_HOME, чтобы заменить встроенную идентичность и инструкции zot-docs для каждого запуска. --system-prompt всё равно побеждает для конкретного вызова. Передайте пустое значение (--system-prompt ""), чтобы намеренно опустить встроенную идентичность. Кастомные промпты всё равно получают добавленные инструкции и сгенерированный контекст, включая AGENTS.md, skills, инструкции auto-swarm при включении и футер даты/cwd. Удалите файл, чтобы вернуться к дефолту.

HTTP-прокси

Чтобы направить управляемые zot HTTP и HTTPS запросы через один прокси, добавьте http_proxy в $ZOT_HOME/config.json:

{
  "http_proxy": "http://127.0.0.1:7890"
}

Настройка применяется при старте к HTTP и HTTPS трафику. Существующие переменные окружения HTTP_PROXY, HTTPS_PROXY, http_proxy и https_proxy имеют приоритет для своего протокола. NO_PROXY и no_proxy продолжают управлять обходами. Перезапустите zot после изменения файла конфигурации. Если URL содержит учётные данные прокси, предпочтите защищённые переменные окружения, так как config.json не является хранилищем секретов.

Постоянные инструкции (AGENTS.md)

Используйте AGENTS.md, чтобы дать zot постоянные инструкции, которые накладываются поверх системного промпта по умолчанию, не заменяя его. Это самый дружелюбный способ формировать поведение (например, укрощение локальных моделей, сразу бросающихся редактировать код), потому что добавляет указания, а не перехватывает базовую идентичность, как это делает SYSTEM.md.

zot автоматически обнаруживает файлы AGENTS.md при старте и загружает их в этом порядке:

  1. $ZOT_HOME/AGENTS.md (глобальные, общесистемные инструкции, применяющиеся к каждому проекту).
  2. Каждый AGENTS.md от корня файловой системы до текущей рабочей директории. Более специфичные (глубокие) файлы могут переопределять более ранние. Это включает ~/AGENTS.md, когда рабочая директория внутри домашней.

Все обнаруженные файлы добавляются к промпту в этом порядке, так что глобальная база может уточняться по проекту. Чтобы вывести активного Zotfile-агента, пути загруженного контекста, расширения и пользовательски установленные skills над интерактивным транскриптом, включите показывать загруженные ресурсы при старте в /settings. Раздел агента появляется только для zot run, настройка по умолчанию выключена, встроенные skills опускаются, а отображаемые списки не отправляются модели и не сохраняются в транскрипте сессии.

Для общего, не привязанного к проекту набора инструкций поместите правила в $ZOT_HOME/AGENTS.md, например:

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

AGENTS.md в сравнении с другими механизмами:

Механизм Область Эффект
$ZOT_HOME/AGENTS.md глобально, каждый запуск добавляется к промпту по умолчанию
./AGENTS.md (и родительские директории) проект добавляется к промпту по умолчанию
$ZOT_HOME/SYSTEM.md глобально, каждый запуск заменяет встроенную идентичность и инструкции zot-docs
--append-system-prompt <text> одиночный запуск добавляет для одного вызова (повторяемо)
--system-prompt <text> одиночный запуск заменяет встроенную идентичность и инструкции zot-docs

Заметка: zot не читает файл инструкций CLAUDE.md. Единственное совместимое с Claude, что он подхватывает — skills под .claude/skills/. Если вы мигрируете с Claude Code, перенесите этот контент в AGENTS.md (глобальный или по-проектный), и zot его использует.

Changelog при обновлении

При первом запуске более нового бинарника zot TUI один раз показывает заметки о релизе GitHub в закрываемом оверлее. Нажмите любую клавишу, чтобы закрыть. Версия записывается в last_changelog_shown файла config.json, поэтому одни и те же заметки о релизе не появляются повторно. Свежие установки не видят changelog (обновления ещё не было). Загрузка выполняется по принципу best-effort: сбой сети или отсутствующая страница релиза молча пропускаются, со следующей попыткой при следующем запуске.

Использование

zot                              # интерактивный tui
zot "fix the failing test"       # tui, предзаполненный промпт
zot -p "list all go files"       # вывести финальный текст, выйти
echo "list all go files" | zot   # переданный stdin подразумевает print-режим
cat README.md | zot -p "summarize this text" # комбинирует stdin с промптом
zot -p --stats stats.json "task" # вывести финальный текст и записать статистику генерации
zot --json "refactor main.go"    # json-события с разделением по строкам, выйти
zot --continue                   # возобновить последнюю сессию для этого cwd
zot --resume                     # выбрать сессию для возобновления
zot --list-models                # показать поддерживаемые модели
zot --help

Статистика print-режима содержит provider, model, prompt_tokens, reasoning_tokens, generated_output_tokens и elapsed_ms. Счётчики покрывают все ходы модели, вызванные промптом, включая циклы инструментов. Токены промпта включают чтения и записи кеша. reasoning_tokens равно null, когда провайдер не сообщает отдельный счётчик; в этом случае generated_output_tokens — общий счётчик вывода провайдера и может включать рассуждение. Прошедшее время покрывает запуск агента, но не старт и разрешение учётных данных. Файл записывается только после успешного запуска.

Флаги

Флаг Описание
--provider <id> Выбрать провайдера (например, anthropic, openai, openai-codex, kimi, google, github-copilot, groq, openrouter, amazon-bedrock, ollama; см. Провайдеры).
--model <id> Выбрать модель (см. --list-models).
--api-key <key> Переопределить API-ключ.
--base-url <url> Переопределить базовый URL провайдера (тесты, self-hosted).
--insecure Пропустить проверку TLS-сертификата для явного эндпоинта --base-url или baseUrl, определённого для пользовательской модели в models.json (самоподписанные локальные/внутренние серверы вывода). Встроенные провайдеры, аутентификация и обнаружение моделей сохраняют обычную проверку TLS.
--system-prompt <text> Заменить системный промпт по умолчанию для этого запуска (также переопределяет $ZOT_HOME/SYSTEM.md; передайте "" для отсутствия встроенной идентичности).
--append-system-prompt <text> Добавить текст к системному промпту (повторяемо).
--reasoning off\|minimum\|low\|medium\|high\|xhigh\|max Задать уровень рассуждения на поддерживаемых моделях (по умолчанию: off). max — отдельный opt-in уровень выше xhigh.
--stats <path> С -p/--print записать статистику генерации как JSON.
-c, --continue Возобновить последнюю сессию для этого cwd.
-r, --resume Выбрать сессию для возобновления.
--session <path> Возобновить конкретный файл сессии.
--no-session Не читать и не писать файлы сессий.
--cwd <path> Использовать <path> как рабочую директорию.
--no-tools Отключить все инструменты.
--tools <csv> Включить только перечисленные инструменты.
--max-steps <n> Ограничить итерации цикла агента (по умолчанию 50).
-e, --ext <path> Загрузить расширение из <path> для этого запуска (повторяемо; побеждает установленные расширения с тем же именем).
--no-ext Пропустить обнаружение расширений для этого запуска. --ext всё равно работает поверх, так что --no-ext --ext ./x запускает только x.
--no-skill Отключить все skills, включая встроенные. Инструмент skill не регистрируется, и системный промпт не содержит манифеста skills.
--no-context-files, -nc Отключить обнаружение и загрузку глобальных и проектных файлов AGENTS.md.
--no-yolo Подтверждать каждый вызов инструмента перед выполнением (только интерактивный TUI). Диалог показывает имя инструмента и однострочный превью его аргументов, а вызовы редактирования показывают предлагаемый diff в панели инструмента, с четырьмя вариантами: да, да-всегда-этот-инструмент-эту-сессию, да-всегда-эту-сессию, нет. Нажмите / пока диалог в фокусе, чтобы сначала запустить slash-команду; закрытие её ввода или дочернего диалога возвращает к ожидающему подтверждению. Игнорируется с предупреждением в stderr в режимах print / json / rpc, где инструменты всё равно выполняются свободно, чтобы скрипты и автоматизация продолжали работать.

Инструменты

  • read: чтение текстовых файлов или инлайн-изображений (PNG, JPEG, GIF, WebP).
  • write: создание или перезапись файлов, создание родительских директорий по необходимости.
  • edit: одна или несколько замен точного совпадения в существующем файле.
  • bash: запуск команды в cwd сессии со слитыми stdout/stderr и таймаутом. На Unix zot использует /bin/bash -c, если доступен, затем bash -c из PATH, и переходит на POSIX /bin/sh -c, если Bash недоступен. На Windows использует cmd /C. macOS по умолчанию поставляется с Bash 3.2, так что более новые возможности Bash могут быть недоступны.

Когда sandbox включён (см. /jail), все четыре инструмента отказываются работать с путями вне cwd сессии.

Режимы

  • Интерактивный (по умолчанию): чат-TUI с потоковым выводом, спиннером, счётчиком стоимости, slash-командами.
  • Print: zot -p "prompt" запускает агента до завершения и выводит только финальный текст ассистента в stdout.
  • Stream: zot --stream "prompt" запускает без TUI и выводит текст ассистента в stdout по мере поступления. Активность инструментов идёт в stderr.
  • Переданный ввод: когда режим не указан, переданный stdin выбирает print-режим. Режимы print, stream и JSON добавляют переданный stdin к позиционному промпту через перенос строки. Например, echo "list all go files" | zot или cat README.md | zot -p "summarize this text".
  • JSON: zot --json "prompt" выводит по одному JSON-объекту на событие агента в stdout, разделённому переносами строк. Схема документирована в docs/rpc.md.
  • RPC: zot rpc работает как долгоживущий дочерний процесс; команды входят на stdin, события и ответы выходят на stdout, оба как NDJSON. Спроектирован для встраивания zot в сторонние приложения на любом языке. См. docs/rpc.md для схемы протокола и examples/rpc/{python,node,shell,go} для рабочих клиентов.

Zotfile-агенты

Zotfile упаковывает инструкции агента, skills, требования и принудительные права инструментов как переносимого агента, которым можно поделиться. Запустите его из локальной директории, упакованного артефакта .zot, короткого имени или напрямую из публичного репозитория GitHub:

zot run ./my-agent
zot run ./my-agent.zot
zot run frkr/zot-archify
zot run acme/agents/code-reviewer --cwd /path/to/project

Однокомпонентные имена разрешаются только в соответствующую локальную директорию или архив .zot. Любой может опубликовать агента как публичный репозиторий GitHub и запустить его как owner/repository, или опубликовать коллекцию и запустить директорию агента как owner/repository/agent. У zot нет встроенного владельца, официальной коллекции, настроенного реестра или белого списка. Для источников GitHub zot скачивает архив репозитория во временную директорию, валидирует и запускает выбранного агента, затем удаляет скачанный источник при выходе из команды. Данные агента, квитанции согласия и сессии всё равно сохраняются в $ZOT_HOME. См. docs/zotfiles.md для создания, прав доступа, упаковки и текущих ограничений.

Встраивание

Два способа управлять zot из другой программы:

  • Go в процессе: импортируйте github.com/patriceckhart/zot/packages/agent/sdk. Один Runtime на проект; Prompt(ctx, text, images) возвращает канал Event. Небольшой пример в examples/sdk/.
  • Любой язык, вне процесса: запустите zot rpc как подпроцесс и обменивайтесь NDJSON через его stdin/stdout. Формат протокола и схема событий в docs/rpc.md. Референсные клиенты в examples/rpc/.

Оба интерфейса используют одну схему событий, так что транскрипты, записанные одним, можно воспроизвести через другой.

Slash-команды

Имена slash-команд регистронезависимы в TUI и мессенджинг-бэкендах; аргументы сохраняют исходный регистр. Введите / в TUI, чтобы открыть popup автодополнения. Доступные команды:

Команда Описание
/help Показать привязки клавиш и команды.
/login Войти через API-ключ или подписку (открывает диалог).
/logout [provider] Очистить учётные данные для любого залогиненного провайдера, или для всех при отсутствии аргумента. /logout openai-codex очищает аутентификацию подписки ChatGPT/Codex, сохраняя публичный API-ключ OpenAI; /logout kimi также отключает fallback на официальный токен Kimi Code CLI, пока вы не залогинитесь в Kimi через zot снова.
/model Выбрать модель из списка (или /model <id> для прямой установки).
/reasoning Задать уровень рассуждения для последующих вызовов модели.
/llama Подключиться к настроенному роутеру llama.cpp, загрузить, выгрузить или удалить кешированные модели, а также искать/скачивать GGUF-модели с Hugging Face с живым прогрессом. Показывается после настройки логина llama.cpp.
/sessions Возобновить предыдущую сессию для этой директории.
/session Пять операций над текущей сессией: инспекция её timeline, export в переносимый файл .zotsession, import обратно, fork от прошлого сообщения пользователя или просмотр её tree ветвей. Открывает выбор без аргумента; прямые формы включают /session timeline, /session export [path], /session import <path>, /session fork и /session tree. Место экспорта по умолчанию — ~/Downloads.
/jump Прокрутить чат к предыдущему ходу (или /jump <text> для фильтрации).
/btw Побочный чат с полным контекстом, не добавляющийся в основной поток.
/swarm Запуск, мониторинг и общение с фоновыми субагентами. Каждый работает параллельно с основной сессией и разделяет её рабочую директорию.
/skills Список обнаруженных skills (файлов SKILL.md) и превью их тела.
/compact Сжать транскрипт в одно сообщение, чтобы освободить контекст.
/study Запустить заготовленный промпт "Прочитать и понять всё в текущей директории", чтобы у агента был полный контекст проекта перед адресными вопросами. Передайте путь — набранный, перетащенный или выбранный через @ — чтобы нацелиться на конкретный файл или директорию: /study [dir:packages/], /study cmd/zot/main.go.
/jail Ограничить инструменты текущей директорией.
/unjail Снова разрешить инструментам обращаться к путям вне директории.
/reload-ext Горячая перезагрузка всех расширений (перечитать манифесты, перезапустить подпроцессы, пересобрать реестр инструментов).
/telegram Подключить, отключить или показать статус моста Telegram (принимает connect / disconnect / status опциональным аргументом; открывает выбор без него). При подключении личные сообщения от связанного пользователя становятся промптами в работающей сессии, а ответы ассистента зеркалируются обратно в Telegram. Псевдоним: /tg.
/settings Изменить постоянные настройки, включая инлайн-изображения, auto-swarm и порог auto-compact. Сохраняется в $ZOT_HOME/config.json; вступает в силу немедленно.
/clear Очистить транскрипт чата.
/exit Выйти из zot.

Команды, зарегистрированные расширениями, появляются под разделителем внизу popup, отсортированные по имени.

Экранирование shell (!command)

Введите !, за которым следует команда, чтобы выполнить её напрямую, минуя модель. Всё после ! передаётся в тот же shell, что использует инструмент bash (/bin/bash -c, если доступен на Unix, затем bash -c из PATH, с POSIX /bin/sh -c как fallback; cmd /C на Windows), выполняется в рабочей директории сессии и учитывает sandbox /jail. Команда, слитый вывод и код завершения добавляются в транскрипт как контекст пользователя, так что модель может использовать их на следующем ходу. Выполнение команды само по себе не запускает ход модели. Выполняющийся !command разделяет состояние занятости с агентом: esc отменяет его, и нельзя запустить его, пока идёт ход (или другое экранирование shell).

/sessions

Показывает предыдущие сессии для текущей рабочей директории, сначала новейшие, с меткой времени, моделью, числом сообщений, стоимостью и первым промптом пользователя. Выберите up/down, enter для возобновления, esc для отмены. zot заменяет текущий файл сессии выбранным и воспроизводит полный транскрипт (включая вызовы инструментов) в агенте. Сессии помнят модель, на которой закончились, так что возобновление продолжается на той же модели, даже если ваш глобальный дефолт изменился.

/session

Пять операций над текущей сессией. Один /session открывает выбор; каждая также запускается напрямую.

  • /session timeline. Заменяет область чата read-only таймлайном текущего системного промпта, сообщений пользователя и ассистента, и вызовов инструментов. Заголовок показывает использование контекста, о котором сообщил провайдер, и оценочное разделение между системным промптом, определениями инструментов и сообщениями. Разделение использует простую оценку по байтам, так что оно направляющее, а не точное по токенизатору. Используйте up / down или pgup / pgdn для выбора события, tab / shift+tab для инспекции его сводки, payload, результата, схемы и тайминга, полученного из транскрипта, и / для поиска. ctrl+e записывает JSON-экспорт в ~/Downloads (с fallback на домашнюю директорию) с правами 0600 на платформах, поддерживающих Unix-режимы файлов. Изображения представлены типом MIME и размером в байтах вместо встраивания данных. Нажмите esc, чтобы вернуться в чат.
  • /session export [path]. Записывает работающий транскрипт в переносимый файл .zotsession. Место по умолчанию — ~/Downloads/<timestamp>-<session-id>-<prompt-slug>.zotsession. Передайте путь, чтобы переопределить; директория тоже подходит (внутри строится датированное имя), голое имя получает добавленное .zotsession. Cwd метаданных удаляется на выходе, чтобы получатель не видел вашу файловую структуру.

    Что включено. Только основной поток чата работающей сессии — сообщения, вызовы инструментов, результаты инструментов, компакции и использование. Субагенты /swarm НЕ включаются. Их транскрипты, unix-socket входящие и файлы сессий по агентам все локальны для машины; .zotsession — это просто транскрипт чата, у него нет способа воскресить unix-socket на другой машине. Если хотите разговор, скопируйте его из панели вручную. - /session import <path>. Копирует файл .zotsession в $ZOT_HOME/sessions/<cwd-hash>/ со свежим id и текущим cwd, затем переключает работающего агента на него. Импортированные сессии полноценны: они появляются в /sessions, /jump и дереве. Пути drag-drop в редакторе принимаются (zot автоматически убирает окружающие кавычки). - /session fork. Открывает выбор хода (та же форма, что /jump). Выберите любое прошлое сообщение пользователя; zot копирует каждое сообщение вплоть до и включая этот ход в новую сессию, записывает parent + fork_point в новые метаданные и переключается на ветку. Родительская сессия остаётся на диске. Используйте, чтобы попробовать другой вопрос, не загрязняя оригинальный транскрипт, или чтобы откатиться после того, как агент пошёл не туда. - /session tree. Показывает каждую сессию в текущем cwd, организованную по отношениям родитель/потомок, в глубину с отступом по уровню. Текущая сессия помечена [current]. Выберите любую запись, чтобы переключиться на неё. Сессии без родителя — корни; ветки, созданные через /session fork, вкладываются под сессию, от которой ответвились. Осиротевшие потомки (чей файл родителя удалён) всё равно показываются как корни, чтобы оставаться обнаруживаемыми.

/jump

Открывает выбор хода для текущей сессии, по строке на промпт пользователя, каждая показывает номер хода, сколько инструментов вызвал этот ход, и первую строку промпта. up/down для выбора, enter для перехода, esc для отмены. Любой печатаемый символ, пока выбор открыт, расширяет фильтр; backspace сужает его обратно. /jump <text> предзаполняет фильтр; если совпадает ровно один ход, zot переходит к нему сразу, не показывая выбор.

Переход неразрушителен. Транскрипт не тронут, вьюпорт просто прокручивается так, чтобы выбранный ход был наверху. Приглушённая строка наверху чата гласит viewing turn N of M, pgdn to catch up. Прокрутите обратно вниз клавишей pgdn (или продолжайте прокрутку стрелками), и индикатор исчезает.

/btw

Открывает оверлей побочного чата с полной основной сессией как замороженным контекстом, чтобы вы могли задавать быстрые уточняющие вопросы ("does asyncio.gather() catch exceptions?", "btw the bundle budget is 10MB", "what's the default fetch timeout?") без раздувания основного потока.

Каждый вопрос запускает изолированный ход агента по system + основной транскрипт + история побочного чата до сих пор. Побочный чат имеет те же инструменты и защиты, что и основной чат, включая подтверждение по инструментам при активном --no-yolo. Ответы, вызовы инструментов и результаты инструментов остаются в оверлее. Когда вы нажимаете esc, чтобы закрыть, ничего не добавляется в основную сессию, и последующие ходы основного потока не перечитывают обмены побочного чата, сохраняя работающее окно контекста компактным.

/btw                              # открыть оверлей, вводить вопросы интерактивно
/btw does PUT replace the whole resource?

Внутри оверлея: enter отправляет, esc отменяет выполняющийся вызов (или закрывает оверлей, если простаивает), ctrl+c закрывает немедленно. Обмены побочного чата никогда не касаются транскрипта и не сохраняются в файл сессии.

/swarm

Фоновые субагенты, работающие параллельно с основной сессией. Каждый — отдельный подпроцесс zot со своим циклом модели, своим постоянным файлом сессии и своим чатом на панели — но все они работают в той же рабочей директории, что и хост, так что видят и редактируют те же файлы, что и вы. Запустите один для побочной задачи ("draft the migration", "investigate this stack trace", "write the test harness for module X"), продолжайте работу в основном потоке, проверяйте его когда захотите.

Агенты редактируют те же файлы, что и вы. Они используют те же инструменты read / write / edit / bash, что и основной агент, против рабочей директории хоста. Нет отдельного worktree или ветки на агента. Если нужны параллельные правки на изолированных checkout'ах, настройте это сами через git worktree вне zot.

/swarm                            # открыть панель
/swarm new <task>                 # запустить агента
/swarm new --model gpt-5 <task>    # закрепить нового агента за конкретной моделью
/swarm logs <id>                  # перейти прямо в транскрипт одного агента
/swarm send <id> <text>           # отправить продолжение, не открывая панель
/swarm resume                     # выбрать остановленного агента, чтобы вернуть
/swarm resume <id>                # вернуть конкретного агента
/swarm kill <id>                  # остановить работающего агента (его состояние остаётся)
/swarm remove <id>                # удалить сессию и состояние агента
/swarm list                       # псевдоним для открытия панели

Панель (/swarm без аргумента) — список всех агентов текущей сессии, со статусом, возрастом и текущей активностью. Клавиши:

Клавиша Действие
↑ / ↓ Перемещение курсора между строками.
enter Открыть вид транскрипта выделенного агента.
n Запустить нового агента (открывает инлайн-редактор задачи; наследует текущую модель хоста).
p Одноразовый редактор промпта для выбранной строки (без входа в транскрипт).
R Возобновить остановленного агента на месте.
k Убить выбранного работающего агента. Его сессия и состояние остаются, чтобы возобновить позже.
r Полностью удалить выбранного агента (сессия + метаданные исчезают).
esc Закрыть панель.

Внутри транскрипта агента — оверлей чата с всегда включённым инлайн-редактором внизу. Разговор течёт над ним; печатайте и enter, чтобы отправить продолжение. Вид автоматически следует за потоковым выводом и показывает инлайн-спиннер с текущей активностью агента (thinking, tool: edit_file и т.д.), пока тот занят. esc возвращает на панель.

Переключение модели запуска изнутри редактора — при составлении задачи в промпте n введите /model на отдельной строке и enter. Появляется стандартный выбор /model; выберите модель, выбор закрывается, и редактор снова открывается с вашей введённой задачей нетронутой и новой моделью, закреплённой для запуска.

Область сессии — каждый агент помечен хост-сессией, которая его запустила, и появляется только на панели этой сессии. Переключайте сессии через /sessions, и панель соответственно сужается. Агенты из других сессий продолжают работать в фоне и появляются снова при переключении обратно.

Персистентность через перезапуски zot — каждый запуск записывает meta.json рядом с логом событий и файлом сессии в $ZOT_HOME/swarm/agents/<id>/. При следующем запуске zot они появляются на панели как отсоединённые; нажмите R (или /swarm resume <id>), чтобы вернуть одного. Возобновлённые агенты переподключаются к той же сессии и сокету входящих, так что разговор продолжается с того места, где остановился.

Где хранится состояние — всё по агенту (файл сессии, лог событий, сокет входящих, метаданные) хранится в $ZOT_HOME/swarm/agents/<id>/. Фактические правки кода агента попадают прямо в ваш репозиторий; отслеживайте их обычными git status / git diff.

/session export НЕ включает субагентов. .zotsession — это просто основной транскрипт чата; состояние по агентам (файл сессии, unix-socket входящих) локально для машины и не проходит через JSONL-файл. Чтобы поделиться тем, что сказал агент, скопируйте это из вида транскрипта вручную.

Auto-swarm. С включённым в /settings -> auto-swarm основной агент получает встроенный инструмент swarm_spawn и подсказку в системном промпте использовать его. Тогда он может самостоятельно форкать субагентов, когда запрос естественно разделяется на независимую параллельную работу ("implement A and B", "investigate three files"). Каждый запуск сразу возвращает id субагента, и основной ход продолжается. Когда каждый субагент, запущенный в этой партии, завершает свою начальную задачу, zot вставляет обратно в основной чат одно сообщение [auto-swarm update], резюмирующее статус, задачу и полный финальный ответ каждого агента. Если агент не выдал ответа ассистента, zot вместо этого включает усечённый хвост транскрипта для диагностики. Затем основной агент пишет краткое резюме-продолжение, ссылаясь на агентов по id. По умолчанию выключено; переключается из /settings.

/settings

Открывает диалог со всеми постоянными настройками. up/down для навигации, enter или space для изменения выбранной строки, esc для закрытия (строки, открывающие подвид, например ярлыки моделей, используют esc, чтобы сначала вернуться на уровень выше). Изменения записываются в $ZOT_HOME/config.json и вступают в силу на следующем ходу (перезапуск не нужен). Текущие настройки:

  • рендерить изображения, если поддерживается — рисовать скриншоты / изображения, возвращённые read, инлайн с использованием протокола изображений терминала, или fallback на текстовый плейсхолдер. Автоопределяется по TERM_PROGRAM; переключатель переопределяет определение. Строка серая и принудительно выключена на терминалах, не поддерживающих ни один протокол изображений.
  • auto-swarm — позволить основному агенту запускать фоновых субагентов параллельно через встроенный инструмент swarm_spawn. По умолчанию выключено. При включении инструмент регистрируется у работающего агента, системный промпт получает короткое дополнение, говорящее модели проактивно делегировать независимые подзадачи, и zot следит за каждым субагентом, запущенным основным агентом. Как только последний субагент в партии завершает начальную задачу, сообщение [auto-swarm update] вставляется обратно в чат со статусом/задачей/хвостом транскрипта каждого агента, чтобы основной агент мог резюмировать коллективный результат. Выключение в середине сессии убирает инструмент из живого агента и удаляет дополнение на следующем ходу — модель прекращает пытаться делегировать. См. /swarm для панели, позволяющей мониторить, писать, убивать или удалять запущенных агентов.
  • порог auto-compact — выберите off, 70%, 80%, 85% (по умолчанию) или 90% от заявленного окна контекста модели. Выбранный процент управляет автоматической компакцией до и после интерактивных ходов и сохраняется как auto_compact_threshold. off отключает триггеры по проценту, но сохраняет ручной /compact и автоматическое восстановление после ответов о превышении окна контекста и слишком большом payload.
  • jail для новых сессий по умолчанию: начинать каждого нового агента с инструментами, ограниченными его рабочей директорией. По умолчанию выключено. Настройка применяется к интерактивным запускам, print, JSON, RPC и фоновым агентам, сохраняется как jail_by_default, и немедленно обновляет текущую интерактивную сессию. /jail и /unjail остаются переопределениями в рамках сессии и не меняют этот дефолт.
  • компактный рендеринг транскрипта: уменьшить визуальные украшения в транскрипте чата. Вызовы инструментов рендерятся как тихий заголовок плюс вывод с отступом вместо панели с рамкой, а отправленные сообщения рендерятся без padded фоновых пузырей. По умолчанию выключено. Изменения применяются немедленно и сохраняются в config.json как compact_mode.
  • показывать загруженные ресурсы при старте: перечислить активного Zotfile-агента (для zot run), загруженные пути AGENTS.md, расширения и пользовательски установленные skills в компактных секциях над транскриптом. Встроенные skills опускаются. По умолчанию выключено. Изменения применяются немедленно и сохраняются в config.json как show_instructions_at_startup.
  • настройки TUI: открывает подвид для расположения ввода и статуса. Стиль ввода может быть plain (строка промпта по умолчанию), lines (линии-разделители над и под вводом) или block (блок ввода в стиле пузыря пользователя). Позиция статуса размещает информацию о модели, использовании и рабочей директории над или под вводом. Позиция рабочего спиннера размещает спиннер занятости над или под вводом. Изменения применяются немедленно и сохраняются в config.json как tui_input_style, tui_status_position и tui_working_position (above_input или below_input для полей позиции).
  • уровень рассуждения: выберите рассуждение для поддерживаемых моделей: off, minimum, low, medium, high, xhigh или max. Уровень max — opt-in и отправляется нативно на GPT-5.6 и модели Claude с адаптивным мышлением; неподдерживающие бэкенды ограничивают его своим максимально принимаемым усилием. Изменение сохраняется в config.json и применяется к следующему вызову модели. Используйте /reasoning, чтобы открыть этот селектор напрямую. Селектор показывает только различающиеся уровни, поддерживаемые активной моделью; модели без поддержки рассуждения предлагают только off.
  • цветовая тема — выберите встроенную auto/dark/light тему или любую JSON-тему, обнаруженную под $ZOT_HOME/themes или загруженным расширением. Файлы тем могут переопределять любое подмножество цветов UI, цветов синтаксиса и кадров/сообщений спиннера. Изменения применяются немедленно; если выбранный файл темы удалён, zot сбрасывается на auto. См. docs/themes.md.
  • ярлыки моделей — открывает подвид с девятью слотами (model 1 ... model 9). enter на слоте открывает тот же селектор /model и привязывает выбранного провайдера/модель к этому слоту; backspace очищает слот. После назначения нажмите Ctrl+1 ... Ctrl+9 из редактора, чтобы мгновенно переключить активную модель (та же кросс-провайдерная замена, что выполняет /model, транскрипт и стоимость переносятся). Назначение ярлыка не меняет текущую модель. Ярлыки пропускаются, пока идёт ход.

/skills

Открывает выбор со списком каждого обнаруженного файла SKILL.md, встроенные скрыты. Каждая строка показывает имя skill, источник и описание. enter открывает тело инлайн (прокручиваемо up/down/pgup/pgdn); esc возвращает назад. Перезапускает обнаружение при каждом открытии, так что изменения SKILL.md в течение сессии отражаются немедленно.

/compact

Отправляет текущий транскрипт через модель со структурированным промптом суммаризации. Возвращённое резюме заменяет транскрипт одним синтетическим сообщением пользователя, с последними несколькими обменами, сохранёнными дословно для непрерывности. Счётчик контекста в статус-строке сбрасывается. Используйте, когда счётчик контекста подбирается к ~80%.

zot также авто-сжимает в фоне: после любого хода, достигающего настроенного порога контекста, агент самостоятельно запускает проход сжатия. Выберите off, 70%, 80%, 85% (по умолчанию) или 90% в /settings → порог auto-compact. Вы увидите condensing history, esc to cancel над статус-строкой и тег (auto) рядом с процентом контекста; esc прерывает это, не трогая транскрипт. Выключение процентного триггера не отключает автоматическую компакцию и повтор после ответа о превышении окна контекста или слишком большом payload.

/jail

Принудительно применяет sandbox, закреплённый на cwd, показанном в статус-строке. read, write и edit разрешают свой целевой путь (включая через симлинки) и отказываются от всего вне sandbox. bash отказывается от очевидных паттернов выхода (sudo, rm -rf /, ведущий cd /, cd .., cd ~, chmod -R, dd of=/ и подобных) и отклоняет аргументы shell или редиректы, указывающие вне sandbox. Статус-строка показывает jailed, ~/your/cwd, пока активно. Включите jail для новых сессий по умолчанию в /settings, чтобы сохранить это поведение между запусками; /unjail тогда разблокирует только текущую сессию.

Это защита от случайностей, а не жёсткая граница безопасности. Если нужна настоящая изоляция, запускайте zot под docker или в подходящем sandbox.

Сессии

Каждый интерактивный запуск или print/json (если не --no-session) записывает JSONL-транскрипт в $ZOT_HOME/sessions/<cwd-hash>/. Возобновите любую из них --continue, --resume, --session <path> или интерактивно через /sessions внутри TUI. Пустые сессии (пользователь вышел без промпта) удаляются при закрытии, чтобы список оставался опрятным.

Используйте zot sessions prune вне TUI, чтобы найти сессии, чьи записанные рабочие директории больше не существуют. Команда группирует сессии по директории, показывает число сохранённых сессий, позволяет выбрать группы и требует подтверждения перед окончательным удалением файлов. Она сохраняет сессии, когда проверка директории завершается ошибкой, отличной от "не найдено", и перепроверяет каждую выбранную директорию непосредственно перед удалением. Удалённая директория и путь, скрытый некоторыми немонтированными файловыми системами, неразличимы, так что просмотрите выбор и убедитесь, что удалённые файловые системы смонтированы, прежде чем удалять группы с отсутствующей директорией.

Используйте --older-than, чтобы вместо этого удалять сессии по последней активности, включая сессии для директорий, которые всё ещё существуют. Поддерживаемые единицы возраста — m (минуты), h (часы), d (24-часовые дни), w (7-дневные недели), mo (календарные месяцы) и y (календарные годы). Добавьте --cwd PATH, чтобы ограничить удаление по возрасту одной рабочей директорией. Файл сессии проверяется снова непосредственно перед удалением и сохраняется, если недавно стал активным.

zot sessions prune --dry-run                         # список групп с отсутствующей директорией
zot sessions prune --older-than 4h --dry-run         # просмотр сессий, неактивных четыре часа
zot sessions prune --older-than 1mo --cwd ~/project  # выбор старых сессий для одной директории
zot sessions prune --older-than 1y --all              # выбрать каждое совпадение, затем подтвердить
zot sessions prune --older-than 30d --all --yes       # удалить каждое совпадение без запроса

--all выбирает каждое совпадение и всё равно запрашивает подтверждение. Добавление --yes делает удаление неинтерактивным и требует --all. Некорректные, нечитаемые, симлинковые и не-абсолютные записи сессий отображаются и сохраняются при удалении по отсутствующей директории. Сканирование включает обычные сессии и сессии именованных агентов под $ZOT_HOME/sessions/; явные файлы сессий, хранящиеся в другом месте, и состояние swarm-агентов не включены.

Провайдеры

Встроенный каталог провайдеров zot включает:

  • С поддержкой подписки: Anthropic Claude Pro/Max (anthropic), OpenAI Codex / ChatGPT Plus/Pro (openai-codex), Kimi Code (kimi), SuperGrok/X Premium (xai), GitHub Copilot (github-copilot).
  • Прямые API-провайдеры: Anthropic, OpenAI Chat Completions, OpenAI Responses, DeepSeek, Google Gemini, Kimi/Moonshot, Moonshot CN, Groq, Cerebras, xAI, Together AI, Hugging Face Router, OpenRouter, Mistral, Z.AI, регионы Xiaomi/MiMo с токен-планами, MiniMax global/CN, Fireworks, Vercel AI Gateway, OpenCode/OpenCode Go.
  • Облачные/платформенные провайдеры: Amazon Bedrock, Google Vertex AI, Azure OpenAI, Cloudflare Workers AI, Cloudflare AI Gateway.
  • Локальные/совместимые: Ollama, режим роутера llama.cpp и OpenAI-совместимые локальные эндпоинты через --base-url.

Используйте /login, чтобы сохранить API-ключи или учётные данные подписки. /model показывает только модели от провайдеров, доступных сейчас из переменных окружения, auth.json, fallback Kimi CLI, локального Ollama или настроенного роутера llama.cpp.

Модели

--list-models или селектор /model показывают полный каталог по всем встроенным провайдерам. Три источника:

  • Каталог: модели, встроенные в zot, покрывающие Claude, GPT/Codex, Gemini/Gemma, Kimi/Moonshot, DeepSeek, размещённые на Groq Llama/Gemma/Compound, модели, маршрутизированные через OpenRouter, id моделей Bedrock, id моделей Vertex, деплойменты Azure OpenAI, модели Copilot и другие специфичные для провайдера записи каталога.
  • Живые: ID, обнаруженные через GET /v1/models с использованием вашего сохранённого API-ключа (кешируются на 6ч в $ZOT_HOME/models-cache.json, обновляются в фоне при старте).
  • Спекулятивные: ID, появляющиеся в апстрим-генераторе, но ещё не живые в публичном API. Сегодня они выдадут 404 и заработают, как только провайдер их выпустит.

Счётчик контекста в статус-строке использует заявленное окно контекста модели, чтобы показать, сколько от него потребил ваш последний ход.

Fallback модели (rescue)

Когда ход не удаётся из-за восстанавливаемой ошибки провайдера — истёкший токен (401), доступ запрещён (403), rate limit (429), недоступность провайдера (502/503/504) или временный сбой сети — zot открывает селектор rescue поверх чата вместо простой отрисовки красного баннера.

Селектор — тот же вертикальный список / fuzzy-фильтр UI, что и /model, но показывает только модели от провайдеров, в которые вы сейчас залогинены (env-переменные, auth.json, fallback Kimi CLI, ollama). Неудавшаяся модель исключена. Нажмите ↑/↓ для выбора, enter для повтора того же промпта на новой модели, esc для отмены.

Перед фактическим срабатыванием запроса провайдера клиенты OpenAI / Anthropic / Kimi / DeepSeek / Google / OpenAI-Codex также выполняют до двух тихих повторов с короткой задержкой (250мс, 750мс) на 502/503/504 и ошибках сброса соединения / EOF-до-заголовков. Большинство сбоев edge-прокси исчезают, так что вы никогда не увидите селектор rescue.

Повтор rescue всегда отбрасывает --api-key и --base-url времени запуска перед пересборкой агента. Эти переопределения обычно и есть причина срабатывания rescue (плохой ключ, опечатанный base URL, корпоративный шлюз, действительный только для изначально выбранного провайдера), так что повтор заново разрешает учётные данные из env-переменных / auth.json / дефолтов провайдера. Используйте /model, если хотите, чтобы переопределения сохранились.

Конфигурация не требуется — список кандидатов строится динамически из ваших активных учётных данных. Ошибки bad-request / превышения длины контекста / сериализации НЕ направляются в селектор rescue, потому что смена модели их не исправит; они всё равно проявляются как обычная ошибка.

Кастомные модели

Поместите models.json в $ZOT_HOME ($XDG_STATE_HOME/zot/, если задано, иначе дефолт платформы выше), чтобы добавить модели, отсутствующие во встроенном каталоге, или переопределить существующие записи:

{
  "providers": {
    "openai": {
      "models": [
        {
          "id": "gpt-5.5",
          "name": "GPT-5.5",
          "reasoning": true,
          "reasoningLevelMap": {"minimum": "low", "max": ""},
          "contextWindow": 400000,
          "maxTokens": 128000
        }
      ]
    }
  }
}

Поддерживаемые поля на модель: id (обязательно), name, reasoning, reasoningLevelMap, contextWindow, maxTokens, baseUrl, priceInput, priceOutput, priceCacheRead, priceCacheWrite.

reasoningLevelMap опционально. Применяются дефолты протокола, когда он опущен. Добавляйте только специфичные для модели исключения, используя minimum, low, medium, high, xhigh или max в качестве ключей. Отобразите ключ на другой уровень, когда оба ввода эквивалентны, используйте identity-отображение вроде "max": "max", чтобы включить уровень сверх дефолта протокола, или отобразите на пустую строку или off, чтобы удалить его. То же эффективное отображение управляет /reasoning и запросами провайдера.

Ключи провайдеров нормализуются: openai-codex и openai-responses отображаются на openai, anthropic-messages — на anthropic, moonshot, moonshot-ai и kimi-code — на kimi, а deepseek-chat и deepseek-ai — на deepseek. Встроенные id провайдеров, такие как groq, openrouter, github-copilot, amazon-bedrock, google-vertex, azure-openai-responses, fireworks, vercel-ai-gateway, mistral и xai, тоже можно использовать напрямую.

Пользовательские модели показывают source: user в --list-models и имеют приоритет как над встроенным каталогом, так и над живо-обнаруженными моделями. Добавление models.json не скрывает встроенный каталог; записи сливаются поверх него. Отсутствующие или некорректные файлы молча игнорируются.

Кастомные провайдеры

Ключ провайдера верхнего уровня, не являющийся встроенным id, определяет кастомного провайдера. Дайте ему baseUrl уровня провайдера и формат протокола api (openai для OpenAI-совместимого Chat Completions, дефолт, openai-responses для OpenAI Responses API, или anthropic для Anthropic Messages API). baseUrl уровня модели переопределяет уровень провайдера для этой модели; неизвестное значение api откатывается на openai с предупреждением.

{
  "providers": {
    "my-company": {
      "baseUrl": "https://llm.mycompany.com/v1",
      "api": "openai",
      "models": [
        { "id": "company-llm-v2", "name": "Company LLM v2" }
      ]
    }
  }
}

Кастомные провайдеры полноценны: они появляются в --list-models, /model и /login. models.json никогда не хранит секреты. Передайте ключ через /login, --api-key или производную переменную окружения в верхнем snake_case (так my-company читает MY_COMPANY_API_KEY). Поскольку многие self-hosted шлюзы не предоставляют эндпоинт списка моделей, ключи кастомных провайдеров принимаются и сохраняются без проверочного зонда; неверный ключ проявится при первом вызове модели.

Чтобы получить ключ этого кастомного провайдера из менеджера паролей, добавьте соответствующую запись в $ZOT_HOME/auth.json:

{
  "additional_api_key_creds": {
    "my-company": {
      "api_key_command": {
        "program": "op",
        "args": ["read", "op://Work/OpenAI/credential"],
        "timeout_ms": 120000
      }
    }
  }
}

ID провайдера в models.json и auth.json должны совпадать. Затем выберите кастомную модель напрямую:

zot --provider my-company --model company-llm-v2

Kimi Code

zot имеет встроенную поддержку Kimi через эндпоинт Kimi Coding и OpenAI-совместимый chat API Moonshot.

zot --provider kimi

По умолчанию это использует:

  • модель: kimi-for-coding
  • базовый URL: https://api.kimi.com/coding/v1

Порядок поиска учётных данных для Kimi:

  1. --api-key
  2. KIMI_API_KEY
  3. MOONSHOT_API_KEY
  4. $ZOT_HOME/auth.json
  5. официальный токен Kimi Code CLI в ~/.kimi/credentials/kimi-code.json, если не отключён /logout kimi

Используйте /login для логина по API-ключу или подписке Kimi Code. Flow подписки использует device-code OAuth-flow Kimi Code: zot открывает URL верификации, ждёт подтверждения браузером, сохраняет токен в auth.json и обновляет его автоматически.

Для прямых ключей Moonshot API или кастомного совместимого эндпоинта:

zot --provider kimi --model kimi-k2-0905-preview --base-url https://api.moonshot.ai/v1 --api-key "$KIMI_API_KEY"

Kimi K3 встроен как kimi/k3, moonshotai/kimi-k3, moonshotai-cn/kimi-k3, opencode-go/kimi-k3, openrouter/moonshotai/kimi-k3 и vercel-ai-gateway/moonshotai/kimi-k3. Его лимит вывода — 131 072 токена на любом встроенном маршруте.

Можно добавить дополнительные ID моделей Kimi/Moonshot в models.json под провайдером kimi.

xAI

xAI поддерживает либо XAI_API_KEY, либо аутентификацию по подписке через /login. Опция подписки помечена Sign in with SuperGrok or X Premium, открывает предзаполненный URL device-authorization и обновляет сохранённый токен автоматически. Модель xAI по умолчанию — grok-4.5, отправляется через Responses API.

DeepSeek

zot имеет встроенную поддержку DeepSeek через OpenAI-совместимый chat API DeepSeek.

zot --provider deepseek

По умолчанию это использует:

  • модель: deepseek-v4-pro
  • базовый URL: https://api.deepseek.com/v1

Каталог поставляется с deepseek-v4-pro (рассуждение) и deepseek-v4-flash. Это именно те ID, которые сегодня возвращает GET https://api.deepseek.com/models. Можно добавить дополнительные ID моделей в models.json под провайдером deepseek.

Порядок поиска учётных данных для DeepSeek:

  1. --api-key
  2. DEEPSEEK_API_KEY
  3. $ZOT_HOME/auth.json

Используйте /login и выберите api key, чтобы вставить ключ DeepSeek. zot один раз зондирует /v1/models и сохраняет ключ под deepseek в auth.json.

Модель аутентификации: только API-ключ. DeepSeek не предлагает OAuth-flow подписки. Шаг /login subscription перечисляет только Anthropic, OpenAI и Kimi; DeepSeek появляется только под /login → api key.

Только текст на уровне протокола. Эндпоинт chat-completions DeepSeek сейчас отклоняет мультимодальную схему контента (unknown variant image_url, expected text). Когда активный провайдер — deepseek, zot молча отбрасывает части ImageBlock из исходящих сообщений пользователя/инструмента и сохраняет только текст. Переключение обратно на модель с поддержкой зрения (Claude, GPT-4o/5, Gemini) снова отправляет изображение нормально, потому что файл сессии всё равно хранит его.

Для кастомного совместимого эндпоинта (зеркало, шлюз, self-host):

zot --provider deepseek --base-url https://my-deepseek-mirror.example.com/v1 --api-key "$DEEPSEEK_API_KEY"

Google Gemini

zot имеет встроенную поддержку Google Gemini через AI Studio Generative Language API.

zot --provider google

По умолчанию это использует:

  • модель: gemini-2.5-pro
  • базовый URL: https://generativelanguage.googleapis.com

Каталог поставляется с gemini-2.5-pro, gemini-2.5-flash, gemini-2.5-flash-lite, gemini-2.0-flash и gemini-2.0-flash-lite. Живое обнаружение против /v1beta/models добавляет всё остальное, что видит ваш ключ.

Порядок поиска учётных данных для Google:

  1. --api-key
  2. GEMINI_API_KEY
  3. GOOGLE_API_KEY
  4. $ZOT_HOME/auth.json

Используйте /login и выберите api key, чтобы вставить ключ AI Studio. zot один раз зондирует /v1beta/models и сохраняет ключ под google в auth.json.

Модель аутентификации: только API-ключ (этот провайдер). Google не выпускает OAuth-токены для потребительских подписок Gemini Advanced / Google One AI Premium, так что нет flow "войти с подпиской Google". Шаг /login subscription тихо понижается до формы api-key, когда вы выбираете Google, чтобы не заходить в тупик. Если нужна OAuth/аутентификация сервисным аккаунтом вместо API-ключа, используйте провайдер google-vertex ниже.

Лимиты бесплатного уровня. Бесплатный уровень AI Studio имеет жёсткие ограничения в минуту и в день, различающиеся по моделям: gemini-2.5-pro самый строгий (несколько запросов в минуту, ~50 в день), Flash и Flash-Lite гораздо щедрее. Если ход Pro получает 429 с "You exceeded your current quota", пока Flash на том же ключе всё ещё работает — вы упёрлись в дневной лимит бесплатного уровня Pro. Либо переключитесь на Flash для циклов агента, либо включите биллинг в вашем проекте AI Studio, чтобы перевести тот же ключ с бесплатного на pay-as-you-go тариф ($1.25/M вход, $10/M выход для Pro).

Уровни рассуждения (--reasoning off|minimum|low|medium|high|xhigh|max, также настраиваемые через /reasoning или в /settings как уровень рассуждения) отображаются по-разному для каждого поколения. max — отдельный opt-in уровень выше xhigh. GPT-5.6 и модели Claude с адаптивным мышлением получают нативный max; неподдерживающие провайдеры ограничивают его своим максимально принимаемым усилием. Провайдеры на основе бюджета сохраняют свои ограничения провайдера/модели. Gemini 3.x использует перечисление thinkingLevel (MINIMAL/LOW/MEDIUM/HIGH), с Gemini-3-Pro, закреплённым на минимум LOW и HIGH для любого запроса medium-или-выше. off не отправляет конфигурацию рассуждения. Модели Gemini 2.0 не имеют конфигурации мышления.

Можно добавить дополнительные ID моделей Gemini в models.json под провайдером google.

Gemini Enterprise Agent Platform (ранее Google Vertex AI)

zot также имеет встроенную поддержку Gemini Enterprise Agent Platform, корпоративного/GCP-размещённого эндпоинта Gemini от Google. В отличие от провайдера google (AI Studio) выше, провайдер google-vertex поддерживает API-ключ Google Cloud плюс файлы учётных данных service_account и authorized_user. Он не поддерживает потребительский логин Google или полную цепочку ADC-учётных данных, такую как учётные данные metadata-сервера и workload-identity.

zot --provider google-vertex

Обязательная конфигурация (переменные окружения, читаются при конструировании):

  • GOOGLE_CLOUD_PROJECT — обязательно, ID вашего проекта GCP.
  • GOOGLE_CLOUD_LOCATION — опционально, по умолчанию us-central1.

Порядок поиска учётных данных для Vertex:

  1. GOOGLE_CLOUD_API_KEY: простейший вариант. API-ключ, созданный в консоли GCP, отправляется как x-goog-api-key, без обмена токеном.
  2. GOOGLE_APPLICATION_CREDENTIALS: путь к поддерживаемому файлу учётных данных JSON.
  3. Файл ADC по умолчанию: если ни одно из вышеперечисленного не задано, zot проверяет файл, записанный gcloud auth application-default login. Это ~/.config/gcloud/application_default_credentials.json на Unix-системах и %APPDATA%\gcloud\application_default_credentials.json на Windows.

Поддерживаются две формы файлов учётных данных:

  • type: "service_account": zot подписывает JWT приватным ключом и обменивает его на короткоживущий access-токен.
  • type: "authorized_user": zot обменивает сохранённые client ID, client secret и refresh-токен на короткоживущий access-токен.

Access-токены кешируются в памяти и обновляются по требованию.

Если ничего из этого недоступно, zot выдаёт ошибку vertex: no auth — set GOOGLE_CLOUD_API_KEY or GOOGLE_APPLICATION_CREDENTIALS.

Локальные модели через ollama

zot работает с ollama из коробки. Ollama обслуживает OpenAI-совместимый API локально, так что любая скачанная модель работает с zot.

Быстрый старт:

ollama pull qwen3.5:4b
zot --provider ollama --model qwen3.5:4b

Это всё. API-ключ не нужен для локальных моделей. zot по умолчанию использует http://localhost:11434.

Для удалённого экземпляра ollama или за аутентификацией:

zot --provider ollama --model llama3 --base-url https://my-server.com/v1 --api-key my-token

Можно также добавить модели в models.json, чтобы не указывать флаги каждый раз:

{
  "providers": {
    "ollama": {
      "models": [
        {
          "id": "qwen3.5:4b",
          "name": "Qwen 3.5 4B",
          "contextWindow": 32768,
          "maxTokens": 8192
        }
      ]
    }
  }
}

Провайдер ollama использует протокол OpenAI chat completions внутренне, так что также работает с любым OpenAI-совместимым сервером (vLLM, LM Studio, LocalAI и т.д.).

Локальные модели через режим роутера llama.cpp

zot может подключаться к недавнему роутеру llama.cpp, управлять его GGUF-файлами и использовать загруженные модели через OpenAI-совместимый API вывода роутера. Это отдельно от Ollama. Сервер Ollama обычно слушает порт 11434, и вместо этого следует использовать провайдера ollama zot.

Установите или обновите llama.cpp. На macOS через Homebrew:

brew install llama.cpp
# или, если уже установлен
brew upgrade llama.cpp

Создайте директорию для GGUF-файлов и запустите llama-server без --model, -m или -hf. Указание одной из этих опций запускает одну модель, а не API роутера, который нужен zot.

mkdir -p ~/llama-models

llama-server \
  --models-dir ~/llama-models \
  --no-models-autoload \
  --jinja \
  --host 127.0.0.1 \
  --port 8080 \
  -ngl 999 \
  -c 32768

--no-models-autoload оставляет решения о загрузке /llama. --jinja включает шаблоны чата модели и улучшает совместимость с вызовами инструментов. -ngl 999 запрашивает максимальную выгрузку на GPU, в то время как -c 32768 ограничивает каждую загруженную модель контекстом 32K. Скорректируйте эти значения под ваше железо.

Подтвердите, что режим роутера активен, перед настройкой zot:

curl http://127.0.0.1:8080/health
curl http://127.0.0.1:8080/models

Запрос моделей должен вернуть JSON с массивом data. 404 обычно означает, что сервер устарел, работает на другом порту или запущен в режиме одной модели.

В zot запустите /login, выберите api key и выберите llama.cpp. Введите http://127.0.0.1:8080 как URL роутера и оставьте API-ключ пустым для локального сервера. Не вводите /v1; zot выводит URL вывода сам. Сохранённый URL и опциональный ключ хранятся в $ZOT_HOME/auth.json.

Можно настроить то же соединение через переменные окружения:

export LLAMA_BASE_URL=http://127.0.0.1:8080
export LLAMA_API_KEY=optional-secret

При использовании ключа запускайте сервер с соответствующим значением --api-key. Держите --host 127.0.0.1, если удалённым клиентам не нужно достучаться до роутера.

Запустите /llama, чтобы:

  • инспектировать текущие состояния моделей роутера
  • искать репозитории GGUF на Hugging Face
  • выбрать квантование и скачать его с прогрессом в байтах
  • явно загрузить или выгрузить модель
  • нажать d, чтобы попросить роутер удалить скачанную модель из кеша после подтверждения

Модели, обнаруженные через --models-dir или пресет, не могут быть удалены zot. Вместо этого удалите эти файлы из их настроенного источника. Роутер удаляет выбранный GGUF из кеша Hugging Face, но некоторые версии llama.cpp сохраняют общие артефакты репозитория, такие как файлы mmproj. Удалите директорию кеша репозитория вручную, если эти артефакты больше не нужны. Поиск Hugging Face использует HF_TOKEN, если доступен. Закрытые репозитории требуют предварительного одобрения доступа, и процессу llama-server также нужен авторизованный HF_TOKEN, потому что сервер выполняет загрузку.

Открытие /model обновляет роутер и перечисляет каждую загруженную модель под провайдером llama.cpp. Выгруженные модели намеренно опускаются, потому что не могут отвечать на запросы вывода. Загрузите их через /llama сначала, затем выберите через /model.

Модель, установленная через Ollama, хранится во внутреннем хранилище Ollama и не становится автоматически доступна как GGUF-файл llama.cpp. Скачайте копию GGUF через /llama или поместите GGUF-файлы в ~/llama-models, затем перезапустите роутер, чтобы он обнаружил файлы, добавленные вручную.

Инлайн-изображения

Когда инструмент возвращает изображение (например, read для PNG), zot рендерит его инлайн на терминалах, которые это поддерживают: Ghostty, Kitty, iTerm2, WezTerm. На других терминалах вы видите текстовый плейсхолдер с типом MIME, пиксельными размерами и размером в байтах. Управляется переменной окружения ZOT_INLINE_IMAGES:

Значение Эффект
не задано (по умолчанию) Автоопределение по TERM_PROGRAM; текстовый плейсхолдер внутри VS Code и Herdr.
iterm, iterm2 Принудительный протокол iTerm2 OSC 1337.
kitty Принудительный протокол графики Kitty.
off, none Всегда текстовый плейсхолдер.

Поддержка графики Kitty в Herdr сейчас экспериментальна, так что zot не включает там инлайн-изображения автоматически. После включения experimental.kitty_graphics в Herdr задайте ZOT_INLINE_IMAGES=kitty, чтобы подключиться.

Кадры, содержащие изображения, перерисовываются полностью (без дифференциального diff), чтобы предотвратить залипание устаревших пикселей изображения при прокрутке. Это стоит одной вспышки терминала на кадр с изображением; задайте ZOT_INLINE_IMAGES=off, если это раздражает.

Рендеринг инструментов

По умолчанию каждый вызов инструмента (bash, read, write, edit) рендерится внутри панели с рамкой — ┌─ header ─┐, строки тела с префиксом │ и футер └─┘. На экране с множеством вызовов рамки могут выглядеть шумно, так что zot также предлагает режим flat: одна тихая строка заголовка на вызов (▌ bash …) с отступом, вывод без рамки. Та же информация — имя инструмента, сводка аргументов, потоковый вывод, усечение ... (N more lines, ctrl+o to expand) — просто без рамки.

Задайте ключ tool_render в $ZOT_HOME/config.json:

{
  "tool_render": "flat"
}
Значение Эффект
не задано / "box" (по умолчанию) Каждый вызов инструмента обёрнут в панель с рамкой.
"flat" Без рамки: тихая строка заголовка плюс вывод с отступом.

Переменная окружения ZOT_FLAT_TOOLS переопределяет конфиг для одного запуска, что удобно, чтобы попробовать без редактирования файла:

Значение Эффект
1, true, yes, on, flat Принудительно flat-рендеринг.
0, false, no, off, box Принудительно панель с рамкой.
не задано Откат на ключ конфигурации tool_render.
ZOT_FLAT_TOOLS=1 zot   # flat, только этот запуск
ZOT_FLAT_TOOLS=0 zot   # рамки, даже если config.json говорит "flat"

В обоих случаях цвета темы всё равно управляют рендерингом (заголовок использует ваш акцент/цвет текста, вывод использует цвет вывода инструмента), и ctrl+o всё равно раскрывает усечённый результат.

Ширина аргумента инструмента

Строка заголовка для вызова инструмента показывает имя инструмента плюс однострочную сводку его основного аргумента — path, command или запрос. Эта сводка усекается до 60 ячеек по умолчанию (web_answer What is the best architecture to implement resilience wit...). На широком терминале это может обрезать длинные запросы больше, чем хотелось бы, так что задайте переменную окружения ZOT_TOOL_ARG_WIDTH, чтобы поднять (или снизить) лимит:

ZOT_TOOL_ARG_WIDTH=120 zot   # позволить до 120 ячеек перед усечением
Значение Эффект
не задано (по умолчанию) Усекать сводку аргумента до 60 ячеек.
целое число в [20, 500] Усекать до этого числа ячеек.
что-либо ещё Игнорируется; откат на дефолт 60 ячеек.

Компактный ввод

По умолчанию отправленное вами сообщение рендерится как padded пузырь с фоновым оттенком: пустая тонированная строка над и под текстом, с акцентной полосой ▌ слева. Так что даже однострочный промпт занимает три строки. Задайте compact_input, чтобы свернуть это в одну тихую строку ▌ your text на завёрнутую строку — без строк отступа, без фонового оттенка.

{
  "compact_input": true
}
Значение Эффект
не задано / false (по умолчанию) Padded пузырь пользователя с фоновым оттенком.
true Одна тихая строка желоба на завёрнутую строку.

Переменная окружения ZOT_COMPACT_INPUT переопределяет конфиг для одного запуска (1/true/on/compact принудительно компактный; 0/false/off/bubble принудительно пузырь):

ZOT_COMPACT_INPUT=1 zot   # компактный, только этот запуск

Очередь сообщений

Можно продолжать печатать, пока агент работает. Нажатие enter во время хода ставит сообщение в очередь вместо прерывания: оно отображается над статус-строкой как sliding in: <text> и доставляется как следующий ход пользователя, как только текущий завершится. Очередь сколько угодно; выполняются по порядку. esc отменяет активный ход и сбрасывает очередь, чтобы неуправляемый ход не завалил вас устаревшими продолжениями; ctrl+c во время занятости взводит подсказку выхода вместо прерывания, второй ctrl+c в течение двух секунд выходит из zot.

Чтобы вернуть последнее поставленное в очередь сообщение обратно в редактор (чтобы подправить перед выполнением), нажмите Option+↑. В интегрированном терминале VS Code это сочетание не переживает обработку клавиш macOS в xterm.js — используйте там Option+Shift+↑. Строка подсказки zot под очередью адаптируется автоматически в зависимости от $TERM_PROGRAM.

Slash-команды также работают, пока агент занят. Неразрушительные (/help, /jump, /btw, /sessions, /skills, /reasoning, /settings, /jail, /unjail, /exit) применяются немедленно. Разрушительные (/clear, /compact, /login, /logout, /model, /reload-ext) сначала отменяют активный ход, затем выполняются.

Клавиши (интерактивный режим)

Ввод

Клавиша Действие
enter Отправить (ставится в очередь, если агент занят).
alt+enter Новая строка.
tab Завершить выбранную slash-команду.
esc Отменить текущий ход (пока занят); очистить ввод (пока простаивает).
ctrl+c Очистить ввод и очередь (пока простаивает) или взвести подсказку выхода (пока занят). Нажмите снова в течение 2с, чтобы выйти. Используйте esc, чтобы отменить работающий ход.
ctrl+d Выйти при пустом вводе.
ctrl+l Перерисовать экран.
ctrl+v Вставить текст из буфера обмена в сфокусированный чат, побочный чат, диалог, фильтр или ввод учётных данных. На Linux используется wl-paste, xclip или xsel; нативная для терминала bracketed paste остаётся доступной без этих команд. В основном чате на macOS содержимое буфера обмена только с изображением сохраняется как временный PNG и прикрепляется к следующему промпту.
ctrl+o Развернуть или свернуть длинные результаты инструментов (вывод read, write, edit, bash более ~12 строк).
ctrl+1 ... ctrl+9 Переключиться на модель, привязанную к этому слоту быстрой модели (настраивается в /settings -> ярлыки моделей). Не действует, пока идёт ход.
@ Открыть выбор файла. Обзор файлов и директорий в рабочей директории.

Выбор файла (@)

Клавиша Действие
@ Открыть выбор файла (введите после пробела или в начале ввода).
up, down Навигация по списку файлов.
right Открыть выбранную директорию.
left Вернуться к родительской директории.
enter Выбрать файл или директорию и вставить как чип ([file:name] или [dir:name/]).
esc Закрыть выбор файла.

Введите @, за которым следует строка фильтра, чтобы сузить список (например, @read показывает только записи, содержащие "read"). Выбранные файлы вставляются как компактные чипы, разворачивающиеся в полный путь при отправке. Перетащенные файлы и директории тоже автоматически сворачиваются в чипы.

Навигация по строкам редактора

Клавиша Действие
ctrl+a, ctrl+e Перейти в начало или конец строки.
alt+left, alt+right Перейти на слово назад или вперёд.
ctrl+u, ctrl+k Удалить до начала или конца строки.
ctrl+w, alt+backspace Удалить предыдущее слово.
up, down Перемещение внутри многострочного ввода. У верхнего края up вызывает предыдущие промпты, а down двигается вперёд по истории промптов.

Прокрутка чата

Клавиша Действие
pgup, pgdn Прокрутить на страницу вверх или вниз.
up, down (редактор пуст, не просматривается история промптов) Прокрутить на три строки вверх или вниз. Так колесо мыши достигает логики прокрутки на большинстве терминалов.

Расширения

zot можно расширять на любом языке через протокол subprocess + JSON-RPC. Расширения могут регистрировать slash-команды, открывать инструменты модели, перехватывать вызовы инструментов (блокировать или переписывать аргументы), гейтить целые ходы перед вызовом модели и переписывать видимый текст ассистента перед тем, как он дойдёт до пользователя. По умолчанию ничего не установлено; подключайтесь явно. Горячая перезагрузка в любое время через /reload-ext.

Установка и управление

zot ext install <path|git-url>   # копировать / клонировать в $ZOT_HOME/extensions/
zot ext list                      # показать установленные расширения
zot ext doctor                    # диагностировать проблемы загрузки, регистрации и конфликтов
zot ext logs <name> [-f]          # cat или tail лога stderr расширения
zot ext enable <name>             # снова включить отключённое расширение
zot ext disable <name>            # отключить без удаления
zot ext remove <name>             # удалить директорию расширения

zot ext doctor сохраняет обычный запуск расширений fail-soft, но даёт вам явный вид для устранения неполадок: ошибки манифеста, отключённые или затенённые расширения, ошибки загрузки подпроцесса, статус ready/auto-ready, зарегистрированные команды/инструменты, конфликты регистрации, предупреждения и путь к логу stderr.

Для разработки укажите zot --ext <path> на рабочую директорию и полностью пропустите шаг установки. Повторяемо; имеет приоритет над установленными расширениями с тем же именем.

Обновление расширений

zot update обновляет бинарник zot и каждое установленное расширение, живущее в git-checkout'е. Поведение по расширению:

  • Отключённые расширения пропускаются.
  • Расширения без директории .git/ (установленные через zot ext install ./local-path) пропускаются — тянуть неоткуда.
  • Для остальных zot прячет любое грязное состояние worktree (включая неотслеживаемые рантайм-файлы вроде todos.json или config.json), выполняет git pull --ff-only и возвращает stash. Если возврат вызывает конфликты, маркеры конфликтов остаются на месте, и вы увидите предупреждение.
  • Разошедшиеся ветки, офлайн-pull'ы или любой другой сбой git отображаются как failed, и обрабатывается следующее расширение. zot update сам никогда не прерывается из-за расширения.
  • zot не запускает никакой шаг сборки (go build, npm install, make) после pull. От авторов расширений ожидается коммит исполняемого артефакта (бинарника, транспилированного JS и т.д.). Если нужна сборка, пересоберите вручную и используйте /reload-ext.

Расширения только для темы

Расширение может поставлять только тему: extension.json плюс theme.json (или themes/theme.json) и без исполняемого файла. zot загружает его без запуска подпроцесса и показывает в /settings с информацией об источнике. См. docs/themes.md.

Референс

examples/extensions/ поставляет референсные реализации на Go, TypeScript, Node и shell. См. docs/extensions.md для полного протокола, API SDK (packages/agent/ext) и дорожной карты фаз.

Skills

Skill — это файл SKILL.md на директорию с YAML frontmatter-заголовком. zot обнаруживает skills при старте, выводит их имена в системный промпт и открывает встроенный инструмент skill, который модель использует для загрузки тела по требованию.

По умолчанию zot загружает встроенные skills плюс пользовательски установленные skills из:

  • ./.zot/skills/<name>/SKILL.md (проект)
  • $ZOT_HOME/skills/<name>/SKILL.md (глобально)
  • ./.claude/skills/<name>/SKILL.md, ~/.claude/skills/<name>/SKILL.md (Claude-совместимый layout)
  • ./.agents/skills/<name>/SKILL.md, ~/.agents/skills/<name>/SKILL.md (agent-совместимый layout)

См. docs/skills.md для полей frontmatter, советов по созданию и примеров skills в examples/skills/.

Telegram-бот (мост)

zot может работать как telegram-бот, чтобы можно было писать ему личные сообщения с телефона. Два способа запустить: изнутри TUI (работающая сессия зеркалируется в Telegram) или как отдельный фоновый демон (headless-бот со своим независимым агентом).

Изнутри TUI

Введите /telegram в работающем TUI, чтобы открыть выбор с connect, disconnect и status. При подключении:

  • Личные сообщения от связанного пользователя становятся промптами в той же сессии, в которую вы печатаете, так что можно продолжить разговор с телефона в терминале и обратно.
  • Сообщения, набранные в TUI, зеркалируются в Telegram-тред с префиксом you: ..., а ответы ассистента возвращаются с префиксом zot: ..., так что Telegram-чат остаётся полной записью обеих сторон разговора.
  • Сообщения, отправленные из Telegram, появляются как ваш собственный пузырь в Telegram (без зеркала), а ответ ассистента на них возвращается без префикса.
  • Статус-строка показывает тег - tg -, пока мост активен.
  • /telegram connect / /telegram disconnect / /telegram status (или /tg) также работают как прямые команды без выбора.

Мост внутри TUI отказывается запускаться, пока работает отдельный демон (ниже), так как два одновременных long-poll потребителя одного бота конкурируют за каждое обновление и молча теряют сообщения.

Отдельный демон

Для headless-серверов или долго работающих ботов, не привязанных к TUI:

zot telegram-bot setup     # вставить токен BotFather, проверить, сохранить
zot telegram-bot run       # foreground: long-poll в этом терминале (ctrl+c для остановки)
zot telegram-bot start     # background: отсоединиться и сразу вернуться
zot telegram-bot stop      # SIGTERM фоновому боту (SIGKILL через 5с)
zot telegram-bot logs -f   # tail $ZOT_HOME/logs/bot.log (без -f просто cat)
zot telegram-bot status    # конфигурация (токен замаскирован) + работает/остановлен
zot telegram-bot reset     # забыть токен и связанного пользователя
# короткий псевдоним: `zot tg ...` принимается для каждой подкоманды

Фоновый вариант записывает PID потомка в $ZOT_HOME/bot.pid и перенаправляет stdout и stderr в $ZOT_HOME/logs/bot.log. zot telegram-bot stop читает этот PID, отправляет SIGTERM, ждёт до пяти секунд, затем эскалирует до SIGKILL, если потомок ещё жив. Запуск двух экземпляров одновременно отклоняется при старте.

Используйте установленный бинарник для start. go run ./cmd/zot telegram-bot start не сработает. go run собирает бинарник во временной директории и удаляет его при выходе, что убивает отсоединённого потомка. Сначала выполните make install (или go build) и вызовите установленный бинарник.

Flow настройки:

  1. Напишите @BotFather в telegram, запустите /newbot, скопируйте выданный токен.
  2. Запустите zot telegram-bot setup и вставьте токен, когда спросят.
  3. Запустите zot telegram-bot run в директории, в которой должен работать агент.
  4. Откройте вашего бота в telegram, отправьте /start. Первый пользователь, сделавший это, забирает мост (хранится как allowed_user_id); любой другой пользователь отклоняется.

С этого момента любое отправленное вами личное сообщение пересылается агенту как промпт пользователя. Прикреплённые фото или документы image/* скачиваются и передаются моделям с поддержкой зрения. Команды telegram внутри бота регистронезависимы: /help, /status, /stop (отменить текущий ход). Конфигурация хранится в $ZOT_HOME/bot.json (режим 0600).

Запуск любого моста Telegram удаляет любой webhook, настроенный для этого бота, перед началом long polling, сохраняя ожидающие обновления. Telegram не позволяет webhooks и polling getUpdates одновременно, так что не делитесь токеном бота с другим сервисом, ожидающим сохранения активного webhook.

Режим бота учитывает обычные флаги zot: --provider, --model, --cwd, --reasoning, --continue, --no-session, --no-tools и так далее. Например, запустите zot tg run -c --model claude-opus-4-1, чтобы возобновить последнюю сессию на Opus.

Архитектура: протокол-независимое ядро бота

Функциональность мессенджера разделена на два слоя. Общее, протокол-независимое ядро живёт в packages/agent/modes/bot: оно владеет очередью ходов, промптингом агента, диспетчеризацией встроенных команд (/start, /help, /status, /stop), форматированием статуса и обновлением учётных данных по ходу. Конкретные транспорты реализуют небольшой интерфейс BotAdapter (входящий polling, отправка ответов, индикатор набора текста и опциональный специфичный для протокола статус-текст); поддержка Telegram в packages/agent/modes/telegram — один такой адаптер.

Это значит, что дополнительные бэкенды мессенджинга (Discord, Slack, Signal и подобные) можно добавить, реализовав BotAdapter в новом пакете и подключив подкоманду. Изменения в runner, агенте или ядре не требуются. ID каналов — непрозрачные строки, принадлежащие адаптеру, так что общий runner остаётся свободным от специфичных для протокола типов.

Разработка

make build     # собрать ./bin/zot
make test      # go test -race ./...
make lint      # go vet + проверка gofmt
make fmt       # gofmt -w .
make release   # кросс-компиляция linux/darwin/windows на amd64 и arm64

Структура исходников (единый Go-модуль, четыре пакета под packages/):

cmd/zot/                              main()
packages/provider/                    поверхность LLM-клиента, каталог моделей, потоковые клиенты
packages/provider/auth/               хранилище учётных данных, зонд API-ключа, oauth, сервер логина
packages/core/                        цикл агента, сессии, отслеживание стоимости, компакция
packages/tui/                         raw-режим терминала, парсер ввода, редактор, рендерер, markdown, вид
packages/agent/                       подключение cli, разбор аргументов, системный промпт, конфиг
packages/agent/extensions/            менеджер подпроцессов расширений
packages/agent/extproto/              типы формата протокола расширений
packages/agent/modes/                 интерактивный tui, print, json, диалоги
packages/agent/modes/bot/             протокол-независимый runner бота (интерфейс BotAdapter)
packages/agent/modes/telegram/        адаптер telegram, api-клиент, демон
packages/agent/tools/                 read, write, edit, bash, sandbox
packages/agent/skills/                обнаружение skills, парсер frontmatter, инструмент skill
packages/agent/swarm/                 рантайм фоновых субагентов
packages/agent/sdk/                   публичный Go SDK для встраивания zot в процесс (пакет sdk)
packages/agent/ext/                   публичный Go SDK для написания расширений (пакет ext)

Нижестоящие потребители могут зависеть от отдельных пакетов: go get github.com/patriceckhart/zot/packages/core подтягивает только core и его транзитивные зависимости (сегодня: provider), без кода агента или TUI.

Лицензия

MIT

Войдите, чтобы оставить комментарий