Что изменилось
Из SDK ничего не удалено и не переименовано — все методы, что работали раньше, работают с теми же сигнатурами. Изменилось где лежит значение и что читает платформа. Если ваше расширение только регистрирует команды, ноды или вебвью, беспокоиться не о чем. Если оно читает или пишет значения портов и параметров, необходимую информацию вы найдёте в этом разделе..
Значение теперь хранится в одном из четырёх слотов
Порт данных и параметр класса раньше хранили значение в одном месте — defaultValue, и все писали в него: автор узла в схеме, пользователь в инспекторе, запуск со своим результатом. Теперь это четыре отдельных слота:
| Слот | Кем записывается | Сохраняется в проекте |
| --- | --- | --- |
| defaultValue | автор node, в schema.json | нет — приходит из schema каждый раз |
| value | человек, в inspector | да |
| template | человек, в режиме выражения | да |
| resolved | запуск | нет |
Чтение подчиняется одному правилу: resolved → value → defaultValue,используется первое, что существует.
// самостоятельное чтение снимка
const current = port.template ?? port.value ?? port.defaultValue
// или разрешите платформе применить правило
const effective = await sdk.project.nodeEditor.getPortValue(nodeId, portKey)
getPortValue ведёт себя как и раньше — возвращает действующее значение. Обновлять нужно только прямые чтения snapshot.defaultValue.
Результаты запусков больше не сохраняются в файл проекта
setNodeOutputs и setNodesOutputs пишут в слот resolved, а не в defaultValue. Из этого два следствия:
- запуск больше не помечает проект как изменённый, и его результаты в него не сохраняются в проекте;
- расширение, которое читало результаты запуска из
snapshot.defaultValue, не обнаружит там данных. Читайте их черезgetPortValueили храните в собственном хранилище — именно так и поступает оркестратор, проходя по графу.
Проекты мигрируют при загрузке
В старом проекте выражения лежат в defaultValue — поле раньше хранило их именно там. При загрузке такого проекта, любой порт данных, у которого defaultValue представляет собой целую{{…}}, а value и template оба пустые, переносит этот текст в template, а defaultValue очищается.
Именно это заставляет поле открыться в режиме выражения, а не показывать фигурные скобки как литерал, — и это же изменениеЮ чаще всего будет проблемой для кода, который ждал выражение в defaultValue.
Что проверить в своём расширении
- Любое чтение
defaultValue— заменить наtemplate ?? value ?? defaultValueили наgetPortValue. - Любое чтение результатов запуска из снапшота — они теперь хранятся в
resolvedи в снапшот не попадают. - Поиск ноды по имени: созданные и продублированные ноды получают уникальное имя (
Fetch Users,Fetch Users 2, …), поэтому поиск поdisplayNameсразу после создания может не сработать. Используйте полученныйNodeId. - Нода с именем
creds— имя зарезервировано под секреты в выражениях и получает суффикс. - Определения нод, которые не проходили валидацию:
schema.jsonс ошибкой теперь отображается как проблема с указанием пути к файлу и текстом ошибки, а не исчезает из панели со строчкой в логе. Ничего не сломалось — это просто стало видимым.
Что вы можете внедрить
Всё перечисленное необязательно: нода или расширение, которые ничего из этого не объявили, ведут себя так же, как и раньше.
contributes.expressionProvidersиsdk.expressions— свой язык выражений в полях, с подсказками и диагностикой, которые рисует платформа.setNodeInputsResolved— сообщить из запуска, чем обернулось выражение; редактор покажет это под полем.- Схемы выходов — объявить, что лежит внутри
objectилиarray, чтобы подсказки шли глубже одного уровня. - Зависимые параметры —
dependsOn,visibleWhen,disabledWhen,requiredWhen,resetWhenMissingи провайдеры вариантов, которые платформа исполняет прямо из schema.
Разобранный пример всего пути — грамматика, подсказки, DSL из графа, запуск, возвращающий значения в поля — лежит в extensions/example-workflow.