Features
- GPT-5.5 теперь используется по умолчанию для
openaiиopenai-codex— Pi SDK 0.70.0 добавилgpt-5.5в каталог OpenAI, поэтомуPI_PREFERRED_DEFAULTSтеперь выбирает его в качестве модели по умолчанию для обоих провайдеров аутентификацииopenaiиopenai-codexвместо первой возвращённой SDK. Новые подключения с API-ключом и подключения AIKraft Agents Backend (OpenAI) сразу используютgpt-5.5; существующие подключения сохраняют явный выбор модели. Исправляет . - DeepSeek теперь поддерживается как провайдер на базе Pi — Добавлен DeepSeek в
PROVIDER_METADATA(URL панели),PI_PROVIDER_DISPLAY(метка + placeholder) иPI_PREFERRED_DEFAULTS(deepseek-v4-pro/deepseek-v4-flash), чтобы подключения по умолчанию использовали современную модель вместо первой возвращённой Pi SDK. Рендерер автоматически подхватывает нового провайдера черезPI_AUTH_PROVIDER_DOMAINS(deepseek.com) для разрешения favicon, пресет настройки API и метку на странице настроек. CLI получил ключDEEPSEEK_API_KEYи вынесresolveApiKey,shouldSetupLlmConnectionиgetProviderDisplayNameв тестируемые экспорты; авто-настройка--base-urlтеперь работает для не-антропических провайдеров, а этап валидации использует тот же путь резолвера. Исправляет .
Improvements
source_testтеперь автоматически включает и перезапускает ход, чтобы инструменты становились доступными сразу — Ранееsource_testтолько проверял источник; пользователи с действительной конфигурацией, ноenabled: false, должны были вручную переключить флаг и перезапустить сессию, даже если все проверки прошли. Инструмент теперь устанавливаетenabled: trueпри необходимости и вызывает существующий в сессии коллбэкonSourceActivationRequest, чтобы MCP/API-серверы были созданы и применены к работающему агенту. Вспомогательное исправление (в этом выпуске) маршрутизирует успешную активацию через ту же инфраструктуруsource_activated+auto_retry, которая уже обрабатывала ошибки "инструмент не найден на неактивном источнике": после активации текущий ход чисто завершается, а рендерер повторно отправляет исходное сообщение пользователя с суффиксом[{slug} activated]— чтобы следующийquery/handlePromptполучил свежий список инструментов с активированным источником. Это исправляет ошибку, специфичную для Claude, при которойsource_testсообщал "инструменты теперь доступны", но SDK уже заморозилmcpServersна этапе запуска запроса, поэтому инструментыmcp__{slug}__*были невидимы для модели, пока пользователь не ввёл ещё одно сообщение. Pi ведёт себя так же для согласованности (и также требовал границы хода — его подпроцесс принимает новые определения прокси-инструментов только на следующемhandlePrompt). Отключить можно с помощьюautoEnable: false, чтобы сохранить чистое поведение валидации. Нет изменений для Codex или других бэкендов без коллбэка активации — они всё равно получают установкуenabledи понятное сообщение "перезапустите сессию для загрузки инструментов".spawn_sessionпринимаетthinkingLevel— Агенты теперь могут устанавливать уровень рассуждений при делегировании в спауненную сессию (off|low|medium|high|xhigh|max), вместо того чтобы всегда наследовать уровень родительской сессии или workspace по умолчанию. Параметр безопасно игнорируется на не-рассуждающих моделях (например, gpt-4o, gemini-2.5-flash): драйверы Pi и Claude SDK оба ограничивают параметр рассуждений возможностями модели, поэтому передачаthinkingLevelне-рассуждающей модели является безопасной заглушкой, а не ошибкой. Также исправляет скрытую ошибку, при которойcreateSession({ thinkingLevel })в API менеджера сессий тихо игнорировался — опция теперь учитывается с приоритетом вызывающий → workspace → глобальный, как уже работало сpermissionMode. Исправляет .- Настоящий типизированный контроль для
pi-agent-server— Скриптtypecheckпакета был перенаправлен наbun run build(бандлер, а неtsc), поэтому отклонения формы API от Pi SDK пропускались в CI (см. конкретную регрессию ниже в исправлении регистрации инструментов подпроцесса Pi). Добавлен выделенный шагtsc --noEmit -p tsconfig.typecheck.json, подключённый вtypecheck:all, а также амбиентные заглушки для turndown/pdfjs-dist/bash-parser, чтобы новый типизированный контроль не требовал @types-пакетов. Исправлены каскады существующих отклонений типов, которые он выявил (PiCredentialvsAuthCredential, форма событияagent_end, обогащениеsdkTurnAnchor,CustomModelEntryна динамическом сайте регистрации,initConfignullability в замыканиях queryLlm и неверный обобщлённый тип в помощникеresultweb-fetch).
Bug Fixes
- WebUI "Добавить новую метку" больше не запускает настольное приложение — Ввод
#<new-label>в чате WebUI и клик на "Добавить новую метку" ранее открывал popover, который при отправке запускал deep linkcraftagents://action/new-session. Браузер разрешал эту схему, запуская Electron-приложение вместо создания метки в браузере. Причина: точка вызова чат-ввода cherry-picked поля из конфигурации EditPopover и упустилаinlineExecution: true, возвращаясь к устаревшему пути deep-link в том же окне (который работал внутри Electron, но ломался на границе WebUI ↔ ОС). Переключено на полное распространение конфигурации, как уже делаетAppShellс тем же popover. - Вложения больше не просачиваются между сессиями (в этот раз серьёзно) — Прикрепление файла, переключение сессий без отправки и возврат теперь восстанавливают вложение в исходной сессии по всем четырём путям (файловый выбор, OS drag-drop, clipboard paste, web drag). Первичное исправление предполагало, что у каждого вложения есть реальный путь в ОС — верно для Finder drag/OS picker, неверно для paste/web-drag, где Chromium синтезирует
Fileиз Blob без диска-источника — поэтому ссылки на черновики возвращались к значениям только с именем файла и не могли быть прочитаны при гидратации. Новый слой сохранения гибридный: файловый выбор и OS-drag захватывают абсолютный путь черезwebUtils.getPathForFile(Electron 32+) и читают его при гидратации через выделенный RPCfile:readUserAttachment; paste и web-drag сохраняют байты внутри черновика (лимит 20 МБ на вложение — огромные вставки логируют предупреждение и удаляются из черновика). Старые черновики формата 0.8.11 отклоняются при загрузке, поэтому вложения, сохранённые предыдущей сломанной версией, исчезнут один раз после обновления вместо того, чтобы навсегда преследовать композер. Исправляет . - Ссылки на пользовательские URL-схемы теперь открывают нужное приложение — Клик по ссылкам
obsidian://,vscode://,zed://,notion://,slack://и аналогичным в сообщениях чата теперь направляет их в OS-обработчик протокола вместо блокировки (настольная версия) или перезаписи вhttps://<host>/obsidian://...(WebUI). Обработка URL переключена с строгого allowlist (http/https/mailto/craftdocs) на blocklist известно опасных схем (javascript:,data:,vbscript:,blob:,file:). WebUI и Viewer теперь используют fallback на клик по anchor для не-http схем, чтобы Chrome надёжно маршрутизировал через диспетчер внешних протоколов. Исправляет . /compactбольше не превышает таймаут на GPT-сессиях — Ручная компоновка (включая "Принять и компоновать" для отправленного плана) против Pi-поддерживаемых моделей OpenAI завершалась ошибкой через 60 секунд, потому что RPC подпроцесса не оставлял места для длинных ответов GPT-5.4 на больших диалогах. Таймаут увеличен до 5 минут — действительно зависшие подпроцессы всё ещё обнаруживаются watchdog'ом stdio death. Сессии Claude не затрагиваются (они используют встроенный канал compact SDK).- Регистрация инструментов подпроцесса Pi восстановлена — Pi SDK 0.70.0 тихо изменяла форму
CreateAgentSessionOptions.toolsс массива объектов инструментов наstring[]allowlist имён. Подпроцесс продолжал передаватьAgentTool[], поэтому при выполненииallowedToolNames = new Set(objects)и.has(name)возвращалfalseдля каждого поиска — каждый пользовательский инструмент был отфильтрован защитой allowlist в_refreshToolRegistry, оставляя LLM только встроенными[read, bash, edit, write]. Исправление теперь маршрутизирует объекты инструментов черезcustomTools: ToolDefinition[]с соответствующимtools: string[]allowlist, включающим каждое зарегистрированное имя, удаляет частный хак защиты_baseToolsOverride + _buildRuntimeи восстанавливаетgrep/find/ls, которые в последний раз были собраны до 0.68 в монолитном массивеcodingTools. Тест регрессии теперь фиксирует контракт формы (каждоеcustomTools[].name∈ allowlisttools), чтобы следующее обновление SDK не могло молча удалить инструменты. call_llmPi теперь использует запрошенную модель —queryLlmмаршрутизировалcall_llmчерез RPCmini_completion, который несёт толькоprompt. Каждыйcall_llmтихо работал на mini-модели подключения (часто устаревшейpi/gpt-5.1-codex-mini), игнорируяrequest.modelиrequest.systemPrompt. Введён новый RPCllm_query, несущий полныйLLMQueryRequest; подпроцесс делегирует его дословно модельно-осведомлённомуqueryLlm.PiAgent.queryLlmотслеживает отложенные запросы в карте с очисткой при результате / общей ошибке / выходе подпроцесса, и переопределение событияcall_llmв адаптере теперь заполняетargs.modelтолько при отсутствии значения (никогда не перезаписывает явные значения). Тест инварианта round-trip проверяет полный конверт запроса побайтово. Исправляет .- Mini-дополнения Pi выбирают модель, подходящую для провайдера —
handleMiniCompletionзавершался ошибкой "No API key found for openai." для пользователей ChatGPT Plus / openai-codex / google / github-copilot, когда подключение не имело явногоminiModel. Fallback проверки провайдера вqueryLlmвсегда назначалgetDefaultSummarizationModel(Haiku), который разрешается только под anthropic auth — Pi SDK 0.70.0 по умолчанию тогда тихо отображалась как OpenAI-модель, и вводящее в заблуждение auth-сообщение всплывало. Новый помощникpickProviderAppropriateMiniModelпроходит поPI_PREFERRED_DEFAULTS[authProvider]в поисках разрешимого, не-отклонённого кандидата (anthropic явно сохраняется, чтобы сохранить Haiku как mini-модель по умолчанию), иrunQueryWithModelтеперь быстро завершается с понятным сообщением, если модель не разрешена. - Композер больше не крашится на искажённых черновиках — Защита чат-ввода от ненадёжного содержимого черновика: рендерер теперь принудительно преобразует текст черновика на границе,
RichTextInputзащищён от не-строковых значений, и область ввода заворачивается в локальный error boundary с действиями восстановления, чтобы плохой черновик не мог унести всё окно. Интерфейс fallback локализован и проходит проверку i18n. - Чистые блоки
@@теперь отображаются как rich PatchDiff — Нормализация диффов перенесена в чистую функцию и сделана устойчивой для трёх форм, которые ранее проходили мимо syntax-highlightedCodeBlockвместо просмотрщика диффов pierre: чистые строки маркеров@@, валидные нумерованные ханки без заголовков файлов и уже-валидные unified/git-патчи (сейчас сохраняются побайтово). Путь синтеза сохраняет заголовки файлов пользователя при наличии, чисто удаляет маркеры ханков без оставления пустых контекстных строк и считает строки тела без путаницы с действительными---/+++строками удаления/добавления с заголовками.
Dependency Changes
- Pi SDK обновлен до 0.70.2 —
@mariozechner/pi-{coding-agent,agent-core,ai}обновлены в root,pi-agent-server,server-coreиshared. Шаг 0.66.1 → 0.70.0 заменил удалённый экспортcodingToolsна фабрикуcreateCodingTools(cwd)и изменял формуCreateAgentSessionOptions.tools(см. исправление регистрации инструментов подпроцесса Pi выше). Шаг 0.70.0 → 0.70.2 — патч-обновление без изменений API-поверхности, используемой нашим кодом. (См. запись о GPT-5.5 в Features выше для изменения модели по умолчанию, включённого 0.70.0 каталогом.) - Claude Agent SDK зафиксирован на точном 0.2.111 — Раннее обновление 0.2.111 → 0.2.119 сломало сессии Claude с ошибкой "Claude Code SDK not found". Начиная с 0.2.113 SDK заменил JS-входной точку
cli.jsна платформенно-специфичные нативные бинарники (@anthropic-ai/claude-agent-sdk-{platform}-{arch}), которые наш runtime resolver, build-скрипты, CI verify-bundles шаги и unified network interceptor на основе--preloadвсе предполагают, что не существует. Зафиксировано на последнюю JS-версию и сужены peer-dep диапазоны с^0.2.19/>=0.2.19до точного0.2.111, чтобы следующее изменение не могло приземлиться как тихий патч. Полный переход на нативные бинарники (перемещение interceptor) отслеживается отдельно.
Breaking Changes
- Нет.
source_testобратно совместим;autoEnableпо умолчаниюtrue, но предыдущий вывод валидации является строгим подмножеством нового вывода. ПередайтеautoEnable: false, чтобы точно воспроизвести старое поведение.spawn_sessionполучает необязательное поле — существующие вызовы не затрагиваются.