diff --git a/src/cleveragents/actor/schema.py b/src/cleveragents/actor/schema.py index 2fb3b169..8e3550df 100644 --- a/src/cleveragents/actor/schema.py +++ b/src/cleveragents/actor/schema.py @@ -37,6 +37,9 @@ Version: 3.0.0 from __future__ import annotations from enum import StrEnum +from typing import Any + +from pydantic import BaseModel, Field, field_validator class ActorType(StrEnum): @@ -114,8 +117,165 @@ class ContextView(StrEnum): FULL = "full" # Complete context (use sparingly) +# ============================================================================ +# Tool Models (for inline tool definitions in actors) +# ============================================================================ + + +class ToolParameter(BaseModel): + """ + Parameter definition for inline tool functions. + + Used in ToolDefinition to specify input parameters for Python code tools. + Supports type hints and default values for tool inputs. + + Attributes: + name: Parameter name (must be valid Python identifier) + type: Python type annotation as string (e.g., "str", "int", "list[str]") + description: Human-readable parameter description + required: Whether parameter must be provided (default: True) + default: Default value if not provided (only for optional params) + + Examples: + >>> param = ToolParameter( + ... name="input_file", + ... type="str", + ... description="Path to input file", + ... required=True + ... ) + """ + + name: str = Field(..., description="Parameter name") + type: str = Field(..., description="Python type annotation") + description: str = Field(..., description="Parameter description") + required: bool = Field(default=True, description="Whether required") + default: Any | None = Field(default=None, description="Default value") + + @field_validator("name") + @classmethod + def validate_name(cls, v: str) -> str: + """Ensure parameter name is a valid Python identifier.""" + if not v.isidentifier(): + msg = f"Parameter name must be valid Python identifier: {v}" + raise ValueError(msg) + return v + + +class ToolDefinition(BaseModel): + """ + Inline tool definition with Python code. + + Allows defining simple tools directly in actor YAML files without + creating separate tool modules. Useful for actor-specific utilities. + + Attributes: + name: Tool name (namespaced format: "namespace/tool_name") + description: What the tool does (used in LLM tool selection) + parameters: List of input parameters + code: Python code implementing the tool (must define a function) + + Examples: + >>> tool = ToolDefinition( + ... name="utils/count_lines", + ... description="Count lines in a file", + ... parameters=[ + ... ToolParameter(name="file_path", type="str", description="File") + ... ], + ... code="def count_lines(file_path: str) -> int:\\n ..." + ... ) + """ + + name: str = Field(..., description="Tool name (namespaced)") + description: str = Field(..., description="Tool description") + parameters: list[ToolParameter] = Field( + default_factory=list, description="Tool parameters" + ) + code: str = Field(..., description="Python code for tool") + + @field_validator("name") + @classmethod + def validate_name(cls, v: str) -> str: + """Ensure tool name follows namespace/name format.""" + if "/" not in v: + msg = f"Tool name must be namespaced (namespace/name): {v}" + raise ValueError(msg) + return v + + +# ============================================================================ +# Configuration Models (memory and context settings) +# ============================================================================ + + +class MemoryConfig(BaseModel): + """ + Conversation history and memory settings for actors. + + Controls how much conversation history is retained and passed to the LLM. + Balances context quality with token usage. + + Attributes: + enabled: Whether to maintain conversation history (default: True) + max_messages: Maximum messages to retain (None = unlimited) + max_tokens: Maximum tokens in history (None = unlimited) + summarize_old: Whether to summarize old messages (default: False) + + Examples: + >>> memory = MemoryConfig( + ... enabled=True, + ... max_messages=50, + ... max_tokens=4000 + ... ) + """ + + enabled: bool = Field(default=True, description="Enable conversation memory") + max_messages: int | None = Field(default=None, description="Max messages to retain") + max_tokens: int | None = Field(default=None, description="Max tokens in history") + summarize_old: bool = Field(default=False, description="Summarize old messages") + + +class ContextConfigSchema(BaseModel): + """ + File inclusion and context window configuration. + + Defines which files/directories to include in actor context and how + to manage the context window size. + + Attributes: + include_files: List of file paths to include in context + include_dirs: List of directory paths to include in context + exclude_patterns: Glob patterns to exclude from context + max_context_tokens: Maximum context window size (None = model default) + + Examples: + >>> context = ContextConfigSchema( + ... include_files=["README.md", "src/main.py"], + ... include_dirs=["src/", "tests/"], + ... exclude_patterns=["**/__pycache__/**", "*.pyc"], + ... max_context_tokens=8000 + ... ) + """ + + include_files: list[str] = Field( + default_factory=list, description="Files to include" + ) + include_dirs: list[str] = Field( + default_factory=list, description="Directories to include" + ) + exclude_patterns: list[str] = Field( + default_factory=list, description="Exclusion patterns" + ) + max_context_tokens: int | None = Field( + default=None, description="Max context tokens" + ) + + __all__ = [ "ActorType", + "ContextConfigSchema", "ContextView", + "MemoryConfig", "NodeType", + "ToolDefinition", + "ToolParameter", ]