feat(workflow): support variable types(TODO)

This commit is contained in:
mengyonghao
2026-01-05 10:49:30 +08:00
parent 184150810b
commit 373b91143d

View File

@@ -4,13 +4,16 @@
""" """
from enum import StrEnum from enum import StrEnum
from typing import Any
from pydantic import BaseModel, Field from pydantic import BaseModel, Field, ConfigDict
VARIABLE_PATTERN = r"\{\{\s*(.*?)\s*\}\}"
class VariableType(StrEnum): class VariableType(StrEnum):
"""变量类型枚举""" """变量类型枚举"""
STRING = "string" STRING = "string"
NUMBER = "number" NUMBER = "number"
BOOLEAN = "boolean" BOOLEAN = "boolean"
@@ -22,43 +25,94 @@ class VariableType(StrEnum):
ARRAY_OBJECT = "array[object]" ARRAY_OBJECT = "array[object]"
class TypedVariable(BaseModel):
"""
TODO: 强类型限制
Strongly typed variable that validates value on assignment.
"""
value: Any = Field(..., description="Variable value")
type: VariableType = Field(..., description="Declared type of the variable")
model_config = ConfigDict(
validate_assignment=True
)
def __setattr__(self, name, value):
if name == "value":
self._validate_value(value)
if name == "type":
raise RuntimeError("Cannot modify variable type at runtime")
super().__setattr__(name, value)
def _validate_value(self, v: Any):
t = self.type
match t:
case VariableType.STRING:
if not isinstance(v, str):
raise TypeError("Variable value does not match type STRING")
case VariableType.BOOLEAN:
if not isinstance(v, bool):
raise TypeError("Variable value does not match type BOOLEAN")
case VariableType.NUMBER:
if not isinstance(v, (int, float)):
raise TypeError("Variable value does not match type NUMBER")
case VariableType.OBJECT:
if not isinstance(v, dict):
raise TypeError("Variable value does not match type OBJECT")
case VariableType.ARRAY_STRING:
if not isinstance(v, list) or not all(isinstance(i, str) for i in v):
raise TypeError("Variable value does not match type ARRAY_STRING")
case VariableType.ARRAY_NUMBER:
if not isinstance(v, list) or not all(isinstance(i, (int, float)) for i in v):
raise TypeError("Variable value does not match type ARRAY_NUMBER")
case VariableType.ARRAY_BOOLEAN:
if not isinstance(v, list) or not all(isinstance(i, bool) for i in v):
raise TypeError("Variable value does not match type ARRAY_BOOLEAN")
case VariableType.ARRAY_OBJECT:
if not isinstance(v, list) or not all(isinstance(i, dict) for i in v):
raise TypeError("Variable value does not match type ARRAY_OBJECT")
case _:
raise TypeError(f"Unknown variable type: {t}")
class VariableDefinition(BaseModel): class VariableDefinition(BaseModel):
"""变量定义 """变量定义
定义工作流或节点的输入/输出变量。 定义工作流或节点的输入/输出变量。
这是一个通用的数据结构,可以在多个地方使用。 这是一个通用的数据结构,可以在多个地方使用。
""" """
name: str = Field( name: str = Field(
..., ...,
description="变量名称" description="变量名称"
) )
type: VariableType = Field( type: VariableType = Field(
default=VariableType.STRING, default=VariableType.STRING,
description="变量类型" description="变量类型"
) )
required: bool = Field( required: bool = Field(
default=False, default=False,
description="是否必需" description="是否必需"
) )
default: str | int | float | bool | list | dict | None = Field( default: str | int | float | bool | list | dict | None = Field(
default=None, default=None,
description="默认值" description="默认值"
) )
description: str | None = Field( description: str | None = Field(
default=None, default=None,
description="变量描述" description="变量描述"
) )
max_length: int = Field( max_length: int = Field(
default=200, default=200,
description="只对字符串类型生效" description="只对字符串类型生效"
) )
class Config: class Config:
json_schema_extra = { json_schema_extra = {
"examples": [ "examples": [
@@ -96,22 +150,22 @@ class BaseNodeConfig(BaseModel):
- description: 节点描述 - description: 节点描述
- tags: 节点标签(用于分类和搜索) - tags: 节点标签(用于分类和搜索)
""" """
name: str | None = Field( name: str | None = Field(
default=None, default=None,
description="节点名称(显示名称),如果不设置则使用节点 ID" description="节点名称(显示名称),如果不设置则使用节点 ID"
) )
description: str | None = Field( description: str | None = Field(
default=None, default=None,
description="节点描述,说明节点的作用" description="节点描述,说明节点的作用"
) )
tags: list[str] = Field( tags: list[str] = Field(
default_factory=list, default_factory=list,
description="节点标签,用于分类和搜索" description="节点标签,用于分类和搜索"
) )
class Config: class Config:
"""Pydantic 配置""" """Pydantic 配置"""
# 允许额外字段(向后兼容) # 允许额外字段(向后兼容)