ai 26.1100.0 Заметное

AI 26.1100.0: срок жизни задачи очереди ИИ-запросов задаётся на запрос

4 мин чтения

В модуле ai коробочного Битрикс24 версии 26.1100.0 срок жизни задачи очереди ИИ-запросов больше не зашит в четыре часа. Его задают на запрос через Engine::setQueueJobTtl(), момент истечения пишется в новую колонку b_ai_queue.EXPIRE_DATE, а просроченную задачу QueueJob::createFromHash() теперь проваливает и удаляет сам. Ещё установщик переехал с SQL-скриптов на миграции ядра, и появилась заготовка триггера перезапуска ИИ-агентов.

В коробку версия вышла 14 сентября 2026 года, по данным официального канала «Битрикс24 changelog». Читать стоит тем, кто шлёт ИИ-запросы из своего кода через Engine или достаёт задачи очереди по хешу.

Что может сломаться

Удалённых и несовместимо изменённых публичных сигнатур нет, новых @deprecated тоже, в API добавились только новые методы и необязательные параметры. Сломать ваш код может изменившееся поведение.

Проверьте вызовы createFromHash()

Раньше QueueJob::createFromHash() (lib/QueueJob.php) отдавал задачу любого возраста, а старые задачи чистил только агент clearOldAgent(). Теперь у метода сигнатура createFromHash(string $hash, bool $allowExpired = false), и просроченную задачу он по умолчанию не отдаёт.

Просроченной считается задача, у которой EXPIRE_DATE в прошлом. Если EXPIRE_DATE равен NULL, срок считается от DATE_CREATE плюс DEFAULT_TTL, то есть 14400 секунд, четыре часа. Для такой задачи метод возвращает null и сам вызывает приватный expire(). Тот удаляет строку, шлёт backend- и frontend-события провала с ошибкой HASH_EXPIRED и откатывает списание лимита. Просроченную «битую» строку, у которой не распаковались движок или payload, метод удаляет сразу.

Колбэки в ядре ведут себя по-разному. Колбэки успеха передают allowExpired: true и принимают поздний результат, пока строка существует. Это callbackBodyAction в lib/controller/queue.php и callbackSuccessAction в lib/controller/integration/b24cloudai.php и thirdparty.php. Колбэки ошибок (callbackErrorAction в тех же файлах) зовут метод со значением по умолчанию, так что просроченную задачу провалит и удалит сам createFromHash().

Если вы вызываете createFromHash() в своём коде, проверяйте null и учитывайте, что сам вызов теперь может удалить задачу и разослать событие провала. Если нужен поздний результат, как в колбэках успеха, передавайте allowExpired: true.

getTTL() больше не константа

Приватную константу TTL_SECONDS = 14400 заменили две публичные, QueueJob::DEFAULT_TTL = 14400 и QueueJob::MAX_TTL = 86400. getTTL() теперь возвращает TTL конкретной задачи. У задачи, загруженной из БД, это разница EXPIRE_DATE − DATE_CREATE, а если EXPIRE_DATE пуст, DEFAULT_TTL. Если ваш код считал, что задача всегда живёт четыре часа, берите срок из getTTL().

QueueJob::createWithinFromEngine(IEngine $engine, ?int $ttl = null) получил необязательный TTL. Он и Engine::setQueueJobTtl() бросают \InvalidArgumentException, если значение меньше единицы или больше 86400.

could_not_lock стал ошибкой провайдера

Ответ с кодом could_not_lock теперь считается ошибкой провайдера (lib/Engine/Engine.php, QueueJob::fail()). Пользователь получит AI_ENGINE_ERROR_PROVIDER, как на коды 100 и от 500 и выше. Для кода завели константу Engine::ERROR_CODE_COULD_NOT_LOCK = 'could_not_lock'.

Задайте срок жизни своему запросу

Engine::setQueueJobTtl(int $ttl): static задаёт время жизни задачи очереди для конкретного запроса, getQueueJobTtl(): int его возвращает (по умолчанию QueueJob::DEFAULT_TTL). Engine и ThirdParty (lib/Engine/ThirdParty.php) передают это значение в QueueJob::createWithinFromEngine(), а QueueJob::register() записывает в EXPIRE_DATE момент «сейчас + TTL». Потолок — MAX_TTL, сутки. Срок выставляйте до отправки запроса, потому что createWithinFromEngine() получает его при постановке задачи в очередь.

Метод бросает исключение на недопустимом значении, так что в сервисе его удобно обернуть в Result:

        <?php declare(strict_types=1);

namespace Vendor\Assistant\Application\Service;

use Bitrix\AI\Engine\Engine;
use Bitrix\AI\QueueJob;
use Bitrix\Main\Error;
use Bitrix\Main\Loader;
use Bitrix\Main\Result;

final class AiQueueTtlService
{
    public function __construct()
    {
        Loader::requireModule('ai');
    }

    public function apply(Engine $engine, int $ttlSeconds): Result
    {
        $result = new Result();

        try {
            $engine->setQueueJobTtl($ttlSeconds);
        } catch (\InvalidArgumentException) {
            return $result->addError(new Error(
                sprintf('TTL задачи должен быть от 1 до %d с, передано %d', QueueJob::MAX_TTL, $ttlSeconds),
                'AI_QUEUE_TTL_OUT_OF_RANGE',
            ));
        }

        return $result->setData(['ttl' => $engine->getQueueJobTtl()]);
    }
}

    

Не стройте процессы на триггере перезапуска ИИ-агентов

В модуле появилась активити бизнес-процессов aiagentrestarttrigger (install/activities/bitrix/aiagentrestarttrigger/). Это триггер CBPAiAgentRestartTrigger extends \Bitrix\Bizproc\Activity\BaseTrigger в группах STARTER и AI, секция AI_AGENT. Он возвращает restartRunId, previousRunId, initiatorId (в виде user_N), timestamp и runType (по умолчанию restart), а runType и restartRunId дублирует в переменные процесса. Триггер скрыт, если опция feature_ai_agents модуля bizproc не задана или равна N, а также если NodeAvailabilityServiceInterface не зарегистрирован в ServiceLocator или сообщает, что узел недоступен.

Параметры события тоже расширили. В enum ProcessedEvent появилось OnAiAgentRestart. Конструктор AiListenerParameters получил необязательные agentInstanceId, restartRunId, previousRunId, initiatorId, timestamp и runType = RUN_TYPE_INITIAL. В классе появились константы KEY_AGENT_TEMPLATE_ID, KEY_AGENT_INSTANCE_ID, KEY_RESTART_RUN_ID, KEY_PREVIOUS_RUN_ID, KEY_INITIATOR_ID, KEY_TIMESTAMP, KEY_RUN_TYPE, RUN_TYPE_INITIAL и RUN_TYPE_RESTART. toArray() добавляет новые ключи, только когда runType === 'restart'.

Отправлять событие пока некому. В коробочном Битрикс24 с этой версией OnAiAgentRestart в bitrix/modules встречается только в enum ProcessedEvent, а параметры перезапуска есть только в AiListenerParameters. Сервис SystemTemplateActivationService в bizproc (lib/Internal/Service/AiAgentGrid/) отправляет только OnAiAgentStart. Bizproc запускает триггеры по коду (Starter::addEvent(code: 'AiAgentStartTrigger', …) для старта), а код AiAgentRestartTrigger вне папки самой активити не встречается, так что процесс на новом триггере пока не запустится.

БД: проверьте колонку EXPIRE_DATE

Установщик переехал на миграции ядра. Файлы install/db/mysql/install.sql, uninstall.sql и их пары в install/db/pgsql/ удалены. Вместо них появились install/migrations/tables.php на построителе Bitrix\Main\UpdateSystem\Migration, events.php и agents.php. В install/index.php installDB() вызывает installMigrations(), а uninstallDB() вызывает uninstallMigrations($dropTables). Из 1349 удалённых строк релиза 908 приходятся на эти SQL-скрипты.

tables.php создаёт те же 31 таблицу, что и старый install.sql. По именам колонок и индексов новая схема отличается от MySQL-скрипта только в b_ai_queue, где добавились колонка EXPIRE_DATE datetime и индекс IX_B_EXPIRE_DATE.

Как колонка появится на уже установленных порталах, из кода модуля не видно, потому что скрипт обновления в папке модуля не остаётся. Комментарий в QueueJob::clearOldAgent() упоминает «interrupted updater backfill». Код везде готов к EXPIRE_DATE = NULL и тогда считает срок от DATE_CREATE + DEFAULT_TTL. На MySQL после обновления проверить колонку и индекс можно так:

        SHOW COLUMNS FROM b_ai_queue LIKE 'EXPIRE_DATE';
SHOW INDEX FROM b_ai_queue WHERE Key_name = 'IX_B_EXPIRE_DATE';

    

Из install/index.php ушли ручные registerEventHandler, CAgent::AddAgent, CAgent::removeModuleAgents('ai') и приватные методы configureBoxBitrixGptFeatures() и getConnectionType(). Агентов при удалении модуля снимает ModuleManager::unRegisterModule() из main. Руками отписывается только старый обработчик PublicAgreement::onPageStart, рядом в коде комментарий «legacy cleanup».

agents.php ставит агентов по окружениям с теми же интервалами, что были в index.php:

  • везде: QueueJob::clearOldAgent (раз в 120 с), Updater::refreshDbAgent (раз в 3600 с), PropertiesSync::retrieveModelsAgent (раз в 86400 с);
  • в облаке (BX24_HOST_NAME): EngineSettings::resetToBitrixAudioInCloudAgent, resetToBitrixGPTInCloudAgent, enforceEngineBaselineAgent, раз в час, первый запуск через 600, 600 и 3600 с, как раньше;
  • в коробке: resetFollowUpTextStepsToBGPTAgent и resetFlowsToBGPTAgent, раз в час, первый запуск через 600 с.

Мелочи и находки

  • Внутреннее JS-расширение ai.roles-dialog (install/js/ai/roles-dialog/src/) переделали. Глобальные события EventEmitter update и update-complete убраны вместе с перезагрузкой диалога после закрытия слайдера библиотеки ролей. Перед открытием библиотеки диалог теперь закрывается (this.hide()), аналитику open_list отправляет сам RolesDialog. components/roles-dialog-roles-library.js экспортирует фабрику getRolesDialogRolesLibrary(onOpenRolesLibrary) вместо объекта RolesDialogRolesLibrary, а getRolesDialogEmptyGroupStubWithStates() получил второй параметр onOpenRolesLibrary. Если вы подписывались на update или update-complete снаружи, эти обработчики больше не вызовутся.
  • Приватный QueueJob::tryDelete() удаляет строку сырым DELETE FROM ?# WHERE ID = ?i через SqlExpression и проверяет getAffectedRowsCount(). События провала и откат лимита отправляет только тот запрос, который действительно удалил строку. Почему не ORM, сказано в комментарии: «ORM delete() gives no affected-rows contract». Так закрыта гонка между поздним колбэком и тиком агента.
  • Комментарий у Engine::ERROR_CODE_COULD_NOT_LOCK требует, чтобы значение совпадало с Bitrix\AiProxy\Controller\Query::ERROR_CODE_COULD_NOT_LOCK. Модуля aiproxy в коробочном Битрикс24 нет, это серверная сторона облачного прокси.
  • Агенты EngineSettings::resetToBitrixGPTInCloudAgent() и resetToBitrixAudioInCloudAgent() теперь возвращают __METHOD__ . '();', то есть имя без ведущего обратного слэша. Раньше возвращалось '\Bitrix\AI\Agents\EngineSettings::…'. В коробке это не заметно, agents.php ставит их только в облаке.
  • В install/migrations/agents.php среди английских комментариев затесался один русский. В нём сказано, что legacy-вызов PropertiesSync без интервала переведён в явные 86400 с, «поведение сохранено (подтверждено verify-харнессом)».
  • В lib/Payload/Formatter/StatementTrait.php и UserMarkers.php перед mb_strtolower() и str_replace() добавили приведение к (string). EngineSettingsService теперь пропускает пустой или нестроковый код движка.
  • VERSION_DATE в install/version.php ровно 2026-07-21 12:00:00, а в коробку версия вышла 14 сентября.
  • 20 JS/CSS-файлов в install/js/ai/copilot/ значатся в статистике с нулём строк. У них сменились только права, 100755 → 100644.

Что делать

  • Найдите в своём коде createFromHash(. Проверяйте null, а если нужен поздний результат, передавайте allowExpired: true.
  • Если вы рассчитывали на фиксированные четыре часа, берите срок задачи из getTTL(), а свой задавайте через Engine::setQueueJobTtl() в пределах 1–86400 секунд.
  • После обновления проверьте, что в b_ai_queue есть колонка EXPIRE_DATE и индекс IX_B_EXPIRE_DATE.
  • Уберите подписки на события update и update-complete из ai.roles-dialog, если они у вас были.
  • Триггер aiagentrestarttrigger в шаблоны пока не ставьте, событие OnAiAgentRestart никто не отправляет.

Читайте дальше

voximplant 26.700.0 Ломающее Свежее

Voximplant 26.700.0: оценку качества связи убрали, у notifyAdmins() появился тип

Модуль телефонии voximplant 26.700.0 вышел в коробочный Битрикс24 11 сентября 2026 года, по данным официального канала «Битрикс24 changelog». Из карточки звонка убрали оценку качества связи вместе с её JS-событиями, у `Im::notifyAdmins()` появился тип параметра, а публичные константы `SipStatusInfor...

3 мин
ui 26.687.0 Рутинное Свежее

UI 26.687.0: триал VibePlus в облаке и дизайн чипа TintedBitrixGpt

`Bitrix\UI\Controller\InfoHelper` при активации демо сначала спрашивает у модуля bitrix24, включён ли старт VibePlus, и если да, запускает триал VibePlus вместо обычного демо тарифа. Ветка срабатывает только при подключённом модуле bitrix24 и определённой константе `BX24_HOST_NAME`. В `ui.system.chi...

1 мин
ui 26.675.0 Ломающее Свежее

UI 26.675.0: ui.actionpanel переехал в бандл, а rich_text по-новому обходится с квадратными скобками

Модуль ui 26.675.0 собран 26 августа 2026. Из PHP поменялись `Converter` и `Whitelist` в `Bitrix\UI\Format\BBCode`, и пользовательские поля типа `rich_text` теперь иначе сохраняют и индексируют текст с квадратными скобками. На фронтенде старую панель групповых действий `ui.actionpanel` перевели на б...

4 мин
ui 26.650.0 Рутинное Свежее

UI 26.650.0: клавиатура в пикере реакций и аудио во вьюере

Релиз на 2 МБ, из PHP в нём только `config.php` расширений и номер версии. Пикером реакций теперь можно управлять с клавиатуры (роль `menu`, стрелки, Escape), у него появились опции `priorityReaction` и `contextAction` и методы `focus()` и `destroy()`. Если пикер привязан к кнопке, ссылке или элемен...

1 мин
Мы используем файлы cookie для улучшения работы сайта. Продолжая использовать сайт, вы соглашаетесь с нашей политикой конфиденциальности.
AI Домовой

AI Домовой История

на связи

пишет…
Нет истории чатов
AI Домовой

Нужна авторизация

Войдите, чтобы задавать вопросы AI Домовому.

Войти