ChatDev/entity/configs/node/loop_counter.py
2026-01-07 16:24:01 +08:00

80 lines
2.5 KiB
Python
Executable File

"""Configuration for loop counter guard nodes."""
from dataclasses import dataclass
from typing import Mapping, Any, Optional
from entity.configs.base import (
BaseConfig,
ConfigError,
ConfigFieldSpec,
require_mapping,
extend_path,
optional_str,
)
@dataclass
class LoopCounterConfig(BaseConfig):
"""Configuration schema for the loop counter node type."""
max_iterations: int = 10
reset_on_emit: bool = True
message: Optional[str] = None
@classmethod
def from_dict(cls, data: Mapping[str, Any] | None, *, path: str) -> "LoopCounterConfig":
mapping = require_mapping(data or {}, path)
max_iterations_raw = mapping.get("max_iterations", 10)
try:
max_iterations = int(max_iterations_raw)
except (TypeError, ValueError) as exc: # pragma: no cover - defensive
raise ConfigError(
"max_iterations must be an integer",
extend_path(path, "max_iterations"),
) from exc
if max_iterations < 1:
raise ConfigError("max_iterations must be >= 1", extend_path(path, "max_iterations"))
reset_on_emit = bool(mapping.get("reset_on_emit", True))
message = optional_str(mapping, "message", path)
return cls(
max_iterations=max_iterations,
reset_on_emit=reset_on_emit,
message=message,
path=path,
)
def validate(self) -> None:
if self.max_iterations < 1:
raise ConfigError("max_iterations must be >= 1", extend_path(self.path, "max_iterations"))
FIELD_SPECS = {
"max_iterations": ConfigFieldSpec(
name="max_iterations",
display_name="Maximum Iterations",
type_hint="int",
required=True,
default=10,
description="How many times the loop can run before this node emits an output.",
),
"reset_on_emit": ConfigFieldSpec(
name="reset_on_emit",
display_name="Reset After Emit",
type_hint="bool",
required=False,
default=True,
description="Whether to reset the internal counter after reaching the limit.",
advance=True,
),
"message": ConfigFieldSpec(
name="message",
display_name="Release Message",
type_hint="text",
required=False,
description="Optional text sent downstream once the iteration cap is reached.",
advance=True,
),
}