0.9.1 5 мая 2026 г.

Белый список ботов Telegram и управление доступом, режимы отправки mid-stream, переключатель поддержки изображений

Возможности Белый список ботов Telegram и управление доступом — Решает проблему «кто угодно, кто найдёт бота, может писать моему Agent». Двухуровневая модель доступа: (1) владельцы workspace на…

Возможности

  • Белый список ботов Telegram и управление доступом — Решает проблему «кто угодно, кто найдёт бота, может писать моему Agent». Двухуровневая модель доступа: (1) владельцы workspace на уровне платформы (accessMode: 'open' | 'owner-only'), (2) доступ на уровне binding с режимами 'inherit' | 'allow-list' | 'open'. Первый пользователь, запустивший /pair в парном супергруппе, автоматически становится владельцем workspace. Перевод бота на owner-only в Настройки → Сообщения → Telegram переключает переключатель workspace и мигрирует все устаревшие binding 'open' в 'inherit', чтобы ни один публичный binding не остался висячим. Новый сворачиваемый «Разрешённые пользователи» (иконка Users) отображает владельцев с элементами управления для удаления; панель «Ожидающие запросы» показывает отправителей, которых шлюз уже отклонил, чтобы оператор мог Разрешить или Разрешить для этого чата (решение на уровне строки, никогда не повышает отклонённые на уровне binding до глобального владельца). Инлайн-кнопки (bind:/perm:/plan:) проходят через тот же оценщик доступа, что и текстовые команды, поэтому не владелец не может обойти шлюз. Отправители ботов молча отбрасываются на уровне платформы. Путь разблокировки находится в контекстном меню платформы (рядом с Reconfigure, только при заблокированном состоянии). Составной ключ хранилища ожидающих запросов (platform, userId, reason, bindingId) разделяет отклонение отправителя на уровне workspace от его отклонений на уровне binding, чтобы каждое можно было разрешить независимо. Закрывает . (fd68c070, aa46043a, 3f4fe418)

  • Поведение отправки mid-stream на уровне соединения (Steer vs Queue) — Новое подменю в Настройки → AI контекстном меню соединения позволяет выбрать, что происходит при отправке ответа во время активного потока. Steer сохраняет текущее поведение (попытки перенаправить новое сообщение в активный turn); Queue завершает текущий turn чисто и воспроизводит отложенное сообщение после onProcessingStopped. У двух режимов разная природа сбоев — эмулируемый steer Claude может выдать steer_undelivered, если ни один tool не срабатывает до конца turn, при этом расходуя токены напрасно; .steer Pi нативен и не имеет такого сбоя. Значения по умолчанию выбираются для каждого провайдера при создании соединения (anthropic → queue, pi/pi_compat → steer) и сохраняются в connection.midStreamBehavior. 4 новых i18n-ключа × 7 локалей. Закрывает часть дискуссий о mid-stream UX. (35a4ca2e, f346035a)

  • Переключатель поддержки изображений на уровне модели в чат-вводе — Подключения с пользовательскими конечными точками (pi_compat) теперь отображают однокликовый переключатель изображений рядом с каждой моделью в выборщике моделей чата. При загрузке изображения, если активная модель разрешает supportsImages !== true, появляется инлайн-баннер предварительной проверки над предварительным просмотром вложения с действием «Включить поддержку изображений». Оба интерфейса используют общие вспомогательные функции (modelSupportsImages / setModelSupportsImages), чтобы не расходиться. Переключатель также отображается в ветке одиночного выборщика (для подключений pi_compat с 0 или 1 моделями + defaultModel). Схема хранилища не изменена — переключает connection.models[i].supportsImages. Встроенные каталоги anthropic / pi остаются принадлежащими SDK и не редактируются из этого интерфейса. Закрывает . (f36c0833, bba2d726, 31ddd5aa)

  • Порог результатов tool_result масштабируется с размером контекстного окна модели — Фиксированный порог 15k-токенов для обработки больших ответов расходовал 25 % контекста на один tool result в модели с окном 64k, и три-четыре умеренных Read/Grep результата могли переполнить даже после автоматической компоновки Pi. Новая вспомогательная функция tokenLimitFor(contextWindow): минимум 2k, максимум 15k, линейная зависимость contextWindow * 0.10 между ними (64k → 6.4k, 128k → 12.8k). Обёртка Pi использует agent.state.model.contextWindow для каждого вызова, чтобы порог отслеживал set_model в течение сессии. ClaudeAgent читает из трекера использования. Устраняет пробел 1 из . (0d3c2796)

Улучшения

  • Согласование i18n в Настройки → Сообщения — Настройки → Сообщения смешивали английские фрагменты в каждую неанглийскую локаль (венгерский показывал «Reconfigure» / «Disconnect» / «Connect» наряду с переведённым текстом), потому что общие глаголы дублировались в пространствах имён платформ и три ключа разрешались через t(..., { defaultValue: ... }) без реальной записи. Добавлено 7 общих глаголов (common.*: configure / connect / disable / disconnect / more / reconfigure / reconnect), переведённых на все 6 неанглийских локалей, заменено 8 точек вызова в MessagingSettingsPage.tsx, удалено 9 избыточных ключей на платформу × 7 локалей (63 ячейки удалено), и жёстко закодированная константа PLATFORM_API_DESCRIPTION маршрутизируется через новые ключи apiType. Добавлено 8 платформенных пробелов, ранее оставленных на английском. Итог: 14–17 непереведённых значений на локаль → 2–5 (оставшиеся только легитимные когнаты, такие как «Region»). Добавление новой платформы больше не требует дублирования переводов глаголов. (bd575ed1)

  • Сортировка файлов локалей — Во всех файлах en/de/es/hu/ja/pl/zh-Hans.json 96 из 1393 ключей на локаль были вне алфавитного порядка — одинаковый порядок подтверждён в прошлых массовых скриптах перевода, которые сохраняли порядок вставки. Новый скрипт scripts/sort-locales.ts (запускается через bun run sort-locales, или bun run lint:i18n:sorted для CI/проверки) нормализует файлы на месте. Хук перед коммитом (scripts/lint-i18n-staged.sh) теперь блокирует коммиты с неотсортированными локалями с подсказкой «Fix: bun run sort-locales», и validate:ci включает ту же проверку. Итог: ноль ключей добавлено/удалено; тестовое покрытие паритета локалей: 58 / 7 → 65 / 0. (3a40b5a5, 3f4fe418)

  • Обновление Pi SDK до 0.72.1 — Обновление @mariozechner/pi-ai, pi-agent-core и pi-coding-agent с 0.70.2 до 0.72.1 во всех четырёх файлах package.json. Удалены теперь устаревшие google-gemini-cli и google-antigravity из PI_EXCLUDED_PROVIDERS. Версия 0.72.0 заменила compat.reasoningEffortMap на модельный thinkingLevelMap; проверено, что buildCustomEndpointModelDef AIKraft не устанавливает ни одно из этих полей, поэтому существующие регистрации пользовательских конечных точек не затрагиваются. Дополнительные исправления: отключены таймауты простоя тела/заголовков undici для длинных потоков (#3715), обработка ошибок конца потока Anthropic (#3936), совместимость DeepSeek V4, поддержка GPT-5.5 Codex, кэшированный websocket-транспорт для OpenAI Codex (#4083). (522a727f)

  • Валидация HTTP MCP больше не запускает подпроцессvalidateMcpConnection ранее запускал полный подпроцесс Claude Code через query SDK, чтобы вызвать mcpServerStatus. На macOS песочница Electron убивала этот подпроцесс SIGKILL до завершения валидации, поэтому каждый HTTP MCP source_test завершался ошибкой, даже если сервер был здоров. Теперь используется CraftMcpClient напрямую (уже поддерживает HTTP-транспорт и выполняет проверку listTools внутри connect); удалены подпроцесс, обмен переменными среды Anthropic, проверка учётных данных Claude и мёртвые поля claudeApiKey/claudeOAuthToken/model из конфигурации валидации. Итог: −231 / +119 строк. Исправляет . (f0a12c4e)

  • Зонд API source учитывает testEndpoint.body и метод; описания tool упрощены — POST-only конечные точки надёжно возвращали 500 из-за пустого тела зонда, потому что настроенное testEndpoint.body и testEndpoint.headers игнорировались. Базовый зонд также теперь учитывает testEndpoint.method вместо танца HEAD→GET-on-405, который молча пропускал POST-only конечные точки. Отдельно, guide.md больше не встраивается в описание API tool при каждом запросе LLM — PrerequisiteManager агента уже вынуждает Read sources/{slug}/guide.md перед любым вызовом api_{slug}, поэтому руководство всегда попадает в историю диалога один раз. Для источников, импортированных из OpenAPI, это экономит десятки КБ на запрос и устраняет раздутие, которое приводило к превышению лимита ретрансляции. (589a51bf)

  • Скрипт IPC-инвентаризации автоматически обновляет снимок тестаscripts/ipc-inventory.ts теперь перезаписывает автоматически сгенерированный блок EXPECTED_CHANNELS в ipc-channels.test.ts на месте, вместо того чтобы просто печатать отчёт миграции. Запускайте после добавления/удаления/переименования любого элемента RPC_CHANNELS. (aa46043a)

Исправления

  • Переключатель supportsImages для пользовательских конечных точек теперь распространяется на живой подпроцесс Pi — Переключение поддержки изображений на уровне модели записывалось на диск, но не достигало работающего подпроцесса Pi, поэтому модель продолжала заменять загруженные изображения на заглушку «(image omitted: model does not support images)». Две причины: getOrCreateAgent блокировал обновление во время выполнения на managed.isProcessing (который sendMessage только что установил в true, сделав ветку обновления мёртвым кодом), и обработчик llmConnections.SAVE не имел пути уведомления для активных сессий. Теперь SAVE запускает push в реальном времени отсоединённо (чтобы сохранение конфигурации не зависело от N × 15s таймаутов сессий), блокировка использует agent.isProcessing только, и per-session agentRefreshLocks мьютекс сериализует параллельные обновления, чтобы agent.chat не запускался против ещё применяемого обновления. Изменения полей, требующие перезапуска (piAuthProvider, slug, маршрутизация аутентификации/провайдера — поля, которые IPC update_runtime_config не может распространить), теперь маршрутизируются напрямую в dispose + recreate через отдельную функцию buildRestartRequiredSignature. (81a6f195, 6c0fec02, ebf01805, f0bbfe96)

  • Переключатель Vision больше не очищает кнопку trigger для строковых моделей — Продвижение строковой записи models: ['gpt-4o'] до объекта через новый переключатель изображений теряло имя модели (нет поля name), поэтому кнопка выборщика отображалась пустой. setModelSupportsImages теперь заполняет name: id, shortName: id при продвижении; защитный fallback m.name ?? stripPiPrefixForDisplay(m.id) на трёх точках отображения выборщика также восстанавливает любые существующие частичные записи из hand-edited config.json. (bba2d726)

  • Изменения метаданных холодной сессии выживают после перезапуска приложенияpersistSession ранее молча пропускал вызов для сессии, сообщения которой ещё не были загружены лениво (состояние после перезапуска для каждой сессии в боковой панели). Изменения статуса / меток / переименования, сделанные до открытия сессии, никогда не записывались на диск и терялись при следующем перезапуске. Холодный путь теперь синхронно гидратирует сообщения + использование токенов из JSONL перед постановкой в очередь — сохраняет исходную цель проверки (не перезаписывать реальные сообщения []), удаляя при этом молчаливую потерю. setSessionLabels теперь асинхронна и ожидает flush, чтобы соответствовать setSessionStatus. (d5a31774)

  • Переполнение контекста Pi+GPT больше не приводит к трём ошибкам — Переполнение контекста Pi+GPT выдавало Codex error: context_length_exceededAuto-compaction failed: undefined is not an objectPi subprocess error: Agent is already processing a prompt в интерфейсе. Три независимые причины: гонка в Pi SDK _runAutoCompaction (отдельный PR в ожидании), дублирующая компоновка в обёртке pi-agent-server handlePrompt, гоняющая с внутренним _runAutoCompaction SDK, и PiEventAdapter, завершающий итератор при каждом agent_end, поэтому восстановленный turn из agent.continue приходил в закрытом итераторе. Теперь: конечный автомат восстановления переполнения (5 состояний: none/held/awaiting/compacting/recovering) в PiEventAdapter держит очередь открытой через поток компоновки → continue SDK с fallback таймаутом 5 секунд; дублирующий путь ручной компоновки в pi-agent-server удалён; таймаут waitForCompaction по умолчанию совпадает с RPC-таймаутом компоновки (60с → 300с); дружелюбное сообщение заменяет сырой стек AbortController до выпуска исправления upstream SDK. (f70d2b56)

  • Browser-pane hide больше не крашится во время загрузки — Слушатель 'close' мог повторно вызвать hide через keepAliveOnWindowClose, и emitStateChange выполнялся синхронно после win.hide, пока Chromium всё ещё завершал работу — особенно критично, когда BrowserView был в процессе загрузки. Итог: чёрный экран при «Hide Window» во время выполнения tool агентом. Добавлена защита isHiding, отложенный callback изменения состояния в микрозадачу, и вызов webContents.stop перед win.hide при активной загрузке. Исправляет . (a4038a28)

  • RoutedClient больше не крашится при синхронном переключении workspaceonConnectionStateChanged вызывает обратный вызов синхронно, когда новый клиент уже находится в состоянии 'connected', поэтому предыдущая форма const unsub = … помещала unsub в TDZ и выбрасывала ReferenceError: Cannot access 'unsub' before initialization. Влияние на производство: любой переход make-before-break, завершающийся на уже подключённом новом клиенте. Переключено на let + optional-chaining, чтобы обратный вызов мог отписаться от самого себя в синхронных и асинхронных случаях. (44f8f001)

Документация

  • Настройка Google OAuth использует тип клиента Web application, а не Desktop app — Вопрос : пользователи, следующие документации, получали redirect_uri_mismatch от Google при использовании рекомендуемого клиента «Desktop app». Новые проекты Google Cloud и рабочие аккаунты с более строгими настройками отклоняют URI loopback для клиентов Desktop app, даже если desktop-поток использует http://localhost:<port>/callback. Тип клиента «Web application» работает в обоих случаях. Обновлено apps/online-docs/source-guides/google-oauth-setup.mdx до единого настройки Web application с обеими URI перенаправления (http://localhost:6477/callback для desktop loopback; https://aikraft.ru/auth/callback для WebUI/headless). (70828cbc, 34521a7d)

  • Документация mid-stream send и переключателя изображений в чат-вводеcore-concepts/interactions.mdx получил раздел «Отправка во время ответа агента», объясняющий режимы Steer vs Queue, индикатор Queued и per-backend defaults. reference/config/llm-connections.mdx добавил поле midStreamBehavior в таблицу схемы. reference/config/custom-endpoint.mdx документирует переключатель поддержки изображений в чат-вводе для подключений pi_compat. (f346035a, 31ddd5aa)

Несовместимые изменения

  • Нет. Работа с управлением доступом в Telegram автоматически мигрирует устаревшие binding 'open' в 'inherit' при блокировке workspace — никаких ручных настроек не требуется. connection.midStreamBehavior возвращается к per-provider default для соединений, созданных до этого выпуска.

Примечания

  • Бот, предварительно спаренный с workspace, не будет иметь владельцев, пока не будет выполнена следующая команда /pair, в момент которой первый пользователь автоматически становится владельцем. Чтобы проверить текущее состояние из интерфейса, откройте Настройки → Сообщения → Telegram и проверьте сворачиваемый «Разрешённые пользователи».
  • Новый bun run sort-localesbun run lint:i18n:sorted в CI) заменяет ad-hoc ручную сортировку локалей. Если вы вносите переводы, добавьте новый ключ в любое место файла и запустите скрипт сортировки перед коммитом — хук перед коммитом заблокирует коммит с неотсортированными локалями.
  • Обновление Pi SDK до 0.72.1 внутреннее — никаких изменений конфигурации не требуется. Если вы ранее настраивали google-gemini-cli или google-antigravity (оба удалены upstream), эти записи больше не распознаются.

← Все версии