v1.1.1
Текущая- Все агенты DeepSeek переведены на актуальную модель deepseek-flash (миграция 017)
Все агенты на DeepSeek — то есть все субагенты, кроме
codexbase(Codex CLI), и сам оркестратор — теперь работают на самой свежей модели DeepSeek. Актуальный идентификатор —deepseek-flash(DeepSeek-V4.1-Flash, выпущена 10.09.2026); идентификаторыdeepseek-v4-flashиdeepseek-v4-pro— предыдущее поколение и снятые с поддержки алиасы: провайдер их ещё принимает, но текущей моделью они больше не являются.Причина дефекта: снятый с поддержки алиас
deepseek-v4-flashстоял в каталоге первым и поэтому молча становился моделью по умолчанию для всех агентов DeepSeek.Код
-src/ai/model-registry.ts: записи каталога теперь можно помечать признакомlegacy: true, иdefaultModelFor()их пропускает — устаревшая модель больше никогда не станет значением по умолчанию. Сами устаревшие идентификаторы продолжают полноценно разрешаться (поиск в каталоге, распознавание изображений, тарифы, явный выбор), защищены только значения по умолчанию. Добавлена общая константаDEFAULT_DEEPSEEK_MODEL, вычисляемая из каталога.
-src/agent/tools/handlers/agent-tools.ts: два зашитых запасных значения|| 'deepseek-v4-flash'заменены наDEFAULT_DEEPSEEK_MODEL.
-src/agent/task-summary-generator.ts,src/agent/task-name-generator.ts: значения по умолчанию вспомогательных генераторов тоже переведены на общую константу.
-src/ai/pricing.ts,web/src/components/chat/modelMeta.tsx: исправлены устаревшие комментарии, утверждавшие, что v4-pro маршрутизируется и тарифицируется как Flash. DeepSeek отозвал эту схему 11.09.2026, у v4-pro свой тариф. Цифры тарифов и бейджи моделей не менялись.Миграция
-migrations/017_run_deepseek_agents_on_current_model.sqlперенаправляет уже сохранённые данные:subagents.model_override(все слаги, кромеcodexbase),app_settings.{defaultModel,modelMedium,modelHigh,modelUltra},projects.{orchestrator_model,subagent_model},project_tasks.orchestrator_modelи четыре колонки моделей вorganization_settings. Каждый запрос защищён условием на старое значение, поэтому повторный запуск не затрагивает ни одной строки. Никаких DROP, TRUNCATE и DELETE; отсутствующие таблицы и колонки пропускаются. Миграция не трогаетdisabled_models,ui.show_modelиsubagent_fallback_mode. Те же изменения были применены вручную на dev, тестовом и боевом стендах 08.10.2026 — этот файл их закрепляет, чтобы восстановление из резервной копии или новый стенд приходили в то же состояние.Тесты
-tests/model-registry-deepseek-default.test.tsфиксирует выбор модели по умолчанию (обе роли →deepseek-flash), признаки устаревших записей, обратную совместимость алиасов и неизменные значения по умолчанию у остальных провайдеров.
-tests/migration-017.test.tsфиксирует имя файла миграции, её идемпотентность, безопасность и точный набор обновляемых записей. - Ротация JSONL-логов задач (хранение 30 дней)
Пофайловые JSONL-логи задач бота (
/opt/aipi-agent/logs/tasks/*.jsonl) не очищались и росли бесконечно. Добавлен хостовый cron-скрипт, который удаляет файлы старше 30 дней (параметрTASK_LOGS_MAX_AGE_DAYS) и убирает пустые каталоги организаций. - Данные журнальных и диагностических таблиц исключены из дампа
Одна только таблица
api_callsзанимала 977 МБ (из них 804 МБ —request_messages: полный контекст каждого вызова, включая base64-картинки из результатов инструментов). Дамп — не место для архивации такого журнала.Из дампа исключены ДАННЫЕ (схема сохраняется, поэтому при восстановлении таблицы создаются пустыми и приложение продолжает в них писать) для таблиц:
api_calls,server_metric_samples,proxy_metric_samples,admin_audit_log,audit_log,command_logs,sdk_usage_logs,diagnostics,prompt_history.Переопределяется переменной
AIPI_EXCLUDE_DATA_TABLES. - Набор фавиконов для каждого инстанса через AIPI_ICON_VARIANT
- В репозиторий добавлены три готовых набора фавиконов (teal/red/green, по 12 файлов) в
web/favicons/<variant>/. - Добавлен плагин Vite (
web/vite.config.ts), который кладёт выбранный набор в кореньweb/dist, чтобы express.static отдавал/favicon.svg,/favicon.ico,/apple-touch-icon.png,/manifest.json,/icon-*.png. Набор берётся изAIPI_ICON_VARIANT(по умолчанию teal); неизвестный, пустой или отсутствующий набор валит сборку. AIPI_ICON_VARIANTпроброшен через frontend-стадию Dockerfile (ARG по умолчанию teal + ENV) и build-args bot/worker/pool-manager вdocker-compose.yml(${AIPI_ICON_VARIANT:-teal}).
Существующие строки подключения иконок, манифеста и theme-color в HTML не менялись.
- В репозиторий добавлены три готовых набора фавиконов (teal/red/green, по 12 файлов) в
- Настраиваемый текст бейджа dev-инстанса (VITE_DEV_BADGE_TEXT)
Текст красной плашки в правом нижнем углу на тестовом и разработочном стендах теперь задаётся переменной
VITE_DEV_BADGE_TEXT(по умолчанию «ТЕСТ»), поэтому каждый стенд подписывается по-своему. - Настраиваемый PRIVATE_BIND_IP и флаг VITE_DEV_INSTANCE
docker-compose.yml: привязка приватных портов db/redis/redis-transport заменена на${PRIVATE_BIND_IP:-192.168.0.149}; значение по умолчанию сохраняет прежнее поведение на боевом стенде без переменной.- Dockerfile и build-args bot/worker/pool-manager:
VITE_DEV_INSTANCEпробрасывается в web-бандл на этапе сборки; значения «true»/«1» помечают инстанс как dev независимо от хоста (плашка «ТЕСТ» и dev-тема). web/src/utils/devHost.ts: флагDEV_INSTANCE_FLAGлибо прежняя проверка по хосту..env.example: задокументированыPRIVATE_BIND_IPиVITE_DEV_INSTANCE.
- Фавикон AIPi (значок с двумя точками)
Обновлён фавикон AIPi — значок с двумя точками.
- Блокировка песочниц на отдельном сервере (sandbox_blocked)
Основной сервер приложения не должен размещать у себя песочницы, и делать песочницы избыточными за счёт кластеризации не планируется — они остаются обычными серверами. Поэтому главному хосту нужен способ выводиться из размещения песочниц и проектов после того, как система его разгрузит: без перевода в состояние «frozen» (оно означает «на выход» и делает сервер удаляемым) и не затрагивая проекты, которые он уже обслуживает.
Флаг политики —
servers.sandbox_blocked(миграция 005). Заблокированный сервер:- никогда не выбирается целью размещения для НОВОГО проекта (
pickBestServer), а значит, на нём не появляются новые песочницы — песочница живёт на сервере своего проекта; - никогда не выбирается целью для переноса, поэтому проекты с других серверов на него не переезжают;
- не получает новых воркеров (ни автоматически, ни вручную) и пропускается прогревом;
- обнуляет число воркеров в 60-секундном проходе пула, но ТОЛЬКО когда на нём не осталось привязанных проектов: снятие воркеров у сервера, который ещё владеет проектами, их сломало бы. Пул никогда не опустошается: если другого пригодного сервера нет, блокировка остаётся в ожидании.
Проекты, уже привязанные к заблокированному серверу, продолжают работать; флаг не зависит от «frozen» и от права на удаление.
Выбор места размещения теперь идёт через одно общее условие
canAcceptNewPlacement, поэтому очередь, выбор цели для переноса и масштабирование не могут разойтись. - никогда не выбирается целью размещения для НОВОГО проекта (
- Выгрузка резервных копий БД и Redis во внешнее хранилище S3
scripts/s3-upload.py(новый): помощник на boto3, загружает файл в бакет резервных копий. Учётные данные читаются из/etc/aipi/s3-backup.env(доступен только root, в git не попадает). Перезапись идемпотентна.scripts/aipi-backup-db.sh: после проверенного локального дампа — выгрузка в S3 в каталогdb-backups/(локальная копия остаётся основной, S3 — внешняя копия на случай потери сервера).scripts/aipi-backup-redis.sh(новый): BGSAVE → копирование RDB из контейнера → выгрузка в S3 в каталогredis-backups/. Транспортный инстанс необязателен (данные с TTL, самовосстанавливающиеся) и по умолчанию выключен.
- Пул чтения с реплики (READ_DATABASE_URL)
По умолчанию безопасно: без
READ_DATABASE_URLничего не меняется — чтение идёт с основного сервера. Когда управляемая реплика будет готова, установкаREAD_DATABASE_URLдаёт отдельный пул для чтения, чтобы увести тяжёлые SELECT-запросы с основного сервера.config.ts: добавленыdb.readUrl(READ_DATABASE_URL) иConfig.readDatabaseUrl.pool.ts: выделенаwrapPool(); добавленаcreateReadDbPool()(меньший пул с той же обёрткойset_configпо организации, поэтому чтение с реплики остаётся в границах организации)..env.example: задокументированаREAD_DATABASE_URL.