Конфиг
Один TOML: ~/.config/snens/config.toml (или --config, или SNENS_CONFIG). Нет файла — работают дефолты. Секретов в нём нет, они в .env рядом.
Правится тремя способами одинаково: рукой в редакторе, snens config ключ=значение, меню настроек поверхности. Ни один не переписывает файл целиком — остаются комментарии и чужие ключи.
Как читается
| когда действует | что это значит |
|---|---|
| следующий ход | ядро перечитывает файл перед каждым ходом; рестарт не нужен |
| новый запуск | значение берётся при старте цикла (run, tui, запрос поверхности) |
| новый процесс | каталоги и адреса фиксируются при загрузке: нужен рестарт сервиса |
Файл сломан — ход не падает: остаётся снимок, прочитанный при старте процесса.
Провайдер
| ключ | тип | дефолт | что меняет |
|---|---|---|---|
base_url | строка | — | адрес OpenAI-совместимого API без /chat/completions |
model | строка | — | slug модели для запроса |
key_env | строка | SNENS_API_KEY | имя переменной с ключом |
active_provider | строка | — | имя активного профиля из [providers.*] |
subagent_model | строка | — | модель подагентов; пусто — как основная |
stream_usage | bool | true | просить провайдера присылать usage в стриме |
body_patch | таблица | {} | произвольные поля в тело запроса |
headers | таблица | {} | произвольные заголовки; сильнее дефолтов |
base_url и model берутся заново перед каждым ходом. key_env — только при создании клиента (старт run/tui/новый запрос к сервису): смена имени переменной требует нового запуска. subagent_model — на новый запуск подагента. Подробности и профили — провайдеры.
Контекст
| ключ | тип | дефолт | что меняет |
|---|---|---|---|
ctx_window | целое | 1000000 | окно модели в токенах |
context_budget | целое | 0 | порог уборки; 0 — авто по окну |
context_target | целое | 0 | цель после уборки; 0 — 70% бюджета |
context_reserve | целое | 8192 | запас до предела окна (не больше ¼ окна) |
keep_results | целое | 5 | сколько последних результатов уборка не трогает |
max_result_chars | целое | 24000 | сколько символов результата инструмента доезжает до модели |
[models.<префикс>] перебивает пороги для моделей по префиксу slug; побеждает самый длинный префикс:
[models.префикс-slug]
context_budget = 120000
context_target = 80000
Что именно обрезается — лимиты.
Процессы
| ключ | тип | дефолт | что меняет |
|---|---|---|---|
max_turns | целое | 200 | потолок ходов на запуск; 0 — без лимита |
timeout_seconds | целое | 120 | таймаут одного run по умолчанию |
max_process_chars | целое | 40000 | потолок вывода процесса до отправки модели |
stream_idle_seconds | целое | 120 | сколько стрим может молчать между кадрами |
reduce_output | bool | true | сокращать вывод shell-команд (ANSI, длинные строки, повторы) |
shell | массив | ["sh","-c"], на Windows ["cmd","/C"] | чем выполняется run |
attachments | bool | true | давать инструментам канал вложений |
max_attachment_bytes | целое | 33554432 | потолок одного вложения, байты |
approval_timeout_seconds | целое | 300 | ожидание одобрения привилегированного действия; 0 — очередь выключена |
Перечитываются на каждом ходу: max_turns, timeout_seconds, max_process_chars, stream_idle_seconds, reduce_output, attachments, approval_timeout_seconds. shell попадает в описания инструментов при старте цикла: его смена требует нового запуска run/tui или рестарта сервиса.
Каталоги
| ключ | тип | дефолт | что меняет |
|---|---|---|---|
sessions_dir | строка | <данные>/sessions | журналы сессий; родитель этого каталога = каталог данных |
tools_dir | строка | tools/ рядом с бинарником, иначе <данные>/tools | реестр инструментов |
skills_dir | строка | <данные>/skills | скиллы: подкаталог = скилл |
tickets_dir | строка | <данные>/tickets | тикеты инстанса |
mail_dir | строка | <данные>/mail | ящик подагентов |
docs_url | строка | https://snens.svuvi.ch/llm/index.txt | ссылка на документацию в системном промпте; пусто — без неё |
Все пути понимают ~. Пять каталогов читаются при загрузке — их смена требует нового процесса; docs_url попадает в промпт новой сессии.
Ревью
| ключ | тип | дефолт | что меняет |
|---|---|---|---|
review_min_turns | целое | 20 | длина сессии, после которой запускается ревью |
review_idle_seconds | целое | 600 | простой на поверхности перед авторевью; 0 — выключено |
review_prompt | строка | — | свой файл промпта ревью вместо встроенного |
Память
Секция [memory]: канал долгой памяти как программа с argv-контрактом.
| ключ | тип | дефолт | что меняет |
|---|---|---|---|
cmd | строка | memory | имя программы в каталоге инструментов (или путь со слэшем) |
enabled | bool | true | мастер-выключатель: false — ни recall, ни retain не зовутся |
recall | строка | always | когда впрыскивать справку: always, session, off |
retain | bool | true | писать ход в банк памяти |
timeout_seconds | целое | 60 | таймаут одного вызова памяти |
tag | массив | [] | теги записи |
snens memory # состояние
snens memory off recall session # правка тех же ключей
Тумблеры действуют со следующего хода. Нет бинаря памяти — канала просто нет, это не ошибка.
Прочее
| ключ | тип | дефолт | что меняет |
|---|---|---|---|
system_prompt | строка | — | свой системный промпт вместо встроенного |
system_prompt фиксируется в журнале при первом ходе сессии: его правка действует на новые сессии, старые продолжают со своим. Флаг instance_git разбирается конфигом, но в коде его никто не читает — полагаться на него не стоит.
Проверка
snens config # текущие значения правимых ключей и путь файла
snens config max_turns=100 # правка на ходу; печатает путь файла
snens config показывает только ключи, которые правятся на ходу. Остальные — в файле; список целиком — таблицы выше. На успехе печатается путь файла, на ошибке — ненулевой код и текст в stderr.