Терминал наносит ответный удар: переносим агентный цикл на все платформы с помощью Rust и Go
Agent! — это приложение для Mac, но агенту для программирования место там, где работают разработчики. Рассказываем, как агентный цикл превратился в два CLI, один на Rust и один на Go, с полноэкранным TUI для macOS, Windows и Linux.
Большую часть своей жизни Agent! был гордым приложением для Mac: нативный Swift и SwiftUI, глубокая интеграция с AppleScript и Accessibility, а также Launch Daemon для root-доступа. Он по-прежнему остаётся флагманом. Но за последние несколько дней что-то изменилось в нашем представлении об агентах для программирования, и сегодня это выходит в релиз.
Агентный цикл теперь работает в вашем терминале — на macOS, Windows и Linux. Он доступен в двух редакциях с одинаковыми возможностями: AgentiLoopCLI на Rust и AgentiLoopGo на Go. И да, Agent! для Mac во многом сам написал своих младших братьев.
Смена парадигмы: назад в терминал
Первая волна ИИ-инструментов для программирования жила внутри редакторов и окон чата. Побеждающая волна живёт в терминале. И на то есть веские причины:
- Работа и так происходит в терминале. Сборки, тесты, git, менеджеры пакетов и SSH-сессии — всё там. Агенту в терминале не нужна отдельная интеграция для каждого из них: у него есть
bash. - Он работает где угодно. CLI запускается на Linux-сервере сборки, внутри контейнера, по SSH на Raspberry Pi или в виртуальной машине разработчика под Windows. Приложение для Mac запускается на Mac.
- Он легко комбинируется. Разовый режим (
agentiloop "explain this project") встраивается прямо в скрипты и CI. - Он честен в том, что делает. Каждый вызов инструмента, каждый diff и каждый запрос разрешения прокручиваются перед вами обычным текстом.
Суперспособности приложения для Mac, например управление Photo Booth через Accessibility или автоматизация Mail с помощью ScriptingBridge, действительно существуют только на Mac. А вот агентный цикл — нет. Рассуждать, вызвать инструмент, прочитать реальный результат, исправиться и повторить — это работает в любой ОС, где есть оболочка и файловая система. Поэтому мы вынесли цикл наружу.
Почему два языка?
Можно было выбрать один. Вместо этого мы намеренно портировали одну и ту же архитектуру дважды.
Rust (AgentiLoopCLI) был первым. Каркас рабочего пространства был создан 20 сентября: базовый цикл, провайдер Anthropic, встроенные инструменты и CLI. Проект разделён на пять крейтов: agentiloop-core (цикл, сообщения, сессии и разрешения), agentiloop-provider, agentiloop-tools, agentiloop-mcp и agentiloop-cli. Он работает на tokio, использует reqwest с rustls, так что на Windows не нужно возиться с OpenSSL, а TUI отрисовывает с помощью ratatui. Markdown обрабатывается через pulldown-cmark, а подсветку синтаксиса кода обеспечивает syntect.
Go (AgentiLoopGo) появился 23 сентября в потоке коммитов: ядро (сообщения, агентный цикл, сжатие контекста, сессии и разрешения) с тестами, затем провайдеры, затем MCP-клиент, затем CLI с REPL, TUI, Markdown, подсветкой синтаксиса, сессиями и слэш-командами. TUI отрисовывается с помощью tcell, Markdown рендерится через goldmark, подсветка — через chroma, а редактирование строки обеспечивает liner. Его процесс релиза нацелен на те же пять платформ, что и у редакции на Rust.
Сделать всё дважды — лучшее ревью архитектуры, какое только бывает. Всё, что на самом деле было особенностью Rust или особенностью Go, сразу становится заметным, а то, что остаётся, и есть настоящая архитектура. Есть и практическая польза: выберите тот тулчейн, которому ваша команда уже доверяет. А потом расскажите нам, какой справляется лучше. 🦀 vs 🐹
Тот же цикл, меньшая поверхность
Оба CLI намеренно начинают с небольшого, но точного набора инструментов:
| Инструмент | Что делает | Спрашивает заранее? |
|---|---|---|
read_file | Читает файл с номерами строк | Нет |
list_dir | Выводит содержимое папки | Нет |
write_file | Создаёт или перезаписывает файл | Да |
edit_file | Заменяет точный фрагмент текста | Да |
bash | Выполняет команду (sh -c на Mac и Linux, cmd /C на Windows) | Да |
Нужно больше? Обе редакции включают MCP-клиент, портированный из собственного AgentMCP в Agent!, с поддержкой stdio, Streamable HTTP и устаревшего HTTP+SSE, так что инструменты любого MCP-сервера подключаются напрямую.
Разрешения — часть ядра, а не надстройка над интерфейсом. В Rust трейт PermissionPolicy решает, можно ли выполнить каждый вызов, исходя из имени инструмента, того, изменяет ли он что-либо, и его входных данных. Ответ — Allow, Deny или Cancel. Третий вариант появился из-за вполне реального неудобства: нажатие Esc в запросе разрешения должно пропускать только этот вызов, а не завершать всю задачу. CLI предоставляет интерактивную политику, а тесты и CI используют AllowAll.
Кроссплатформенность — в деталях
«Работает на Windows» легко заявить и трудно обеспечить по-настоящему. Вот что для этого понадобилось:
- По-настоящему убивать зависшую команду. Когда
bashпревышает время ожидания, убить оболочку недостаточно, если она породила дочерние процессы. Редакция на Go убивает всё дерево процессов: группу процессов в Unix и черезtaskkill /Tв Windows. Код разделён наproc_unix.goиproc_windows.go. - CI на всех трёх ОС. Репозиторий Go запускает CI на macOS, Linux и Windows, а процесс релиза Rust собирает пять бинарников: macOS arm64 и x86_64, Linux x86_64 и arm64, а также Windows x86_64.
- Подписанные бинарники для Mac. Процесс релиза умеет подписывать и нотаризовать сборки для macOS, чтобы Gatekeeper их не блокировал.
- Никакой археологии в конфигурационных файлах. CLI запоминает, как вы его запустили: провайдер, модель, режим TUI и сессию. После первого запуска простой
agentiloopпродолжит ровно с того места, где вы остановились.
TUI, который ощущается как приложение
Запускать его можно тремя способами: полноэкранный TUI (agentiloop --tui), построчный режим чата для простых терминалов и разовый режим для скриптов. У TUI выдались насыщенные несколько дней:
- анимированный индикатор занятости в поле ввода со спиннером, текущим действием и прошедшим временем
- отслеживание токенов в секунду
- кликабельные ссылки
- история запросов, сохраняющаяся между запусками
- возобновлённые сессии показывают предыдущий разговор, так что вы не смотрите на пустой экран
/modelна основе актуального списка моделей провайдера
А если API-ключ отсутствует или неверен, он сообщает об этом простыми словами и называет настоящего провайдера, вместо того чтобы вывалить ошибку 401.
Провайдеры
С первого дня он работает с Claude (API-ключ или OAuth-токен Claude Code в одном и том же поле учётных данных, схема аутентификации определяется автоматически), OpenAI и любым OpenAI-совместимым сервером, локальными моделями через Ollama или LM Studio, а также с oMLX на Apple Silicon. Адрес и ключ oMLX он автоматически читает из ~/.omlx/settings.json.
Попробуйте релиз
Сегодня мы выпустили v0.0.4 — полноценный релиз. Проект ещё на ранней стадии и быстро развивается, и мы хотим получить ваши отзывы сейчас, пока что-то изменить ещё дёшево. Скачайте бинарник из релизов Rust или соберите редакцию на Go из исходников.
Приложение для Mac никуда не денется. Если у вас Mac, Agent! по-прежнему умеет то, что не под силу ни одному терминалу. Но если вы когда-нибудь хотели иметь того же агента на Linux-сервере, ноутбуке с Windows и Raspberry Pi — он уже здесь.