Ver Fonte

feat(docs): runtime docs (#493)

Louis Young há 6 meses atrás
pai
commit
d3d73efe70

+ 5 - 0
apps/docs/src/en/guide/_meta.json

@@ -15,5 +15,10 @@
     "type": "dir",
     "type": "dir",
     "name": "concepts",
     "name": "concepts",
     "label": "Concepts"
     "label": "Concepts"
+  },
+  {
+    "type": "dir",
+    "name": "runtime",
+    "label": "Runtime (WIP)"
   }
   }
 ]
 ]

+ 5 - 0
apps/docs/src/en/guide/runtime/_meta.json

@@ -0,0 +1,5 @@
+[
+  "introduction",
+  "quick-start",
+  "source-code-guide"
+]

+ 155 - 0
apps/docs/src/en/guide/runtime/introduction.mdx

@@ -0,0 +1,155 @@
+---
+title: Introduction
+description: Basic concepts and design principles of FlowGram Runtime
+sidebar_position: 2
+---
+
+# Introduction to FlowGram Runtime
+
+**⚠️ FlowGram Runtime is currently in early development stage, and only supports nodejs runtime, and only work in free layout.**
+
+This document introduces the basic concepts, design principles, and core features of FlowGram Runtime to help business integration developers understand and use this reference implementation of a workflow runtime engine.
+
+## What is FlowGram Runtime
+
+FlowGram Runtime is a reference implementation of a workflow runtime engine, designed to provide runtime reference for business developers. It can parse and execute graph-based workflows, supporting various node types including Start, End, LLM, Condition, Loop, and more.
+
+### Project Positioning and Goals
+
+FlowGram Runtime is **positioned as a demo rather than an SDK**, with the following main goals:
+
+- Provide design and implementation reference for workflow runtimes
+- Demonstrate how to build and extend workflow engines
+- Offer code that developers can directly learn from and modify
+- Support rapid prototyping and proof of concept
+
+As a reference implementation, FlowGram Runtime will not be published as a package. Developers need to fork the repository and modify it according to their specific business scenarios and requirements.
+
+## Core Concepts
+
+### Workflow
+
+A workflow is a directed graph composed of nodes and edges, describing the execution order and logical relationships of a series of tasks. In FlowGram Runtime, workflows are defined in JSON format, containing nodes and edges.
+
+Example workflow definition:
+```json
+{
+  "nodes": [
+    { "id": "start", "type": "Start", "metadata": {}, "data": {} },
+    { "id": "llm", "type": "LLM", "metadata": {}, "data": { "systemPrompt": "You are an assistant", "userPrompt": "{{input}}" } },
+    { "id": "end", "type": "End", "metadata": {}, "data": {} }
+  ],
+  "edges": [
+    { "source": "start", "target": "llm" },
+    { "source": "llm", "target": "end" }
+  ]
+}
+```
+
+### Node
+
+Nodes are the basic execution units in a workflow, each representing a specific operation or task. FlowGram Runtime supports various node types, including:
+
+- **Start Node**: The starting point of a workflow, providing workflow input
+- **End Node**: The endpoint of a workflow, collecting workflow output
+- **LLM Node**: Calls large language models, supporting system prompts and user prompts
+- **Condition Node**: Selects different execution branches based on conditions, supporting various comparison operators
+- **Loop Node**: Performs the same operation on each element in an array, supporting sub-workflows
+
+Each node contains ID, type, metadata, and data information, with different node types having different configuration options and behaviors.
+
+### Edge
+
+Edges define the connection relationships between nodes, representing the direction of data and control flow. Each edge contains source node, target node, and optional source port information.
+
+The definition of edges determines the execution path and data flow of the workflow, forming the foundation for building complex workflow logic.
+
+### Execution Engine
+
+The execution engine is responsible for parsing workflow definitions, executing nodes in the defined logical order, and handling data flow between nodes. It is the core component of FlowGram Runtime, managing the entire lifecycle of workflows.
+
+## Technical Architecture
+
+FlowGram Runtime adopts a Domain-Driven Design (DDD) architecture, dividing the system into multiple domains:
+
+- **Document**: Data structures for workflow definitions, including node and edge models
+- **Engine**: Core logic for workflow execution, responsible for workflow parsing and scheduling
+- **Executor**: Responsible for executing the specific logic of various node types, such as LLM calls and condition evaluation
+- **State**: Maintains state information during workflow execution, including execution history and current status
+- **Variable**: Manages variable data during workflow execution, supporting variable storage and access
+
+### Technology Stack
+
+The JavaScript version of FlowGram Runtime is built on the following technology stack:
+
+- **TypeScript**: Provides type safety and modern JavaScript features
+- **LangChain**: Integrates large language models and related tools
+- **OpenAI API**: Provides AI model calling capabilities
+- **Fastify**: High-performance web framework for HTTP API services
+- **tRPC**: Type-safe API framework
+
+### Module Composition
+
+The project consists of three core modules:
+
+1. **js-core**: Core runtime library, including workflow engine, node executors, and state management
+2. **interface**: Interface definitions, defining APIs and data models
+3. **nodejs**: NodeJS service implementation, providing HTTP API and service management
+
+## Current Development Status and Limitations ⚠️
+
+FlowGram Runtime is currently in early development stage, with the following status and limitations:
+
+### Development Status
+
+- Core functionality has been implemented, including workflow engine, basic node types, and main APIs
+- Basic LLM integration is complete, supporting integration with OpenAI and LangChain
+- Basic error handling and state management mechanisms are provided
+- Includes test cases and example workflows, though documentation is relatively limited
+
+### Known Limitations
+
+- **Unstable API**: API interfaces may change, with no guarantee of backward compatibility
+- **Incomplete Features**: Some features are not fully implemented, such as ServerInfo API and Validation API
+- **Error Handling**: Error handling mechanisms are not fully refined, certain edge cases may cause exceptions
+- **Storage Mechanism**: Current storage mechanisms are relatively simple, not suitable for production environment persistence requirements
+- **Security Mechanisms**: Lacks comprehensive security mechanisms such as authentication, authorization, and input validation
+
+## Future Development Plans
+
+Future development plans for FlowGram Runtime include:
+
+### Multi-language Support
+
+Currently only JavaScript/TypeScript version is available, with plans to develop:
+- **Python Version**: Suitable for data science and machine learning scenarios
+- **Go Version**: Suitable for high-performance server-side scenarios
+
+### Feature Enhancements
+
+- Add more node types: Code, Intent, Batch, Break, Continue.
+- Improve error handling and exception recovery mechanisms
+- Add complete server-side validation, including schema validation and input validation.
+- Support `Docker` deployment.
+
+### TestRun Optimization
+
+- TestRun supports input form
+- TestRun input parameter validation
+- Single node test run
+
+## Access to FlowGram Editor (Web Frontend)
+
+Modify the runtime configuration in `editorProps` to server mode and configure the service address:
+
+```ts
+createRuntimePlugin({
+  // mode: 'browser', // remove this line
+  mode: 'server',
+  serverConfig: {
+    domain: 'localhost',
+    port: 4000,
+    protocol: 'http',
+  },
+})
+```

+ 108 - 0
apps/docs/src/en/guide/runtime/quick-start.mdx

@@ -0,0 +1,108 @@
+---
+title: Quick Start
+description: Get started quickly with FlowGram Runtime
+sidebar_position: 3
+---
+
+# Quick Start
+
+This document will help you quickly get started with FlowGram Runtime, including environment preparation, installation, configuration, creating and running workflows. Through this guide, you'll be able to set up your workflow runtime environment and run your first workflow example in a short time.
+
+## Getting the Code
+
+Since FlowGram Runtime is positioned as a demo rather than an SDK and will not be published as an npm package, you need to follow these steps to obtain and use it:
+
+### Method 1: Fork the Repository (Recommended)
+
+1. Visit the FlowGram Runtime repository
+2. Click the "Fork" button to create your own copy of the repository
+3. Clone your forked repository to your local machine
+
+### Method 2: Direct Clone
+
+If you just want to try it out without submitting changes, you can clone the original repository directly:
+
+```bash
+git clone git clone git@github.com:bytedance/flowgram.ai.git
+cd flowgram.ai
+```
+
+## Environment Preparation
+
+Before you start using FlowGram Runtime, please ensure your development environment meets the following requirements:
+
+- **Node.js**: Version 18.x or higher (LTS version recommended)
+
+```bash
+nvm install lts/hydrogen
+nvm alias default lts/hydrogen # set default node version
+nvm use lts/hydrogen
+```
+
+- **Package Manager**: pnpm 9+ and rush 5+
+
+```bash
+npm i -g pnpm@9.12.0 @microsoft/rush@5.140.1
+```
+
+## Installing Dependencies and Project Setup
+
+After obtaining the code, you need to install dependencies and perform basic setup:
+
+1. **Install Project Dependencies**
+
+```bash
+rush install
+```
+
+2. **Build the Project**
+
+```bash
+rush build
+```
+
+## Starting the Service
+
+1. **Navigate to Runtime Directory**
+
+```bash
+cd packages/runtime/nodejs
+```
+
+2. **Start the nodejs Server**
+
+```bash
+npm run dev
+```
+
+If everything is working correctly, you should see the following output in the console:
+
+```
+> Listen Port: 4000
+> Server Address: http://[::1]:4000
+> API Docs: http://localhost:4000/docs
+```
+
+3. **Verify the Service**
+
+You can test the service using cURL:
+
+```bash
+curl --location 'http://localhost:4000/api/task/run' \
+--header 'Content-Type: application/json' \
+--data '{
+  "inputs": {
+      "test_input": "Hello FlowGram!"
+  },
+  "schema": "{\"nodes\":[{\"id\":\"start_0\",\"type\":\"start\",\"meta\":{\"position\":{\"x\":180,\"y\":0}},\"data\":{\"title\":\"Start\",\"outputs\":{\"type\":\"object\",\"properties\":{\"test_input\":{\"key\":4,\"name\":\"test_input\",\"isPropertyRequired\":true,\"type\":\"string\",\"extra\":{\"index\":0}}},\"required\":[\"test_input\"]}}},{\"id\":\"end_0\",\"type\":\"end\",\"meta\":{\"position\":{\"x\":640,\"y\":0}},\"data\":{\"title\":\"End\",\"inputsValues\":{\"test_output\":{\"type\":\"ref\",\"content\":[\"start_0\",\"test_input\"]}},\"inputs\":{\"type\":\"object\",\"properties\":{\"test_output\":{\"type\":\"string\"}}}}}],\"edges\":[{\"sourceNodeID\":\"start_0\",\"targetNodeID\":\"end_0\"}]}"
+}'
+```
+
+You should see the following output in the command line where the service is running:
+
+```
+> POST TaskRun - taskID:  xxxx-xxxx-xxxx-xxxx
+{ test_input: 'Hello FlowGram!' }
+> LOG Task finished:  xxxx-xxxx-xxxx-xxxx
+{ test_output: 'Hello FlowGram!' }
+```

+ 632 - 0
apps/docs/src/en/guide/runtime/source-code-guide.mdx

@@ -0,0 +1,632 @@
+---
+title: Source Code Guide
+description: Analysis of FlowGram Runtime source code structure and implementation details
+---
+
+# FlowGram Runtime Source Code Guide
+
+This document aims to help developers gain a deep understanding of FlowGram Runtime's source code structure and implementation details, providing guidance for customization and extension. Since FlowGram Runtime is positioned as a reference implementation rather than an SDK for direct use, understanding its internal implementation is particularly important for developers.
+
+## Project Structure Overview
+
+### Directory Structure
+
+The FlowGram Runtime JS project has the following directory structure:
+
+```
+packages/runtime
+├── js-core/          # Core runtime library
+│   ├── src/
+│   │   ├── application/    # Application layer, API implementation
+│   │   ├── domain/         # Domain layer, core business logic
+│   │   ├── infrastructure/ # Infrastructure layer, technical support
+│   │   ├── nodes/          # Node executor implementations
+│   │   └── index.ts        # Entry point
+│   ├── package.json
+│   └── tsconfig.json
+├── interface/        # Interface definitions
+│   ├── src/
+│   │   ├── api/       # API interface definitions
+│   │   ├── domain/    # Domain model interface definitions
+│   │   ├── engine/    # Engine interface definitions
+│   │   ├── node/      # Node interface definitions
+│   │   └── index.ts   # Entry point
+│   ├── package.json
+│   └── tsconfig.json
+└── nodejs/           # NodeJS service implementation
+    ├── src/
+    │   ├── api/       # HTTP API implementation
+    │   ├── server/    # Server implementation
+    │   └── index.ts   # Entry point
+    ├── package.json
+    └── tsconfig.json
+```
+
+### Module Organization
+
+FlowGram Runtime JS employs a modular design, primarily divided into three core modules:
+
+1. **interface**: Defines the system's interfaces and data structures, serving as the foundation for other modules
+2. **js-core**: Implements the core functionality of the workflow engine, including workflow parsing, node execution, state management, etc.
+3. **nodejs**: Provides an HTTP API service based on NodeJS, allowing the workflow engine to be called via HTTP interfaces
+
+### Dependencies
+
+The dependencies between modules are as follows:
+
+```mermaid
+graph TD
+    nodejs --> js-core
+    js-core --> interface
+    nodejs -.-> interface
+```
+
+- **interface** is the foundational module with no dependencies on other modules
+- **js-core** depends on interfaces defined in the interface module
+- **nodejs** depends on functionality provided by the js-core module, while also using interface definitions from the interface module
+
+Key external dependencies include:
+
+- **TypeScript**: Provides type safety and object-oriented programming support
+- **LangChain**: Used for integrating large language models
+- **OpenAI API**: Provides the default implementation for LLM nodes
+- **fastify**: Used to implement HTTP API services
+- **tRPC**: Used for type-safe API definitions and calls
+
+## Core Module Analysis
+
+### js-core Module
+
+The js-core module is the core of FlowGram Runtime, implementing the main functionality of the workflow engine. This module adopts a Domain-Driven Design (DDD) architecture, divided into application, domain, and infrastructure layers.
+
+#### Application Layer
+
+The application layer is responsible for coordinating domain objects and implementing system use cases. Key files:
+
+- `application/workflow.ts`: Workflow application service, implementing workflow execution, cancellation, querying, etc.
+- `application/api.ts`: API implementation, including TaskRun, TaskResult, TaskReport, TaskCancel, etc.
+
+#### Domain Layer
+
+The domain layer contains core business logic and domain models. Key directories and files:
+
+- `domain/engine/`: Workflow execution engine, responsible for workflow parsing and execution
+  - `engine.ts`: Workflow engine implementation, containing core logic for node execution, state management, etc.
+  - `validator.ts`: Workflow validator, checking the validity of workflow definitions
+- `domain/document/`: Workflow document model, representing the structure of workflows
+  - `workflow.ts`: Workflow definition model
+  - `node.ts`: Node definition model
+  - `edge.ts`: Edge definition model
+- `domain/executor/`: Node executors, responsible for executing specific node logic
+  - `executor.ts`: Node executor base class and factory
+- `domain/variable/`: Variable management, handling variable storage and references in workflows
+  - `manager.ts`: Variable manager, responsible for variable storage, retrieval, and parsing
+  - `store.ts`: Variable storage, providing variable persistence
+- `domain/status/`: Status management, tracking the execution status of workflows and nodes
+  - `center.ts`: Status center, managing workflow and node statuses
+- `domain/snapshot/`: Snapshot management, recording intermediate states of workflow execution
+  - `center.ts`: Snapshot center, managing node execution snapshots
+- `domain/report/`: Report generation, collecting detailed information on workflow execution
+  - `center.ts`: Report center, generating workflow execution reports
+
+#### Infrastructure Layer
+
+The infrastructure layer provides technical support, including logging, events, containers, etc. Key files:
+
+- `infrastructure/logger.ts`: Logging service, providing logging functionality
+- `infrastructure/event.ts`: Event service, providing event publishing and subscription functionality
+- `infrastructure/container.ts`: Dependency injection container, managing object creation and lifecycle
+- `infrastructure/error.ts`: Error handling, defining error types and handling methods in the system
+
+#### Node Executors
+
+The nodes directory contains executor implementations for various node types. Key files:
+
+- `nodes/start.ts`: Start node executor
+- `nodes/end.ts`: End node executor
+- `nodes/llm.ts`: LLM node executor, integrating large language models
+- `nodes/condition.ts`: Condition node executor, implementing conditional branching
+- `nodes/loop.ts`: Loop node executor, implementing loop logic
+
+### interface Module
+
+The interface module defines the system's interfaces and data structures, serving as the foundation for other modules. Key directories and files:
+
+- `api/`: API interface definitions
+  - `api.ts`: Defines the API interfaces provided by the system
+  - `types.ts`: API-related data type definitions
+- `domain/`: Domain model interface definitions
+  - `document.ts`: Workflow document-related interfaces
+  - `engine.ts`: Workflow engine-related interfaces
+  - `executor.ts`: Node executor-related interfaces
+  - `variable.ts`: Variable management-related interfaces
+  - `status.ts`: Status management-related interfaces
+  - `snapshot.ts`: Snapshot management-related interfaces
+  - `report.ts`: Report generation-related interfaces
+- `engine/`: Engine interface definitions
+  - `types.ts`: Engine-related data type definitions
+- `node/`: Node interface definitions
+  - `types.ts`: Node-related data type definitions
+
+### nodejs Module
+
+The nodejs module provides an HTTP API service based on NodeJS, allowing the workflow engine to be called via HTTP interfaces. Key directories and files:
+
+- `api/`: HTTP API implementation
+  - `router.ts`: API route definitions
+  - `handlers.ts`: API handler functions
+- `server/`: Server implementation
+  - `server.ts`: HTTP server implementation
+  - `config.ts`: Server configuration
+
+## Key Implementation Details
+
+### Workflow Engine
+
+The workflow engine is the core of FlowGram Runtime, responsible for workflow parsing and execution. Its main implementation is located in `js-core/src/domain/engine/engine.ts`.
+
+The main functions of the workflow engine include:
+
+1. **Workflow Parsing**: Converting workflow definitions into internal models
+2. **Node Scheduling**: Determining the execution order of nodes based on edges defined in the workflow
+3. **Node Execution**: Calling node executors to execute node logic
+4. **State Management**: Tracking the execution status of workflows and nodes
+5. **Variable Management**: Handling data transfer between nodes
+6. **Error Handling**: Managing exceptions during execution
+
+Key code snippet:
+
+```typescript
+// Core method for workflow execution
+public async run(params: RunParams): Promise<RunResult> {
+  const { schema, inputs, options } = params;
+
+  // Create workflow context
+  const context = this.createContext(schema, inputs, options);
+
+  try {
+    // Initialize workflow
+    await this.initialize(context);
+
+    // Execute workflow
+    await this.execute(context);
+
+    // Get workflow result
+    const result = await this.getResult(context);
+
+    return {
+      status: 'success',
+      outputs: result
+    };
+  } catch (error) {
+    // Error handling
+    return {
+      status: 'fail',
+      error: error.message
+    };
+  }
+}
+
+// Execute workflow
+private async execute(context: IContext): Promise<void> {
+  // Get start node
+  const startNode = context.workflow.getStartNode();
+
+  // Start execution from the start node
+  await this.executeNode({ context, node: startNode });
+
+  // Wait for all nodes to complete execution
+  await this.waitForCompletion(context);
+}
+
+// Execute node
+public async executeNode(params: { context: IContext; node: INode }): Promise<void> {
+  const { context, node } = params;
+
+  // Get node executor
+  const executor = this.getExecutor(node.type);
+
+  // Prepare node inputs
+  const inputs = await this.prepareInputs(context, node);
+
+  // Execute node
+  const result = await executor.execute({
+    node,
+    inputs,
+    context
+  });
+
+  // Process node outputs
+  await this.processOutputs(context, node, result.outputs);
+
+  // Schedule next nodes
+  await this.scheduleNextNodes(context, node);
+}
+```
+
+### Node Executors
+
+Node executors are responsible for executing the specific logic of nodes. Each node type has a corresponding executor implementation located in the `js-core/src/nodes/` directory.
+
+The basic interface for node executors is defined in `interface/src/domain/executor.ts`:
+
+```typescript
+export interface INodeExecutor {
+  type: string;
+  execute(context: ExecutionContext): Promise<ExecutionResult>;
+}
+```
+
+Taking the LLM node executor as an example, its implementation is in `js-core/src/nodes/llm.ts`:
+
+```typescript
+export class LLMExecutor implements INodeExecutor {
+  public type = 'llm';
+
+  public async execute(context: ExecutionContext): Promise<ExecutionResult> {
+    const inputs = context.inputs as LLMExecutorInputs;
+
+    // Create LLM provider
+    const provider = this.createProvider(inputs);
+
+    // Prepare prompts
+    const systemPrompt = inputs.systemPrompt || '';
+    const userPrompt = inputs.prompt || '';
+
+    // Call LLM
+    const result = await provider.call({
+      systemPrompt,
+      userPrompt,
+      options: {
+        temperature: inputs.temperature
+      }
+    });
+
+    // Return result
+    return {
+      outputs: {
+        result: result.content
+      }
+    };
+  }
+
+  private createProvider(inputs: LLMExecutorInputs): ILLMProvider {
+    // Create different providers based on model name
+    if (inputs.modelName.startsWith('gpt-')) {
+      return new OpenAIProvider({
+        apiKey: inputs.apiKey,
+        apiHost: inputs.apiHost,
+        modelName: inputs.modelName
+      });
+    }
+
+    throw new Error(`Unsupported model: ${inputs.modelName}`);
+  }
+}
+```
+
+### Variable Management
+
+Variable management is an important part of workflow execution, responsible for handling data transfer between nodes. Its main implementation is in the `js-core/src/domain/variable/` directory.
+
+The core of variable management is the variable manager and variable storage:
+
+- **Variable Manager**: Responsible for parsing, getting, and setting variables
+- **Variable Storage**: Provides persistent storage for variables
+
+Key code snippet:
+
+```typescript
+// Variable manager
+export class VariableManager implements IVariableManager {
+  constructor(private store: IVariableStore) {}
+
+  // Resolve variable references
+  public async resolve(ref: ValueSchema, scope?: string): Promise<any> {
+    if (ref.type === 'constant') {
+      return ref.content;
+    } else if (ref.type === 'ref') {
+      const path = ref.content as string[];
+      return this.get(path, scope);
+    }
+    throw new Error(`Unsupported value type: ${ref.type}`);
+  }
+
+  // Get variable value
+  public async get(path: string[], scope?: string): Promise<any> {
+    const [nodeID, key, ...rest] = path;
+    const value = await this.store.get(nodeID, key, scope);
+
+    if (rest.length === 0) {
+      return value;
+    }
+
+    // Handle nested properties
+    return this.getNestedProperty(value, rest);
+  }
+
+  // Set variable value
+  public async set(nodeID: string, key: string, value: any, scope?: string): Promise<void> {
+    await this.store.set(nodeID, key, value, scope);
+  }
+}
+```
+
+### State Storage
+
+State storage is responsible for managing the execution state of workflows and nodes. Its main implementation is in the `js-core/src/domain/status/` and `js-core/src/domain/snapshot/` directories.
+
+The core components of state management include:
+
+- **Status Center**: Manages the status of workflows and nodes
+- **Snapshot Center**: Records snapshots of node execution
+- **Report Center**: Generates workflow execution reports
+
+Key code snippet:
+
+```typescript
+// Status center
+export class StatusCenter implements IStatusCenter {
+  private workflowStatus: Record<string, WorkflowStatus> = {};
+  private nodeStatus: Record<string, Record<string, NodeStatus>> = {};
+
+  // Set workflow status
+  public setWorkflowStatus(workflowID: string, status: WorkflowStatus): void {
+    this.workflowStatus[workflowID] = status;
+  }
+
+  // Get workflow status
+  public getWorkflowStatus(workflowID: string): WorkflowStatus {
+    return this.workflowStatus[workflowID] || 'idle';
+  }
+
+  // Set node status
+  public setNodeStatus(workflowID: string, nodeID: string, status: NodeStatus): void {
+    if (!this.nodeStatus[workflowID]) {
+      this.nodeStatus[workflowID] = {};
+    }
+    this.nodeStatus[workflowID][nodeID] = status;
+  }
+
+  // Get node status
+  public getNodeStatus(workflowID: string, nodeID: string): NodeStatus {
+    return this.nodeStatus[workflowID]?.[nodeID] || 'idle';
+  }
+}
+```
+
+## Design Patterns and Architectural Decisions
+
+### Domain-Driven Design
+
+FlowGram Runtime adopts a Domain-Driven Design (DDD) architecture, dividing the system into application, domain, and infrastructure layers. This architecture helps separate concerns, making the code more modular and maintainable.
+
+Key domain concepts include:
+
+- **Workflow**: Represents a complete workflow definition
+- **Node**: Basic execution unit in a workflow
+- **Edge**: Line connecting nodes, representing execution flow
+- **Execution Context**: Environment for workflow execution
+- **Variable**: Data in the workflow execution process
+
+### Factory Pattern
+
+FlowGram Runtime uses the Factory pattern to create node executors, enabling the system to dynamically create corresponding executors based on node types.
+
+```typescript
+// Node executor factory
+export class NodeExecutorFactory implements INodeExecutorFactory {
+  private executors: Record<string, INodeExecutor> = {};
+
+  // Register node executor
+  public register(executor: INodeExecutor): void {
+    this.executors[executor.type] = executor;
+  }
+
+  // Create node executor
+  public create(type: string): INodeExecutor {
+    const executor = this.executors[type];
+    if (!executor) {
+      throw new Error(`No executor registered for node type: ${type}`);
+    }
+    return executor;
+  }
+}
+```
+
+### Strategy Pattern
+
+FlowGram Runtime uses the Strategy pattern to handle execution logic for different types of nodes, with each node type having a corresponding execution strategy.
+
+```typescript
+// Node executor interface (strategy interface)
+export interface INodeExecutor {
+  type: string;
+  execute(context: ExecutionContext): Promise<ExecutionResult>;
+}
+
+// Concrete strategy implementation
+export class StartExecutor implements INodeExecutor {
+  public type = 'start';
+
+  public async execute(context: ExecutionContext): Promise<ExecutionResult> {
+    // Start node execution logic
+  }
+}
+
+export class EndExecutor implements INodeExecutor {
+  public type = 'end';
+
+  public async execute(context: ExecutionContext): Promise<ExecutionResult> {
+    // End node execution logic
+  }
+}
+```
+
+### Observer Pattern
+
+FlowGram Runtime uses the Observer pattern to implement the event system, allowing components to publish and subscribe to events.
+
+```typescript
+// Event emitter
+export class EventEmitter implements IEventEmitter {
+  private listeners: Record<string, Function[]> = {};
+
+  // Subscribe to event
+  public on(event: string, listener: Function): void {
+    if (!this.listeners[event]) {
+      this.listeners[event] = [];
+    }
+    this.listeners[event].push(listener);
+  }
+
+  // Publish event
+  public emit(event: string, ...args: any[]): void {
+    const eventListeners = this.listeners[event];
+    if (eventListeners) {
+      for (const listener of eventListeners) {
+        listener(...args);
+      }
+    }
+  }
+}
+```
+
+### Dependency Injection
+
+FlowGram Runtime uses Dependency Injection to manage dependencies between components, making components more loosely coupled and testable.
+
+```typescript
+// Dependency injection container
+export class Container {
+  private static _instance: Container;
+  private registry: Map<any, any> = new Map();
+
+  public static get instance(): Container {
+    if (!Container._instance) {
+      Container._instance = new Container();
+    }
+    return Container._instance;
+  }
+
+  // Register service
+  public register<T>(token: any, instance: T): void {
+    this.registry.set(token, instance);
+  }
+
+  // Get service
+  public resolve<T>(token: any): T {
+    const instance = this.registry.get(token);
+    if (!instance) {
+      throw new Error(`No instance registered for token: ${token}`);
+    }
+    return instance;
+  }
+}
+```
+
+## Adding New Node Types (WIP)
+
+To add a new node type, you need to implement the `INodeExecutor` interface and register it with the node executor factory.
+
+Steps:
+
+1. Create a new node executor file in the `js-core/src/nodes/` directory
+2. Implement the `INodeExecutor` interface
+3. Register the new node executor in `js-core/src/nodes/index.ts`
+
+Example: Adding a data transformation node
+
+```typescript
+// js-core/src/nodes/transform.ts
+import { ExecutionContext, ExecutionResult, INodeExecutor } from '@flowgram.ai/runtime-interface';
+
+export interface TransformExecutorInputs {
+  data: any;
+  template: string;
+}
+
+export class TransformExecutor implements INodeExecutor {
+  public type = 'transform';
+
+  public async execute(context: ExecutionContext): Promise<ExecutionResult> {
+    const inputs = context.inputs as TransformExecutorInputs;
+
+    // Transform data using template
+    const result = this.transform(inputs.data, inputs.template);
+
+    return {
+      outputs: {
+        result
+      }
+    };
+  }
+
+  private transform(data: any, template: string): any {
+    // Implement data transformation logic
+    // This is just a simple example
+    return eval(`(data) => { return ${template} }`)(data);
+  }
+}
+
+// js-core/src/nodes/index.ts
+import { TransformExecutor } from './transform';
+
+// Add the new node executor to the array
+WorkflowRuntimeNodeExecutors.push(new TransformExecutor());
+```
+
+## Unit Testing
+
+FlowGram Runtime uses Vitest for unit testing.
+
+Running tests:
+
+```bash
+cd package/runtime/js-core
+npm run test
+```
+
+Writing tests:
+
+```typescript
+// engine.test.ts
+import { WorkflowRuntimeEngine } from '../src/domain/engine';
+import { EngineServices } from '@flowgram.ai/runtime-interface';
+
+describe('WorkflowRuntimeEngine', () => {
+  let engine: WorkflowRuntimeEngine;
+
+  beforeEach(() => {
+    // Create test services
+    const services: EngineServices = {
+      // Use mock objects
+    };
+
+    engine = new WorkflowRuntimeEngine(services);
+  });
+
+  test('should execute workflow successfully', async () => {
+    // Prepare test data
+    const schema = {
+      nodes: [
+        // Test nodes
+      ],
+      edges: [
+        // Test edges
+      ]
+    };
+
+    const inputs = {
+      prompt: 'Test prompt'
+    };
+
+    // Execute workflow
+    const result = await engine.run({ schema, inputs });
+
+    // Verify results
+    expect(result.status).toBe('success');
+    expect(result.outputs).toBeDefined();
+  });
+});
+```

+ 5 - 0
apps/docs/src/zh/guide/_meta.json

@@ -15,5 +15,10 @@
     "type": "dir",
     "type": "dir",
     "name": "concepts",
     "name": "concepts",
     "label": "概念"
     "label": "概念"
+  },
+  {
+    "type": "dir",
+    "name": "runtime",
+    "label": "运行时 (WIP)"
   }
   }
 ]
 ]

+ 5 - 0
apps/docs/src/zh/guide/runtime/_meta.json

@@ -0,0 +1,5 @@
+[
+  "introduction",
+  "quick-start",
+  "source-code-guide"
+]

+ 140 - 0
apps/docs/src/zh/guide/runtime/introduction.mdx

@@ -0,0 +1,140 @@
+---
+title: 介绍
+description: FlowGram Runtime 的基本概念和设计理念
+sidebar_position: 2
+---
+
+# FlowGram Runtime 介绍
+
+**⚠️ FlowGram Runtime 处于早期开发阶段,目前只支持 nodejs 运行时,且只支持自由布局**
+
+本文档将介绍 FlowGram Runtime 的基本概念、设计理念和核心功能,帮助业务接入方开发者了解和使用这个工作流运行时引擎的参考实现。
+
+## 什么是 FlowGram Runtime
+
+FlowGram Runtime 是一个工作流运行时引擎的参考实现,旨在为业务接入方开发者提供运行时参考。它能够解析和执行基于图结构的工作流,支持多种节点类型,包括 Start、End、LLM、Condition、Loop 等。
+
+### 项目定位与目标
+
+FlowGram Runtime **定位为 demo 而非 SDK**,它的主要目标是:
+
+- 提供工作流运行时的设计和实现参考
+- 展示如何构建和扩展工作流引擎
+- 为开发者提供可以直接学习和修改的代码基础
+- 支持快速原型开发和概念验证
+
+作为参考实现,FlowGram Runtime 不会作为包发布,开发者需要 fork 代码库后,根据自己的业务场景和需求进行修改和扩展。
+
+## 核心概念
+
+### 工作流 (Workflow)
+
+工作流是由节点和边组成的有向图,描述了一系列任务的执行顺序和逻辑关系。在 FlowGram Runtime 中,工作流使用 JSON 格式定义,包含节点和边两部分。
+
+工作流定义示例:
+```json
+{
+  "nodes": [
+    { "id": "start", "type": "Start", "metadata": {}, "data": {} },
+    { "id": "llm", "type": "LLM", "metadata": {}, "data": { "systemPrompt": "你是助手", "userPrompt": "{{input}}" } },
+    { "id": "end", "type": "End", "metadata": {}, "data": {} }
+  ],
+  "edges": [
+    { "source": "start", "target": "llm" },
+    { "source": "llm", "target": "end" }
+  ]
+}
+```
+
+### 节点 (Node)
+
+节点是工作流中的基本执行单元,每个节点代表一个特定的操作或任务。FlowGram Runtime 支持多种节点类型,包括:
+
+- **Start 节点**:工作流的起点,提供工作流输入
+- **End 节点**:工作流的终点,收集工作流输出
+- **LLM 节点**:调用大型语言模型,支持系统提示词和用户提示词
+- **Condition 节点**:根据条件选择不同执行分支,支持多种比较操作符
+- **Loop 节点**:对数组中的每个元素执行相同操作,支持子工作流
+
+每个节点包含 ID、类型、元数据和数据等信息,不同类型的节点具有不同的配置选项和行为。
+
+### 边 (Edge)
+
+边定义了节点之间的连接关系,表示数据和控制流的传递方向。每条边包含源节点、目标节点和可选的源端口信息。
+
+边的定义决定了工作流的执行路径和数据流向,是构建复杂工作流逻辑的基础。
+
+### 执行引擎 (Engine)
+
+执行引擎负责解析工作流定义,按照定义的逻辑顺序执行各个节点,并处理节点间的数据流转。它是 FlowGram Runtime 的核心组件,管理整个工作流的生命周期。
+
+## 技术架构
+
+FlowGram Runtime 采用领域驱动设计(DDD)架构,将系统分为多个领域:
+
+- **文档 (Document)**:工作流定义的数据结构,包括节点和边的模型
+- **引擎 (Engine)**:工作流执行的核心逻辑,负责工作流的解析和调度
+- **执行器 (Executor)**:负责执行各类节点的具体逻辑,如 LLM 调用、条件判断等
+- **状态 (State)**:维护工作流执行过程中的状态信息,包括执行历史和当前状态
+- **变量 (Variable)**:管理工作流执行过程中的变量数据,支持变量的存储和访问
+
+### 技术栈
+
+FlowGram Runtime JS 版本基于以下技术栈构建:
+
+- **TypeScript**:提供类型安全和现代 JavaScript 特性
+- **LangChain**:集成大型语言模型和相关工具
+- **OpenAI API**:提供 AI 模型调用能力
+- **Fastify**:高性能的 Web 框架,用于 HTTP API 服务
+- **tRPC**:类型安全的 API 框架
+
+### 模块组成
+
+项目由三个核心模块组成:
+
+1. **js-core**:核心运行时库,包含工作流引擎、节点执行器和状态管理
+2. **interface**:接口定义,定义了 API 和数据模型
+3. **nodejs**:NodeJS 服务实现,提供 HTTP API 和服务管理
+
+## 当前开发状态和限制 ⚠️
+
+FlowGram Runtime 目前处于早期开发阶段,有以下状态和限制:
+
+### 开发状态
+
+- 核心功能已经实现,包括工作流引擎、基本节点类型和主要 API
+- 基本的 LLM 集成已完成,支持与 OpenAI 和 LangChain 的集成
+- 提供了基本的错误处理和状态管理机制
+- 包含测试用例和示例工作流,但文档相对有限
+
+### 已知限制
+
+- **API 不稳定**:API 接口可能会有变更,不保证向后兼容
+- **功能不完善**:部分功能尚未完全实现,如 ServerInfo API 和 Validation API
+- **错误处理**:错误处理机制不够完善,某些边缘情况可能导致异常
+- **存储机制**:当前存储机制较为简单,不适合生产环境的持久化需求
+- **安全机制**:缺乏完善的安全机制,如认证、授权和输入验证
+
+## 未来开发计划
+
+FlowGram Runtime 的未来发展计划包括:
+
+### 多语言支持
+
+目前只有 JavaScript/TypeScript 版本,计划开发:
+- **Python 版本**:适用于数据科学和机器学习场景
+- **Go 版本**:适用于高性能服务端场景
+
+### 功能增强
+
+- 支持固定布局
+- 增加更多节点类型:代码节点、意图识别节点、批处理节点、终止循环节点、继续循环节点
+- 完善错误处理和异常恢复机制
+- 完善的服务端校验接口,包括 schema 校验和输入校验等
+- 支持 `Docker` 运行
+
+### 试运行优化
+
+- 试运行支持输入表单
+- 试运行输入参数校验
+- 单节点调试

+ 124 - 0
apps/docs/src/zh/guide/runtime/quick-start.mdx

@@ -0,0 +1,124 @@
+---
+title: 快速入门
+description: 快速上手使用 FlowGram Runtime
+sidebar_position: 3
+---
+
+# 快速入门
+
+本文档将帮助您快速上手使用 FlowGram Runtime,包括环境准备、安装配置、创建和运行工作流等内容。通过本指南,您将能够在短时间内搭建起自己的工作流运行环境并运行第一个工作流示例。
+
+## 获取代码
+
+由于 FlowGram Runtime 定位为 demo 而非 SDK,不会作为 npm 包发布,您需要通过以下步骤来获取和使用它:
+
+### 方式一:Fork 仓库(推荐)
+
+1. 访问 FlowGram Runtime 的代码仓库
+2. 点击 "Fork" 按钮创建您自己的仓库副本
+3. 克隆您 fork 的仓库到本地
+
+### 方式二:直接克隆 flowgram 仓库
+
+如果您只是想尝试使用而不需要提交更改,可以直接克隆原始仓库:
+
+```bash
+git clone git clone git@github.com:bytedance/flowgram.ai.git
+cd flowgram.ai
+```
+
+## 环境准备
+
+在开始使用 FlowGram Runtime 之前,请确保您的开发环境满足以下要求:
+
+- **Node.js**:版本 18.x 或更高版本(推荐使用 LTS 版本)
+
+```bash
+nvm install lts/hydrogen
+nvm alias default lts/hydrogen # set default node version
+nvm use lts/hydrogen
+```
+
+- **包管理器**:pnpm 9+ 与 rush 5+
+
+```bash
+npm i -g pnpm@9.12.0 @microsoft/rush@5.140.1
+```
+
+## 安装依赖和项目设置
+
+获取代码后,需要安装依赖并进行基本设置:
+
+1. **安装项目依赖**
+
+```bash
+rush install
+```
+
+2. **构建项目**
+
+```bash
+rush build
+```
+
+## 启动服务
+
+1. **进入运行时目录**
+
+```bash
+cd packages/runtime/nodejs
+```
+
+2. **启动 nodejs 服务器**
+
+```bash
+npm run dev
+```
+
+如果一切正常,你能在控制台看到以下输出:
+
+```
+> Listen Port: 4000
+> Server Address: http://[::1]:4000
+> API Docs: http://localhost:4000/docs
+```
+
+3. **验证服务运行**
+
+在命令行支持 cURL 请求
+
+```bash
+curl --location 'http://localhost:4000/api/task/run' \
+--header 'Content-Type: application/json' \
+--data '{
+  "inputs": {
+      "test_input": "Hello FlowGram!"
+  },
+  "schema": "{\"nodes\":[{\"id\":\"start_0\",\"type\":\"start\",\"meta\":{\"position\":{\"x\":180,\"y\":0}},\"data\":{\"title\":\"Start\",\"outputs\":{\"type\":\"object\",\"properties\":{\"test_input\":{\"key\":4,\"name\":\"test_input\",\"isPropertyRequired\":true,\"type\":\"string\",\"extra\":{\"index\":0}}},\"required\":[\"test_input\"]}}},{\"id\":\"end_0\",\"type\":\"end\",\"meta\":{\"position\":{\"x\":640,\"y\":0}},\"data\":{\"title\":\"End\",\"inputsValues\":{\"test_output\":{\"type\":\"ref\",\"content\":[\"start_0\",\"test_input\"]}},\"inputs\":{\"type\":\"object\",\"properties\":{\"test_output\":{\"type\":\"string\"}}}}}],\"edges\":[{\"sourceNodeID\":\"start_0\",\"targetNodeID\":\"end_0\"}]}"
+}'
+```
+
+此时服务所在的命令行应该会有如下输出:
+
+```
+> POST TaskRun - taskID:  xxxx-xxxx-xxxx-xxxx
+{ test_input: 'Hello FlowGram!' }
+> LOG Task finished:  xxxx-xxxx-xxxx-xxxx
+{ test_output: 'Hello FlowGram!' }
+```
+
+## 接入到 FlowGram 编辑器(Web 前端)
+
+在 `editorProps` 配置中修改 runtime 为 server 模式,并配置服务地址
+
+```ts
+createRuntimePlugin({
+  // mode: 'browser', // 移除这一行
+  mode: 'server',
+  serverConfig: {
+    domain: 'localhost',
+    port: 4000,
+    protocol: 'http',
+  },
+})
+```

+ 632 - 0
apps/docs/src/zh/guide/runtime/source-code-guide.mdx

@@ -0,0 +1,632 @@
+---
+title: 源码导读
+description: FlowGram Runtime 源码结构和实现细节解析
+---
+
+# FlowGram Runtime 源码导读
+
+本文档旨在帮助开发者深入理解 FlowGram Runtime 的源码结构和实现细节,为后续的定制开发提供指导。由于 FlowGram Runtime 定位为参考实现而非直接使用的 SDK,因此了解其内部实现对于开发者来说尤为重要。
+
+## 项目结构概述
+
+### 目录结构
+
+FlowGram Runtime JS 项目的目录结构如下:
+
+```
+packages/runtime
+├── js-core/          # 核心运行时库
+│   ├── src/
+│   │   ├── application/    # 应用层,实现API接口
+│   │   ├── domain/         # 领域层,核心业务逻辑
+│   │   ├── infrastructure/ # 基础设施层,提供技术支持
+│   │   ├── nodes/          # 节点执行器实现
+│   │   └── index.ts        # 入口文件
+│   ├── package.json
+│   └── tsconfig.json
+├── interface/        # 接口定义
+│   ├── src/
+│   │   ├── api/       # API接口定义
+│   │   ├── domain/    # 领域模型接口定义
+│   │   ├── engine/    # 引擎接口定义
+│   │   ├── node/      # 节点接口定义
+│   │   └── index.ts   # 入口文件
+│   ├── package.json
+│   └── tsconfig.json
+└── nodejs/           # NodeJS 服务实现
+    ├── src/
+    │   ├── api/       # HTTP API实现
+    │   ├── server/    # 服务器实现
+    │   └── index.ts   # 入口文件
+    ├── package.json
+    └── tsconfig.json
+```
+
+### 模块组织
+
+FlowGram Runtime JS 采用模块化设计,主要分为三个核心模块:
+
+1. **interface**: 定义了系统的接口和数据结构,是其他模块的基础
+2. **js-core**: 实现了工作流引擎的核心功能,包括工作流解析、节点执行、状态管理等
+3. **nodejs**: 提供了基于 NodeJS 的 HTTP API 服务,使工作流引擎可以通过 HTTP 接口调用
+
+### 依赖关系
+
+模块之间的依赖关系如下:
+
+```mermaid
+graph TD
+    nodejs --> js-core
+    js-core --> interface
+    nodejs -.-> interface
+```
+
+- **interface** 是基础模块,不依赖其他模块
+- **js-core** 依赖 interface 模块中定义的接口
+- **nodejs** 依赖 js-core 模块提供的功能,同时也使用 interface 模块中的接口定义
+
+主要的外部依赖包括:
+
+- **TypeScript**: 提供类型安全和面向对象编程支持
+- **LangChain**: 用于集成大型语言模型
+- **OpenAI API**: 提供 LLM 节点的默认实现
+- **fastify**: 用于实现 HTTP API 服务
+- **tRPC**: 用于类型安全的 API 定义和调用
+
+## 核心模块详解
+
+### js-core 模块
+
+js-core 模块是 FlowGram Runtime 的核心,实现了工作流引擎的主要功能。该模块采用领域驱动设计(DDD)架构,分为应用层、领域层和基础设施层。
+
+#### 应用层 (application)
+
+应用层负责协调领域对象,实现系统的用例。主要文件:
+
+- `application/workflow.ts`: 工作流应用服务,实现工作流的执行、取消、查询等功能
+- `application/api.ts`: API 实现,包括 TaskRun、TaskResult、TaskReport、TaskCancel 等
+
+#### 领域层 (domain)
+
+领域层包含业务核心逻辑和领域模型。主要目录和文件:
+
+- `domain/engine/`: 工作流执行引擎,负责工作流的解析和执行
+  - `engine.ts`: 工作流引擎实现,包含节点执行、状态管理等核心逻辑
+  - `validator.ts`: 工作流验证器,检查工作流定义的有效性
+- `domain/document/`: 工作流文档模型,表示工作流的结构
+  - `workflow.ts`: 工作流定义模型
+  - `node.ts`: 节点定义模型
+  - `edge.ts`: 边定义模型
+- `domain/executor/`: 节点执行器,负责执行具体节点的逻辑
+  - `executor.ts`: 节点执行器基类和工厂
+- `domain/variable/`: 变量管理,处理工作流中的变量存储和引用
+  - `manager.ts`: 变量管理器,负责变量的存储、获取和解析
+  - `store.ts`: 变量存储,提供变量的持久化
+- `domain/status/`: 状态管理,跟踪工作流和节点的执行状态
+  - `center.ts`: 状态中心,管理工作流和节点的状态
+- `domain/snapshot/`: 快照管理,记录工作流执行的中间状态
+  - `center.ts`: 快照中心,管理节点执行的快照
+- `domain/report/`: 报告生成,收集工作流执行的详细信息
+  - `center.ts`: 报告中心,生成工作流执行报告
+
+#### 基础设施层 (infrastructure)
+
+基础设施层提供技术支持,包括日志、事件、容器等。主要文件:
+
+- `infrastructure/logger.ts`: 日志服务,提供日志记录功能
+- `infrastructure/event.ts`: 事件服务,提供事件发布和订阅功能
+- `infrastructure/container.ts`: 依赖注入容器,管理对象的创建和生命周期
+- `infrastructure/error.ts`: 错误处理,定义系统中的错误类型和处理方式
+
+#### 节点执行器 (nodes)
+
+nodes 目录包含各种节点类型的执行器实现。主要文件:
+
+- `nodes/start.ts`: Start 节点执行器
+- `nodes/end.ts`: End 节点执行器
+- `nodes/llm.ts`: LLM 节点执行器,集成大型语言模型
+- `nodes/condition.ts`: Condition 节点执行器,实现条件分支
+- `nodes/loop.ts`: Loop 节点执行器,实现循环逻辑
+
+### interface 模块
+
+interface 模块定义了系统的接口和数据结构,是其他模块的基础。主要目录和文件:
+
+- `api/`: API 接口定义
+  - `api.ts`: 定义系统提供的 API 接口
+  - `types.ts`: API 相关的数据类型定义
+- `domain/`: 领域模型接口定义
+  - `document.ts`: 工作流文档相关接口
+  - `engine.ts`: 工作流引擎相关接口
+  - `executor.ts`: 节点执行器相关接口
+  - `variable.ts`: 变量管理相关接口
+  - `status.ts`: 状态管理相关接口
+  - `snapshot.ts`: 快照管理相关接口
+  - `report.ts`: 报告生成相关接口
+- `engine/`: 引擎接口定义
+  - `types.ts`: 引擎相关的数据类型定义
+- `node/`: 节点接口定义
+  - `types.ts`: 节点相关的数据类型定义
+
+### nodejs 模块
+
+nodejs 模块提供了基于 NodeJS 的 HTTP API 服务,使工作流引擎可以通过 HTTP 接口调用。主要目录和文件:
+
+- `api/`: HTTP API 实现
+  - `router.ts`: API 路由定义
+  - `handlers.ts`: API 处理函数
+- `server/`: 服务器实现
+  - `server.ts`: HTTP 服务器实现
+  - `config.ts`: 服务器配置
+
+## 关键实现分析
+
+### 工作流引擎
+
+工作流引擎是 FlowGram Runtime 的核心,负责工作流的解析和执行。其主要实现位于 `js-core/src/domain/engine/engine.ts`。
+
+工作流引擎的主要功能包括:
+
+1. **工作流解析**:将工作流定义转换为内部模型
+2. **节点调度**:根据工作流定义的边,确定节点的执行顺序
+3. **节点执行**:调用节点执行器执行节点逻辑
+4. **状态管理**:跟踪工作流和节点的执行状态
+5. **变量管理**:处理节点间的数据传递
+6. **错误处理**:处理执行过程中的异常情况
+
+关键代码片段:
+
+```typescript
+// 工作流执行的核心方法
+public async run(params: RunParams): Promise<RunResult> {
+  const { schema, inputs, options } = params;
+
+  // 创建工作流上下文
+  const context = this.createContext(schema, inputs, options);
+
+  try {
+    // 初始化工作流
+    await this.initialize(context);
+
+    // 执行工作流
+    await this.execute(context);
+
+    // 获取工作流结果
+    const result = await this.getResult(context);
+
+    return {
+      status: 'success',
+      outputs: result
+    };
+  } catch (error) {
+    // 错误处理
+    return {
+      status: 'fail',
+      error: error.message
+    };
+  }
+}
+
+// 执行工作流
+private async execute(context: IContext): Promise<void> {
+  // 获取开始节点
+  const startNode = context.workflow.getStartNode();
+
+  // 从开始节点开始执行
+  await this.executeNode({ context, node: startNode });
+
+  // 等待所有节点执行完成
+  await this.waitForCompletion(context);
+}
+
+// 执行节点
+public async executeNode(params: { context: IContext; node: INode }): Promise<void> {
+  const { context, node } = params;
+
+  // 获取节点执行器
+  const executor = this.getExecutor(node.type);
+
+  // 准备节点输入
+  const inputs = await this.prepareInputs(context, node);
+
+  // 执行节点
+  const result = await executor.execute({
+    node,
+    inputs,
+    context
+  });
+
+  // 处理节点输出
+  await this.processOutputs(context, node, result.outputs);
+
+  // 调度下一个节点
+  await this.scheduleNextNodes(context, node);
+}
+```
+
+### 节点执行器
+
+节点执行器负责执行具体节点的逻辑。每种节点类型都有对应的执行器实现,位于 `js-core/src/nodes/` 目录。
+
+节点执行器的基本接口定义在 `interface/src/domain/executor.ts` 中:
+
+```typescript
+export interface INodeExecutor {
+  type: string;
+  execute(context: ExecutionContext): Promise<ExecutionResult>;
+}
+```
+
+以 LLM 节点执行器为例,其实现位于 `js-core/src/nodes/llm.ts`:
+
+```typescript
+export class LLMExecutor implements INodeExecutor {
+  public type = 'llm';
+
+  public async execute(context: ExecutionContext): Promise<ExecutionResult> {
+    const inputs = context.inputs as LLMExecutorInputs;
+
+    // 创建 LLM 提供商
+    const provider = this.createProvider(inputs);
+
+    // 准备提示词
+    const systemPrompt = inputs.systemPrompt || '';
+    const userPrompt = inputs.prompt || '';
+
+    // 调用 LLM
+    const result = await provider.call({
+      systemPrompt,
+      userPrompt,
+      options: {
+        temperature: inputs.temperature
+      }
+    });
+
+    // 返回结果
+    return {
+      outputs: {
+        result: result.content
+      }
+    };
+  }
+
+  private createProvider(inputs: LLMExecutorInputs): ILLMProvider {
+    // 根据模型名称创建不同的提供商
+    if (inputs.modelName.startsWith('gpt-')) {
+      return new OpenAIProvider({
+        apiKey: inputs.apiKey,
+        apiHost: inputs.apiHost,
+        modelName: inputs.modelName
+      });
+    }
+
+    throw new Error(`Unsupported model: ${inputs.modelName}`);
+  }
+}
+```
+
+### 变量管理
+
+变量管理是工作流执行的重要部分,负责处理节点间的数据传递。其主要实现位于 `js-core/src/domain/variable/` 目录。
+
+变量管理的核心是变量管理器和变量存储:
+
+- **变量管理器**:负责变量的解析、获取和设置
+- **变量存储**:提供变量的持久化存储
+
+关键代码片段:
+
+```typescript
+// 变量管理器
+export class VariableManager implements IVariableManager {
+  constructor(private store: IVariableStore) {}
+
+  // 解析变量引用
+  public async resolve(ref: ValueSchema, scope?: string): Promise<any> {
+    if (ref.type === 'constant') {
+      return ref.content;
+    } else if (ref.type === 'ref') {
+      const path = ref.content as string[];
+      return this.get(path, scope);
+    }
+    throw new Error(`Unsupported value type: ${ref.type}`);
+  }
+
+  // 获取变量值
+  public async get(path: string[], scope?: string): Promise<any> {
+    const [nodeID, key, ...rest] = path;
+    const value = await this.store.get(nodeID, key, scope);
+
+    if (rest.length === 0) {
+      return value;
+    }
+
+    // 处理嵌套属性
+    return this.getNestedProperty(value, rest);
+  }
+
+  // 设置变量值
+  public async set(nodeID: string, key: string, value: any, scope?: string): Promise<void> {
+    await this.store.set(nodeID, key, value, scope);
+  }
+}
+```
+
+### 状态存储
+
+状态存储负责管理工作流和节点的执行状态。其主要实现位于 `js-core/src/domain/status/` 和 `js-core/src/domain/snapshot/` 目录。
+
+状态管理的核心组件包括:
+
+- **状态中心**:管理工作流和节点的状态
+- **快照中心**:记录节点执行的快照
+- **报告中心**:生成工作流执行报告
+
+关键代码片段:
+
+```typescript
+// 状态中心
+export class StatusCenter implements IStatusCenter {
+  private workflowStatus: Record<string, WorkflowStatus> = {};
+  private nodeStatus: Record<string, Record<string, NodeStatus>> = {};
+
+  // 设置工作流状态
+  public setWorkflowStatus(workflowID: string, status: WorkflowStatus): void {
+    this.workflowStatus[workflowID] = status;
+  }
+
+  // 获取工作流状态
+  public getWorkflowStatus(workflowID: string): WorkflowStatus {
+    return this.workflowStatus[workflowID] || 'idle';
+  }
+
+  // 设置节点状态
+  public setNodeStatus(workflowID: string, nodeID: string, status: NodeStatus): void {
+    if (!this.nodeStatus[workflowID]) {
+      this.nodeStatus[workflowID] = {};
+    }
+    this.nodeStatus[workflowID][nodeID] = status;
+  }
+
+  // 获取节点状态
+  public getNodeStatus(workflowID: string, nodeID: string): NodeStatus {
+    return this.nodeStatus[workflowID]?.[nodeID] || 'idle';
+  }
+}
+```
+
+## 设计模式和架构决策
+
+### 领域驱动设计
+
+FlowGram Runtime 采用领域驱动设计(DDD)架构,将系统分为应用层、领域层和基础设施层。这种架构有助于分离关注点,使代码更加模块化和可维护。
+
+主要的领域概念包括:
+
+- **工作流**:表示一个完整的工作流定义
+- **节点**:工作流中的基本执行单元
+- **边**:连接节点的线,表示执行流程
+- **执行上下文**:工作流执行的环境
+- **变量**:工作流执行过程中的数据
+
+### 工厂模式
+
+FlowGram Runtime 使用工厂模式创建节点执行器,使系统能够根据节点类型动态创建对应的执行器。
+
+```typescript
+// 节点执行器工厂
+export class NodeExecutorFactory implements INodeExecutorFactory {
+  private executors: Record<string, INodeExecutor> = {};
+
+  // 注册节点执行器
+  public register(executor: INodeExecutor): void {
+    this.executors[executor.type] = executor;
+  }
+
+  // 创建节点执行器
+  public create(type: string): INodeExecutor {
+    const executor = this.executors[type];
+    if (!executor) {
+      throw new Error(`No executor registered for node type: ${type}`);
+    }
+    return executor;
+  }
+}
+```
+
+### 策略模式
+
+FlowGram Runtime 使用策略模式处理不同类型的节点执行逻辑,每种节点类型都有对应的执行策略。
+
+```typescript
+// 节点执行器接口(策略接口)
+export interface INodeExecutor {
+  type: string;
+  execute(context: ExecutionContext): Promise<ExecutionResult>;
+}
+
+// 具体策略实现
+export class StartExecutor implements INodeExecutor {
+  public type = 'start';
+
+  public async execute(context: ExecutionContext): Promise<ExecutionResult> {
+    // Start 节点的执行逻辑
+  }
+}
+
+export class EndExecutor implements INodeExecutor {
+  public type = 'end';
+
+  public async execute(context: ExecutionContext): Promise<ExecutionResult> {
+    // End 节点的执行逻辑
+  }
+}
+```
+
+### 观察者模式
+
+FlowGram Runtime 使用观察者模式实现事件系统,使组件能够发布和订阅事件。
+
+```typescript
+// 事件发布者
+export class EventEmitter implements IEventEmitter {
+  private listeners: Record<string, Function[]> = {};
+
+  // 订阅事件
+  public on(event: string, listener: Function): void {
+    if (!this.listeners[event]) {
+      this.listeners[event] = [];
+    }
+    this.listeners[event].push(listener);
+  }
+
+  // 发布事件
+  public emit(event: string, ...args: any[]): void {
+    const eventListeners = this.listeners[event];
+    if (eventListeners) {
+      for (const listener of eventListeners) {
+        listener(...args);
+      }
+    }
+  }
+}
+```
+
+### 依赖注入
+
+FlowGram Runtime 使用依赖注入管理组件之间的依赖关系,使组件更加松耦合和可测试。
+
+```typescript
+// 依赖注入容器
+export class Container {
+  private static _instance: Container;
+  private registry: Map<any, any> = new Map();
+
+  public static get instance(): Container {
+    if (!Container._instance) {
+      Container._instance = new Container();
+    }
+    return Container._instance;
+  }
+
+  // 注册服务
+  public register<T>(token: any, instance: T): void {
+    this.registry.set(token, instance);
+  }
+
+  // 获取服务
+  public resolve<T>(token: any): T {
+    const instance = this.registry.get(token);
+    if (!instance) {
+      throw new Error(`No instance registered for token: ${token}`);
+    }
+    return instance;
+  }
+}
+```
+
+## 添加新的节点类型 (WIP)
+
+要添加新的节点类型,需要实现 `INodeExecutor` 接口并注册到节点执行器工厂。
+
+步骤:
+
+1. 在 `js-core/src/nodes/` 目录下创建新的节点执行器文件
+2. 实现 `INodeExecutor` 接口
+3. 在 `js-core/src/nodes/index.ts` 中注册新的节点执行器
+
+示例:添加一个数据转换节点
+
+```typescript
+// js-core/src/nodes/transform.ts
+import { ExecutionContext, ExecutionResult, INodeExecutor } from '@flowgram.ai/runtime-interface';
+
+export interface TransformExecutorInputs {
+  data: any;
+  template: string;
+}
+
+export class TransformExecutor implements INodeExecutor {
+  public type = 'transform';
+
+  public async execute(context: ExecutionContext): Promise<ExecutionResult> {
+    const inputs = context.inputs as TransformExecutorInputs;
+
+    // 使用模板转换数据
+    const result = this.transform(inputs.data, inputs.template);
+
+    return {
+      outputs: {
+        result
+      }
+    };
+  }
+
+  private transform(data: any, template: string): any {
+    // 实现数据转换逻辑
+    // 这里只是一个简单的示例
+    return eval(`(data) => { return ${template} }`)(data);
+  }
+}
+
+// js-core/src/nodes/index.ts
+import { TransformExecutor } from './transform';
+
+// 将新的节点执行器添加到数组中
+WorkflowRuntimeNodeExecutors.push(new TransformExecutor());
+```
+
+## 单元测试
+
+FlowGram Runtime 使用 Vitest 进行单元测试。
+
+运行测试:
+
+```bash
+cd package/runtime/js-core
+npm run test
+```
+
+编写测试:
+
+```typescript
+// engine.test.ts
+import { WorkflowRuntimeEngine } from '../src/domain/engine';
+import { EngineServices } from '@flowgram.ai/runtime-interface';
+
+describe('WorkflowRuntimeEngine', () => {
+  let engine: WorkflowRuntimeEngine;
+
+  beforeEach(() => {
+    // 创建测试服务
+    const services: EngineServices = {
+      // 使用 mock 对象
+    };
+
+    engine = new WorkflowRuntimeEngine(services);
+  });
+
+  test('should execute workflow successfully', async () => {
+    // 准备测试数据
+    const schema = {
+      nodes: [
+        // 测试节点
+      ],
+      edges: [
+        // 测试边
+      ]
+    };
+
+    const inputs = {
+      prompt: 'Test prompt'
+    };
+
+    // 执行工作流
+    const result = await engine.run({ schema, inputs });
+
+    // 验证结果
+    expect(result.status).toBe('success');
+    expect(result.outputs).toBeDefined();
+  });
+});
+```