Обзор системы контекста

Система контекста FlowEngine NocoBase разделена на три уровня, каждый из которых соответствует своей области видимости. Корректное использование позволяет гибко разделять и изолировать сервисы, конфигурации и данные, улучшая сопровождаемость и масштабируемость.

  • FlowEngineContext (глобальный контекст): глобально уникален, доступен всем моделям и Flow, подходит для регистрации глобальных сервисов, конфигураций и т.д.
  • FlowModelContext (контекст модели): используется для совместного использования контекста внутри дерева моделей. Подмодели автоматически делегируют в контекст родительской модели, поддерживаются одноимённые переопределения. Подходит для логики уровня модели и изоляции данных.
  • FlowRuntimeContext (контекст выполнения Flow): создаётся при каждом запуске Flow и существует на протяжении всего цикла выполнения. Подходит для передачи данных, хранения переменных и фиксации статуса выполнения внутри Flow. Поддерживает два режима: mode: 'runtime' | 'settings', то есть режим выполнения и режим настроек.

Все FlowEngineContext (глобальный контекст), FlowModelContext (контекст модели), FlowRuntimeContext (контекст выполнения Flow) и т. д. являются подклассами или экземплярами FlowContext.


🗂️ Диаграмма иерархии

FlowEngineContext (глобальный контекст)

├── FlowModelContext (контекст модели)
│     ├── Sub FlowModelContext (подмодель)
│     │     ├── FlowRuntimeContext (контекст выполнения Flow)
│     │     └── FlowRuntimeContext (контекст выполнения Flow)
│     └── FlowRuntimeContext (контекст выполнения Flow)

├── FlowModelContext (контекст модели)
│     └── FlowRuntimeContext (контекст выполнения Flow)

└── FlowModelContext (контекст модели)
      ├── Sub FlowModelContext (подмодель)
      │     └── FlowRuntimeContext (контекст выполнения Flow)
      └── FlowRuntimeContext (контекст выполнения Flow)
  • FlowModelContext может обращаться к свойствам и методам FlowEngineContext через механизм делегирования, обеспечивая общий доступ к глобальным возможностям.
  • FlowModelContext подмодели может обращаться к контексту родительской модели (синхронная связь) через механизм делегирования, поддерживая одноимённые переопределения.
  • Асинхронные parent-child модели не создают делегирующую связь, чтобы избежать загрязнения состояния.
  • FlowRuntimeContext всегда обращается к своему FlowModelContext через делегирование, но не распространяет изменения вверх.

🧭 Режим выполнения и режим настройки

FlowRuntimeContext поддерживает два режима, различаемых параметром mode:

  • mode: 'runtime' (режим выполнения): используется во время фактического выполнения Flow. Свойства и методы возвращают реальные данные. Например:

    console.log(runtimeCtx.steps.step1.result); // 42
  • mode: 'settings' (режим настройки): используется на этапе проектирования и настройки Flow. Доступ к свойствам возвращает шаблонную строку переменной, что упрощает работу с выражениями и выбор переменных. Например:

    console.log(settingsCtx.steps.step1.result); // '{{ ctx.steps.step1.result }}'

Такая двухрежимная архитектура обеспечивает доступность данных в режиме выполнения и удобную генерацию ссылок на переменные и выражения в режиме настройки, повышая гибкость и удобство FlowEngine.


🤖 Контекстная информация для инструментов / больших языковых моделей

В определенных сценариях (например, редактирование кода RunJS в JS*Model, AI-кодинг) необходимо, чтобы «вызывающая сторона» понимала следующее без выполнения кода:

  • Какие статические возможности есть в текущем ctx (документация API, параметры, примеры, ссылки на документацию и т. д.).
  • Какие доступные переменные есть в текущем интерфейсе/состоянии выполнения (например, динамические структуры, такие как «текущая запись», «запись текущего всплывающего окна» и т. д.).
  • Компактный снимок текущей среды выполнения (для prompt).

1) await ctx.getApiInfos(options?) (статическая информация API)

2) await ctx.getVarInfos(options?) (информация о структуре переменных)

  • Построение структуры переменных на основе defineProperty(...).meta (включая meta factory).
  • Поддержка обрезки path и контроля глубины maxDepth.
  • Развертывание вниз только при необходимости.

Часто используемые параметры:

  • maxDepth: максимальный уровень развертывания (по умолчанию 3).
  • path: string | string[]: обрезка, вывод только поддерева по указанному пути.

3) await ctx.getEnvInfos() (снимок среды выполнения)

Структура узла (упрощенная):

type EnvNode = {
  description?: string;
  getVar?: string; // Можно использовать напрямую для await ctx.getVar(getVar), начинается с "ctx."
  value?: any; // Разрешенное/сериализуемое статическое значение
  properties?: Record<string, EnvNode>;
};