Прототип агентного CLI для программирования на Go.
go run . run "inspect this project"Провайдер по умолчанию — mock, поэтому команда работает без API-ключей и удобна для тестирования цикла агента и инструментов.
Провайдер openai использует современный Responses API. Устаревший путь через Chat Completions также доступен как chat.
export OPENAI_API_KEY="..."
export OPENAI_MODEL="..."
go run . --provider openai run "inspect this project and suggest next steps"Опционально:
export OPENAI_BASE_URL="https://api.openai.com/v1"Параметры генерации:
go run . --provider openai --model "$OPENAI_MODEL" --reasoning low --max-output-tokens 2048 run "fix the failing tests"--store отключён по умолчанию — локальные сессии остаются без состояния, если явно не включить.
export OLLAMA_MODEL="qwen2.5-coder:7b"
go run . --provider ollama run "inspect this project"Опционально:
export OLLAMA_BASE_URL="http://localhost:11434/v1"Модели Ollama с поддержкой vision могут получать изображения из TUI через /attach path/to/image.png в формате image_url.
export ANTHROPIC_API_KEY="..."
export ANTHROPIC_MODEL="claude-sonnet-4-5"
go run . --provider anthropic run "inspect this project"Опционально:
export ANTHROPIC_BASE_URL="https://api.anthropic.com"export GEMINI_API_KEY="..."
export GEMINI_MODEL="gemini-2.5-flash"
go run . --provider gemini run "inspect this project"Опционально:
export GEMINI_BASE_URL="https://generativelanguage.googleapis.com/v1beta"go run . config init
go run . config show --profile coding
go run . doctor
go run . tools
go run . instructions
go run . instructions --content
go run . skills --all
go run . skills --query "frontend css" --content
go run . status --diff
go run . checkpoint create before-refactor
go run . checkpoint list
go run . diff preview patch.diff
go run . diff apply patch.diff --yes
go run . policy check "git status --short"
go run . policy check --sandbox read-only "echo hello > file.txt"
go run . sessions
go run . sessions compact feature-workgo run . chat --session feature-work
go run . tui --session feature-work
go run . --session feature-work run "continue the refactor"Сессии хранятся в .agentcli/sessions в рабочей директории и исключены из git.
Внутри чата /compact переписывает старую историю в компактное детерминированное резюме, чтобы будущие запросы тратили меньше контекстных токенов.
TUI на Bubble Tea — основной интерфейс. Поддерживаемые команды: /help, /status, /settings, /provider, /model, /reasoning, /limits, /approval, /sandbox, /attach, /attachments, /instructions, /skills, /compact, /clear, /exit.
F2 или Ctrl+S открывает панель настроек. Tab — переключение между полями, стрелки влево/вправо — выбор значений, Enter — применить.
Пример работы в TUI:
/provider ollama
/model llama3.2-vision
/endpoint http://localhost:11434/v1
/reasoning low
/limits context 16000
/attach screenshots/error.png
explain this screenshot and inspect the relevant code
При режиме апрува ask рискованные вызовы инструментов показываются как запрос подтверждения. y/Enter — разрешить, n/Esc — отклонить. always — разрешить всё без запросов.
Вложения изображений отправляются только со следующим запросом и не сохраняются в base64 в истории сессии.
Klyra имеет реальные ограничения по режимам, а не просто метки:
plan— только чтение и веб-поиск с опциональнымupdate_plan; shell, запись, патчи и внешние MCP-инструменты скрыты/заблокированы.inspect— только чтение; инструменты записи и shell скрыты/заблокированы.edit— инструменты записи требуют файлов в корзине контекста.repair— фокусирует агента на падающем выводе, релевантном коде и текущем диффе.refactor— открывает пути preview/поиска и требует явной корзины контекста перед широкими патчами.
Использование:
go run . --mode plan run "plan the auth refactor"
go run . --mode inspect run "map the auth flow"
go run . --mode edit --context-file pkg/auth/middleware.go run "fix the auth bug"/mode edit
/cart add pkg/auth/middleware.go pkg/auth/login_test.go
После хода отладчик контекста показывает режим, корзину, доступные инструменты и риски.
Вложения изображений поддерживаются для OpenAI Responses, Anthropic, Gemini и OpenAI-compatible провайдеров (в том числе Ollama). Вложения кодируются в формате провайдера и удаляются из сохранённой истории после хода.
Klyra автоматически загружает стандартные файлы инструкций репозитория в системный промпт:
AGENTS.mdCLAUDE.mdGEMINI.md.agentcli/instructions.md.agentcli/rules.md.cursorrules.github/copilot-instructions.md.cursor/rules/*.md
go run . instructions --content — посмотреть, что именно увидит агент.
Навыки — небольшие task-specific markdown-сценарии. Klyra автоматически подбирает их по тексту задачи и путям в корзине, и внедряет только подходящие в системный промпт.
Поддерживаемые расположения:
.klyra/skills/*.md.klyra/skills/*/SKILL.md.agentcli/skills/*.md.agentcli/skills/*/SKILL.mdskills/*.mdskills/*/SKILL.md
Пример метаданных:
name: Frontend Cleanup
description: CSS and UI cleanup rules
triggers: frontend, css, style
Use focused edits and avoid glassmorphism.go run . skills --all — список навыков, go run . skills --query "migration sql" --content — просмотр совпадений. Отключить: --no-skills или skills=off в TUI.
Рискованные инструменты (bash, write_file, diff_patch, точечные инструменты записи и восстановление чекпоинта) поддерживают режимы апрува:
go run . --approval ask run "fix the failing tests"
go run . --approval always run "apply the known local fix"
go run . --approval never run "inspect only"Восстановление чекпоинта — явное:
go run . checkpoint restore before-refactorПредпросмотр диффа — валидация без применения:
cat patch.diff | go run . diff previewПрименение диффа всегда валидирует патч и создаёт чекпоинт:
go run . diff apply patch.diff
go run . diff apply patch.diff --yes --checkpoint=falseПолитика shell объясняет, как команда будет обработана:
go run . policy check "git reset --hard HEAD"Профили песочницы:
go run . --sandbox read-only run "inspect the project"
go run . --sandbox workspace-write run "fix a typo"
go run . --sandbox danger-full-access run "fetch dependencies"Дешёвые модели для инспекции, мощные для редактирования и глубокого рассуждения:
go run . --provider openai \
--stream \
--max-context-tokens 32000 \
--max-instruction-bytes 12000 \
--fast-model "$FAST_MODEL" \
--edit-model "$CODING_MODEL" \
--deep-model "$REASONING_MODEL" \
run "inspect the project and propose next steps"Маршрутизация следует явному режиму агента: inspect → быстрый маршрут, edit/repair → маршрут редактирования, plan/refactor → глубокий маршрут.
Агент локально оценивает токены промпта и упаковывает контекст перед вызовами провайдера. Сохраняет системный промпт, оставляет последние ходы, удаляет осиротевшие выводы инструментов и вставляет компактное резюме при превышении --max-context-tokens.
Кокпит контекста строит небольшую корзину ретривала перед каждой задачей. Ранжирует фрагменты файлов через BM25, AST repo-map и локальные hash-эмбеддинги по словам, подтокенам идентификаторов и символьным n-граммам — без сетевого сервиса эмбеддингов.
discover_tools— открывает группы возможностей (workspace,edit,git,shell,web,plan,external) для текущего запуска.guide— возвращает компактное task-specific руководство по запросу.project_map— карта репозитория с бюджетом токенов; включает важные файлы и AST-символы.list_files— список файлов рабочей директории, пропуская сгенерированные папки.read_file— чтение файлов с нарезкой по строкам.file_outline— компактный список импортов/символов одного файла.read_symbol— чтение одного AST-символа вместо целого файла.read_go_symbol— чтение Go-объявления по имени символа.create_file— создание только новых файлов.replace_symbol,replace_lines,insert_lines— точечные инструменты редактирования существующих файлов.write_file— устаревший полнофайловый writer; скрыт в нормальных промптах редактирования.search— поиск черезrg.web_search,fetch_url— поиск в интернете и загрузка страниц.update_plan— запись короткого структурированного плана для режима plan.bash— выполнение shell-команд с таймаутом и сжатием вывода.diff_patch— применение unified diff черезgit apply.
go test ./...
go build ./...Форк добавляет 8 улучшений поверх оригинала:
Если LLM запрашивает несколько инструментов за один шаг (например, прочитать три файла), они выполняются конкурентно через горутины. Проверки на дубли и апрув остаются последовательными, результаты добавляются в контекст в оригинальном порядке.
При ошибках 429, 502, 503, 504, rate limit или разрыве соединения агент автоматически повторяет запрос до 3 раз с задержками 1с → 2с → 4с. Уважает отмену контекста.
Вывод каждого инструмента обрезается до 32 КБ перед записью в контекст. Защищает окно контекста от переполнения при больших выводах bash или файловых операций.
Новый pkg/llm/ollama.go — тонкая обёртка над OpenAI-compatible API. Подключается к локальному серверу Ollama по умолчанию на localhost:11434. Поддерживает переменную окружения OLLAMA_HOST.
provider, err := llm.NewOllamaProviderFromEnv()
// или явно:
provider, err := llm.NewOllamaProvider("http://localhost:11434/v1")Новый инструмент sub_agent позволяет агенту делегировать изолированные подзадачи дочерним агентам. Дочерний агент получает собственный контекст и набор инструментов, результат возвращается как вывод инструмента. Рекурсия заблокирована.
cfg := agent.Config{
SubAgentFactory: agent.DefaultSubAgentFactory(cfg),
}BudgetedWindow сравнивает оценочное количество токенов с реальным из ответа API и корректирует внутренний коэффициент через EMA (α=0.3). Предотвращает переполнение контекстного окна при систематическом занижении оценки.
Проверка ctx.Done() добавлена в начале каждого шага, перед запуском горутин и после их завершения. Агент завершается немедленно при отмене контекста.
В Config добавлено поле Logger *slog.Logger (по умолчанию slog.Default()). Агент логирует вызовы инструментов, ошибки, политику, retry и токены в структурированном формате.
logger := slog.New(slog.NewJSONHandler(os.Stderr, nil))
cfg := agent.Config{
Logger: logger,
}| Файл | Что изменилось |
|---|---|
pkg/agent/agent.go |
Параллельные tool calls, retry, обрезка выводов, Ctrl+C, slog |
pkg/agent/subagent.go |
Новый файл: инструмент sub_agent и SubAgentFactory |
pkg/llm/ollama.go |
Новый файл: провайдер Ollama |
pkg/context/window.go |
Калибровка токенов через CalibrateFrom() |
pkg/tools/registry.go |
Регистрация sub_agent в реестре инструментов |
Вторая волна из 8 исправлений и доработок поверх итерации 1:
Инструмент bash теперь использует cmd /c на Windows вместо bash -lc. До этого инструмент всегда падал без WSL.
Команды run и chat теперь создают контекст через signal.NotifyContext(os.Interrupt, syscall.SIGTERM). Ctx.Done-проверки в агенте (#7 из итерации 1) теперь реально работают при нажатии Ctrl+C.
DefaultSubAgentFactory теперь выставляется в runCmd, newChatCommand и newTUICommand. До этого инструмент sub_agent был зарегистрирован, но никогда не использовался.
DefaultSubAgentFactory теперь сбрасывает в дочернем агенте: Output, Input, StreamHandler, ReasoningHandler, ToolProgress, Approver. Результат дочернего агента возвращается строкой, не смешивается с выводом родителя.
Блок заполнения agent.Config{} был продублирован дословно в runCmd, newChatCommand и newTUICommand (~50 строк × 3). Заменён одним хелпером. При добавлении поля в Config теперь достаточно поменять одно место.
klyra --provider anthropic run --json "объясни этот код"Выводит машиночитаемый JSON:
{
"result": "...",
"usage": { "input": 1234, "output": 456, "total": 1690 }
}/cart add pkg/auth/middleware.go
/cart remove pkg/auth/middleware.go
/cart clear
До этого добавить файл в корзину можно было, убрать — нет.
klyra sessions delete feature-work
klyra sessions prune --days 14В TUI: /sessions delete <id>, /sessions prune --days=30. Сессии больше не копятся бесконечно.
CalibrateFrom() теперь логирует обновление коэффициента через slog.Debug — видно в структурированных логах при SLOG_LEVEL=DEBUG.
| Файл | Что изменилось |
|---|---|
pkg/tools/bash.go |
Windows: cmd /c вместо bash -lc |
pkg/session/store.go |
Новые методы Delete() и Prune() |
pkg/context/window.go |
slog.Debug в CalibrateFrom() |
pkg/agent/subagent.go |
Дочерний агент изолирован (сброс IO/handlers) |
cmd/klyra/root.go |
buildBaseAgentConfig, SIGINT, sub_agent, --json, /cart remove/clear, sessions delete/prune |
Третья волна: стоимость запросов, исключение файлов, параллельный запуск, проверка API.
После каждого запуска выводится примерная стоимость в USD:
usage: input=1234 cached=0 output=456 reasoning=0 total=1690 cost=~$0.0218
Таблица цен покрывает OpenAI (GPT-4o, o1, o3), Anthropic (Claude 3/4 Haiku/Sonnet/Opus) и Google Gemini (1.5/2.0/2.5). Кешированные токены считаются по 10% от базовой цены.
Создайте файл .klyra/ignore.md в корне проекта:
# игнорировать большие сгенерированные файлы
dist/
*.generated.go
fixtures/large_data/
Инструменты list_files, search и project_map будут пропускать эти пути. Синтаксис: glob-паттерны, строки-комментарии начинаются с # или //.
klyra run --timeout 5m "задача которая может зависнуть"
klyra run --timeout 30s "быстрая проверка"Агент принудительно завершается по истечении указанного времени. Поддерживается стандартный Go-формат: 5m, 30s, 1h30m.
klyra run --parallel "проверь auth/" "проверь api/" "проверь db/"Каждый позиционный аргумент запускается как отдельный дочерний агент в параллельных горутинах. Результаты собираются в порядке аргументов после завершения всех. Полезно для одновременного анализа нескольких частей кодовой базы.
Команда chat теперь включает стриминг токенов автоматически. Отключить: --no-stream.
/undo
Восстанавливает последний сохранённый чекпоинт воркспейса (через инструмент workspace_restore). Удобно для отката последних изменений файлов прямо из чата.
CLI:
klyra sessions rename old-name new-nameTUI:
/sessions rename old-name new-name
Переименовывает сессию без потери истории. Возвращает ошибку, если целевое имя уже занято.
klyra doctor --pingОтправляет минимальный запрос к настроенному провайдеру и выводит задержку:
ping: OK (342ms)
Или сообщение об ошибке при недоступности:
ping: FAIL (connection refused)
| Файл | Что изменилось |
|---|---|
pkg/llm/cost.go |
Новый файл: EstimateCost() + таблица цен |
pkg/agent/agent.go |
printUsage показывает стоимость |
pkg/tools/ignore.go |
Новый файл: loadIgnorePatterns + matchesIgnorePattern |
pkg/tools/files.go |
Применяет паттерны ignore в list_files |
pkg/tools/search.go |
Применяет паттерны ignore в search |
pkg/tools/project.go |
Применяет паттерны ignore в project_map |
pkg/session/store.go |
Новый метод Rename() |
cmd/klyra/root.go |
--timeout, --parallel, стриминг, /undo, sessions rename, doctor --ping |
Четвёртая волна: просмотр профилей, безопасный запуск, перенос сессий, init-команда, retry, стоимость в TUI, watch-режим.
klyra config profilesВыводит все именованные профили из конфига с ключевыми настройками:
anthropic provider=anthropic approval=ask max_steps=20
coding provider=openai reasoning=low approval=ask max_steps=20
deep provider=openai reasoning=medium approval=ask max_steps=30
gemini provider=gemini approval=ask max_steps=20
Профиль применяется флагом --profile: klyra --profile deep run "...".
klyra run --dry-run "добавь тесты к pkg/auth"Агент планирует задачу, но все вызовы инструментов перехватываются и блокируются. Выводится список инструментов, которые агент собирается вызвать:
[dry-run] agent would execute the following tools:
1. read_file {"path":"pkg/auth/auth.go"}
2. create_file {"path":"pkg/auth/auth_test.go"}
klyra sessions export my-session backup.json
klyra sessions import backup.json
klyra sessions import backup.json --overwriteЭкспорт сохраняет сессию в JSON-файл, импорт загружает её обратно. Полезно для передачи контекста между машинами или бэкапа.
klyra initСоздаёт стартовые файлы если они не существуют:
.klyra/instructions.md— место для описания проекта и конвенций.klyra/ignore.md— паттерны исключений файлов.agentcli/config.json— конфигурация по умолчанию
klyra run --retry 3 "задача"При ошибке API (rate limit, 503) агент повторяет запуск с экспоненциальной задержкой: 1с, 2с, 4с, ... Прерывается по Ctrl+C.
В строке статуса TUI появляется сумма ~$X.XXXX — накопленная стоимость всех запросов текущей сессии. Обновляется после каждого ответа агента. Отображается зелёным цветом.
klyra run --watch "исправь ошибки линтера"
klyra run --watch --watch-glob "**/*.go" "проверь код"
klyra run --watch --watch-interval 2s "задача"Агент запускается немедленно, затем следит за изменениями файлов через polling. При обнаружении изменений — автоматический повторный запуск. Выход: Ctrl+C.
| Файл | Что изменилось |
|---|---|
cmd/klyra/root.go |
config profiles, --dry-run, sessions export/import, klyra init, --retry, --watch |
pkg/session/store.go |
Новые методы Export() и Import() |
pkg/tui/model.go |
Поле sessionCostUSD, накопление стоимости, отображение в footer |
Пятая волна: композируемость и контроль — автодополнение, пайплайны, бюджет по стоимости, учёт расходов, хуки и запасная модель.
klyra completion bash > /etc/bash_completion.d/klyra # или zsh/fish/powershellСкрипты автодополнения для bash/zsh/fish/powershell (через cobra). Дополнение динамическое: --provider <TAB> предлагает бэкенды (mock/openai/chat/ollama/anthropic/gemini), а --session <TAB> — реальные id сессий из хранилища.
git diff | klyra run "сделай ревью этих изменений"Если stdin — это пайп (не терминал), его содержимое добавляется к задаче под разделителем. В интерактивном терминале stdin не читается, так что обычный запуск не блокируется.
klyra run "сгенерируй changelog" --output-file CHANGELOG.txt
klyra run "..." --json --output-file result.jsonПишет финальный ответ (или payload --json) в файл — удобно для CI-артефактов без перенаправления. Запись только при успешном прогоне.
klyra run --max-cost 0.50 "большой рефакторинг"После каждого шага агент оценивает накопленную стоимость и прерывает прогон до следующего платного вызова, как только лимит (в USD) превышен. 0 отключает гард; модели без цены (mock/local) оцениваются в $0 и не ограничиваются.
klyra run -c "а теперь добавь тесты"
klyra chat --continueВозобновляет самую свежую по времени сессию без знания её id (для run и chat). Явный --session имеет приоритет.
klyra usage
klyra usage --since 24h --by-model
klyra usage --session my-sessionКаждый прогон пишет токены/стоимость в журнал .agentcli/usage.jsonl. Команда показывает суммарный расход с фильтрами --since (длительность или дата) и --session, а --by-model даёт разбивку по моделям.
klyra sessions export my-session --mdЭкспортирует сессию в человекочитаемый markdown (заголовки ролей, рассуждения цитатами, вызовы инструментов) вместо JSON. По умолчанию пишет в <id>.md относительно --cwd.
В конфиге, секция hooks:
{
"hooks": {
"pre_tool_use": [{ "match": "bash", "command": "echo blocking risky bash; exit 1" }],
"post_tool_use": [{ "match": "*", "command": "echo tool $KLYRA_TOOL_NAME done" }]
}
}pre_tool_use запускается перед вызовом инструмента; ненулевой код выхода блокирует вызов (агент видит наблюдение «blocked by pre-tool-use hook»). post_tool_use — информационный. match — glob по имени инструмента (пусто или * = все). Команда выполняется через оболочку из рабочего каталога с переменными KLYRA_TOOL_NAME, KLYRA_TOOL_ARGS (JSON), KLYRA_HOOK_PHASE.
klyra run --fallback-model gpt-4o-mini "задача"Если основной провайдер падает с ошибкой (не отмена/таймаут контекста), агент один раз повторяет шаг на запасной модели того же бэкенда. Отмена по --timeout/Ctrl+C запасную модель не задействует.
| Файл | Что изменилось |
|---|---|
cmd/klyra/root.go |
completion, stdin-пайпинг, --output-file, --max-cost, --continue, usage, sessions export --md, --fallback-model, маппинг хуков |
pkg/agent/agent.go |
Бюджет-гард MaxCostUSD, хуки tool-call (Hooks), fallback-провайдер |
pkg/usage/ledger.go |
Новый пакет: журнал расходов (append/load/summarize/filter) |
pkg/session/store.go |
MostRecent() и ExportMarkdown() |
pkg/config/config.go |
Конфиг-секция hooks (pre_tool_use/post_tool_use) |
Шестая волна — эргономика и качество поверх волны 5.
klyra hooks list # показать сконфигурированные хуки
klyra run --no-hooks "..." # отключить хуки на один прогонhooks list печатает pre/post tool-use хуки (glob + команда) или «no hooks configured». --no-hooks обходит блокирующий pre-хук без правки конфига.
klyra usage --jsonВыводит {totals, records} в JSON для CI/скриптов (в тон run --json). Пустой журнал даёт валидный JSON с пустым массивом.
При достижении 80% лимита --max-cost выводится одноразовое предупреждение estimated cost ... is nearing the ... limit — сигнал до жёсткого обрыва.
sessions export/import и diff preview/apply теперь резолвят относительные пути файлов относительно --cwd, а не каталога процесса. Экспорт/импорт и применение патчей работают в одном рабочем каталоге без сюрпризов.
При запуске run/chat/tui klyra опрашивает локальный Ollama (/api/tags) и вписывает найденные модели в конфиг (ollama_models):
ollama: discovered 3 model(s); select one with /model in the shell
В оболочке команда /model открывает пикер с обнаруженными моделями (а /model <name> по-прежнему задаёт любую вручную). Если Ollama не установлен/не запущен — тихий no-op. Отключается флагом --no-ollama-sync.
staticcheckполностью чист (мёртвый код удалён, deprecated bubbletea mouse API мигрирован наAction/Button+ScrollUp/ScrollDown).- TUI покрыт teatest-интеграцией (реальный цикл Bubble Tea), плюс model-level тесты на cost-аккумулятор и маршрутизацию команд.
| Файл | Что изменилось |
|---|---|
cmd/klyra/root.go |
hooks list, run --no-hooks, usage --json, резолв путей sessions/diff относительно --cwd |
pkg/agent/agent.go |
Порог-предупреждение --max-cost (80%) |
pkg/session/store.go |
import резолвится относительно --cwd |
pkg/tui/model.go |
Миграция mouse/viewport API (SA1019) |
pkg/tui/teatest_test.go |
Интеграционные тесты реального цикла TUI |