Провайдеры и ключи
Провайдер — это base_url, модель и имя переменной с ключом. Профилей может быть несколько; активный выбирается одной строкой в конфиге.
Профиль
active_provider = "cloud"
[providers.local]
base_url = "http://127.0.0.1:11434/v1"
model = "qwen3-coder"
# key_env = "LOCAL_KEY" # необязательно: пусто — берётся общий key_env
[providers.cloud]
base_url = "https://провайдер.example/v1"
model = "имя-модели"
Активный профиль перекрывает top-level base_url/model/key_env. Нет секции [providers] вовсе — работают top-level ключи. Активный, но неполный профиль (стёрли модель) не подменяет top-level: ядро работает как раньше, а не падает на пустом slug. Модель — часть профиля, потому что у провайдеров разный нейминг одних и тех же моделей: переключение без модели отправило бы чужой slug.
Ключ
В конфиге только имя переменной. Значение — в .env рядом с *фактическим* конфигом (--config /tmp/x/config.toml читает /tmp/x/.env):
snens providers key cloud sk-... # значение видно в ps
snens providers key cloud - < ключ.txt # ключ со stdin
Запись сохраняет остальные строки файла и права 0600. Пустое значение — удаление. Приоритет: переменная окружения процесса, потом .env; переменная сильнее файла.
Команды
snens providers # список: ● активный, адрес, модель, задан ли ключ
snens providers activate cloud
snens providers key cloud -
Список показывает только признак «ключ задан», само значение не печатается нигде. Те же действия есть в меню настроек веб-клиента и десктопа — это правка одного и того же файла.
Квирки провайдера
Поля, которые провайдер требует не по стандарту, добавляются без правки кода:
body_patch = { reasoning = { effort = "low" }, parallel_tool_calls = false }
headers = { "X-Title" = "мой snens" }
body_patch кладётся в тело запроса поверх model/messages/tools/stream; headers — в заголовки поверх дефолтов, включая заголовки атрибуции, которые ядро добавляет само при адресе openrouter. Заголовки из конфига побеждают.
Модель подагентов
subagent_model = "имя-дешёвой-модели"
Подагент (run --detach) идёт этой моделью, основная сессия — своей. Не задано — наследуется основная. Закрепление держится кодом процесса: перечитывание конфига на ходу его не затирает.