# Автоматический выбор модели для Pi

[English](README.md)

Плагин автоматически выбирает модель для задач в Pi. По вашим правилам рутинные запросы можно отправлять недорогой модели, а сложные задачи с кодом — более сильной.

Сервис [AllaiGate](https://api.allaigate.com/ru/) определяет тип задачи и оценивает её сложность. Плагин применяет ваши правила и выбирает из подключённых к Pi моделей. Для работы нужны API-ключ AllaiGate и работающий провайдер моделей.

Пример правил — модели выбираете вы:

| Задача и оценка | Ваш выбор |
| --- | --- |
| Простая задача | Ваша недорогая модель |
| Сложная задача с кодом | Ваша более сильная модель для кода |

В [живом тесте 9 сентября 2026 года](docs/live-verification.ru.md) плагин переключил DeepSeek V4 Pro на DeepSeek V4 Flash, после чего Pi выполнил один вызов инструмента и вернул `CORTIQ_LIVE_OK`.

## Установка

Проверено с **`@earendil-works/pi-coding-agent` 0.85.1**. Требуется **Node.js 22.19.0+**. Другие версии Pi не проверены. Пакет доступен в npm; также поддерживается установка из Git или локальной папки.

Сначала настройте провайдеров в Pi и проверьте доступность нужных моделей для своего аккаунта. Отдельный API-ключ получите на [AllaiGate](https://api.allaigate.com/ru/).

```sh
pi install npm:cortiq-pi-router@0.1.1
```

Для установки из Git вместо npm используйте `pi install git:github.com/infosave2007/cortiq-pi-router`.

Добавьте `-l` для установки только в текущий проект; Pi может запросить доверие к проекту. Вариант с локальной копией:

```sh
git clone https://github.com/infosave2007/cortiq-pi-router.git
pi install /absolute/path/to/cortiq-pi-router
```

В пакете объявлено `pi.extensions: ["./dist/index.js"]`. Готовый JavaScript включён в репозиторий: ручная сборка и неопубликованные зависимости не нужны. Установкой пакета управляет Pi. После установки перезапустите Pi.

Передайте ключ через окружение процесса Pi:

```sh
export CORTIQ_ROUTER_KEY='ваш-api-ключ'
pi
```

Не записывайте реальные ключи в репозиторий. Ключи LLM-провайдеров настраиваются отдельно средствами Pi.

## Настройка

Создайте `.pi/cortiq-router.json` в рабочей директории Pi по примеру [cortiq-router.example.json](cortiq-router.example.json). `CORTIQ_ROUTER_CONFIG` задаёт другой JSON-файл; относительный путь разрешается от рабочей директории Pi. Расширение не редактирует настройки Pi. Конфиг читается для каждого пользовательского запуска и повторно проверяется перед выбором модели: новые настройки применяются без перезагрузки расширения.

Замените модели примера точными идентификаторами из настроенного каталога Pi:

```json
{
  "globalTiers": {
    "low": ["openai/gpt-4.1-mini"],
    "medium": ["openai/gpt-4.1"],
    "high": ["openai/gpt-4.1"]
  },
  "taskRules": {},
  "defaultModel": "openai/gpt-4.1-mini"
}
```

Формат — `provider/model`. Разделяется только первый слеш: `openrouter/anthropic/claude-sonnet-4.5` сохраняет весь идентификатор модели. Кандидат должен находиться в каталоге доступных моделей Pi, иметь настроенную авторизацию и входить в активный список scoped models, если он задан. Проверяется поддержка текста и изображений текущего запроса. Наличие авторизации не гарантирует исправность ключа, квоту или доступ аккаунта.

| Настройка | Значение по умолчанию / смысл |
| --- | --- |
| `enabled` | `true`; `false` отключает дальнейшую маршрутизацию |
| `apiKeyEnv` | `CORTIQ_ROUTER_KEY` |
| `routerUrl` | `https://router.allaigate.com`; добавляется `/v1/route` |
| `taxonomyId` | `data-assistant` |
| `timeoutMs` | `15000`; целое 1–120000 мс |
| `maxChars` | `12000`; целое 1–1000000 кодовых единиц UTF-16 |
| `routerProfile` | `balanced`, `cost-saver` или `quality-first` |
| `complexityBands` | Без поля используется tier роутера; `{ "low": 0.35, "medium": 0.65 }` задаёт свои границы |
| `globalTiers` | Пусто; массивы `low`, `medium`, `high` |
| `taskRules` | Пусто; метка задачи → модель/массив либо объект с `low`, `medium`, `high`, `any` (`models` — синоним `any`) |
| `defaultModel` | Не задана; последний кандидат и резерв при ошибке классификатора |
| `echoRouting` | `false`; опциональное уведомление Pi или сообщение в stderr о модели |

Для границ требуется `0 ≤ low < medium ≤ 1`; верхняя граница включена. Используйте метки задач из выбранной таксономии. Сначала идут модели правила задачи для конкретного уровня. Для high общий список high приоритетнее task `any`; для low/medium `any` приоритетнее общего списка. Последней идёт `defaultModel`. Недоступные кандидаты пропускаются.

Без ключа, при timeout, HTTP/auth-ошибке, перенаправлении или некорректном ответе классификатора выбирается подходящая `defaultModel`; иначе сохраняется текущая модель Pi. Отсутствие стандартного конфига означает пустые правила. Явно выбранный отсутствующий файл, неизвестные настройки и неверные типы дают короткую ошибку и оставляют выбор под управлением Pi.

## Работа, приватность и ограничения

Плагин работает через API расширений Pi. Авторизация провайдеров, генерация, инструменты и штатные повторы остаются в Pi. Отдельный gateway не требуется.

Хук `input` запоминает пользовательский текст из interactive/RPC до разворачивания skill/template; сообщения, внедрённые расширениями, исключаются. `before_agent_start` один раз классифицирует этот текст до `maxChars` и вызывает штатный `setModel`. Цикл инструментов не приводит к повторной классификации. Текст развёрнутых skills, системные инструкции, история и байты изображений дополнительно не передаются классификатору.

**Текст пользователя покидает компьютер и отправляется настроенному роутеру.** Он может содержать конфиденциальные данные. Ключи, полные запросы и credentials провайдеров не записываются в логи. Удалённый endpoint должен использовать HTTPS. HTTP допускается только для тестов на `localhost`, `127.0.0.1` или `[::1]`. Проверка TLS включена, перенаправления запрещены.

Выбранная модель становится **текущей моделью сессии**, записывается в её transcript и остаётся выбранной до следующей маршрутизации или ручной смены. Глобальные provider/model по умолчанию не изменяются. Отключение или удаление расширения не восстанавливает прежнюю модель автоматически.

Это выбор перед пользовательским запуском агента, не DSH-делегирование каждого LLM-вызова и не failover до первого streaming chunk. Ошибки провайдеров обрабатывает Pi; расширение не перебирает кандидатов после ошибок генерации. Классификация ограничена таймаутом и учитывает host AbortSignal, когда он доступен. Новый ввод, ручная смена модели и закрытие сессии инвалидируют ожидающее решение. Изменения модели выполняются последовательно; при позднем завершении старого setter восстанавливается более новый выбор пользователя. Сам асинхронный setter Pi не принимает AbortSignal и не может быть прерван во время выполнения.

Размер контекста, исторические вложения, надёжность провайдеров и работа платных API полностью не проверяются. Другие расширения могут влиять на модель и порядок обработки ввода. Платные вызовы AllaiGate/LLM выполняются отдельным скриптом `npm run live` с явным opt-in; обычный CI использует фикстуры.

## Отключение, удаление, разработка

Установите `"enabled": false` в отдельном JSON-файле, чтобы остановить дальнейшую маршрутизацию. Удаление Git-установки:

```sh
pi remove git:github.com/infosave2007/cortiq-pi-router
```

Для локальной установки укажите тот же путь: `pi remove /absolute/path/to/cortiq-pi-router`. Добавьте `-l` для удаления из настроек проекта. После удаления перезапустите Pi. JSON-конфиг и переменную ключа при необходимости удалите отдельно.

```sh
npm ci
npm run check
```

`check` компилирует расширение с опубликованным SDK Pi и выполняет fixture-тесты без платной генерации. `npm run compile` обновляет включённый в Git каталог `dist/`.

Документация Pi: [пакеты и установка](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/packages.md), [API расширений](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/extensions.md), [настройка моделей](https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/models.md).

MIT © 2026 Cortiq Team.

Дополнительные проверки упаковки и настоящего хоста:

```sh
node scripts/package-smoke.mjs --native
node scripts/native-smoke.mjs
npm pack --dry-run
```

Проверяется содержимое архива, установка tarball и Git без доступа к npm, затем настоящий Pi устанавливает и загружает расширение, выполняет запрос через локальные фикстуры сервиса выбора модели и LLM и удаляет пакет. Настройки изолированы; платные сервисы не вызываются. Проверяются выбранная модель генерации и сохранение глобальных настроек. CI также проверяет актуальность `dist/`. Доступные ID моделей можно посмотреть командой `pi --list-models`. Steering/follow-up сообщения внутри уже запущенного цикла используют модель этого цикла.

Для удаления установленного npm-пакета используйте `pi remove npm:cortiq-pi-router@0.1.1` (добавьте `-l` для установки в проект), затем перезапустите Pi.
