Files
LangBot/src/langbot/pkg/workflow/nodes/loop.py
2026-05-05 15:08:04 +08:00

63 lines
2.2 KiB
Python

"""Loop Node - iterate over items"""
from __future__ import annotations
from typing import Any, ClassVar
from ..entities import ExecutionContext
from ..node import WorkflowNode, workflow_node, NodePort, NodeConfig
@workflow_node('loop')
class LoopNode(WorkflowNode):
"""Loop node - iterate over items"""
type_name = "loop"
category = "control"
icon = "🔁"
name = "loop"
name_zh = "循环"
name_en = "Loop"
description = "loop"
description_zh = "遍历项目或重复直到满足条件"
description_en = "Iterate over items or repeat until condition"
inputs: ClassVar[list[NodePort]] = [
NodePort(name="items", type="array", description="Items to iterate over", required=False),
]
outputs: ClassVar[list[NodePort]] = [
NodePort(name="item", type="any", description="Current item in iteration"),
NodePort(name="index", type="number", description="Current iteration index"),
NodePort(name="results", type="array", description="All iteration results"),
NodePort(name="completed", type="boolean", description="Whether loop completed"),
]
config_schema: ClassVar[list[NodeConfig]] = [
NodeConfig(
name="loop_type", type="select", required=True, default="foreach",
description="Type of loop",
label={"en_US": "Loop Type", "zh_Hans": "循环类型"},
options=["foreach", "while", "count"],
),
NodeConfig(
name="max_iterations", type="integer", required=False, default=100,
description="Maximum iterations (safety limit)",
label={"en_US": "Max Iterations", "zh_Hans": "最大迭代次数"},
),
]
async def execute(self, inputs: dict[str, Any], context: ExecutionContext) -> dict[str, Any]:
items = inputs.get("items", [])
if not isinstance(items, list):
items = [items] if items else []
max_iterations = self.get_config("max_iterations", 100)
items = items[:max_iterations]
return {
"item": items[0] if items else None,
"index": 0,
"results": [],
"completed": len(items) == 0,
"_items": items,
}