Type Reference

Type definitions, data structures, and type hints used in Agent Patterns.

Core Types

LLM Configuration Types

LLMConfig

from typing import TypedDict, Literal

class LLMConfig(TypedDict, total=False):
    """Configuration for a single LLM role."""
    provider: Literal["openai", "anthropic"]
    model_name: str
    temperature: float      # Optional, default: 0.7
    max_tokens: int        # Optional, default: 2000

Example:

llm_config: LLMConfig = {
    "provider": "openai",
    "model_name": "gpt-4-turbo",
    "temperature": 0.7,
    "max_tokens": 2000,
}

LLMConfigs

from typing import Dict, Any

LLMConfigs = Dict[str, Dict[str, Any]]

Example:

llm_configs: LLMConfigs = {
    "thinking": {
        "provider": "openai",
        "model_name": "gpt-4-turbo",
    },
    "reflection": {
        "provider": "anthropic",
        "model_name": "claude-3-5-sonnet-20241022",
    },
}

Prompt Types

PromptDict

from typing import TypedDict

class PromptDict(TypedDict):
    """Prompt templates for a step."""
    system: str
    user: str

Example:

prompt: PromptDict = {
    "system": "You are a helpful assistant.",
    "user": "Task: {task}\n\nPlease help."
}

PromptOverrides

from typing import Dict

PromptOverrides = Dict[str, PromptDict]

Example:

overrides: PromptOverrides = {
    "ThoughtStep": {
        "system": "Think carefully.",
        "user": "Question: {input}"
    },
    "ActionStep": {
        "system": "Execute precisely.",
        "user": "Action: {action}"
    }
}

Tool Types

ToolFunction

from typing import Callable

ToolFunction = Callable[[str], str]

Example:

def search_tool(query: str) -> str:
    return f"Results for: {query}"

my_tool: ToolFunction = search_tool

ToolDict

from typing import Dict, Callable

ToolDict = Dict[str, Callable]

Example:

tools: ToolDict = {
    "search": search_tool,
    "calculator": calc_tool,
    "database": db_tool,
}

State Types

State

Generic state dictionary:

from typing import Dict, Any

State = Dict[str, Any]

Example:

state: State = {
    "input": "user query",
    "output": None,
    "iteration": 0,
}

Pattern-Specific State Types

ReActState:

from typing import TypedDict, List, Tuple, Optional

class ReActState(TypedDict):
    input: str
    thought: str
    action: Dict[str, str]
    observation: Any
    intermediate_steps: List[Tuple[str, Dict, Any]]
    final_answer: Optional[str]
    iteration_count: int
    max_iterations: int

ReflectionState:

class ReflectionState(TypedDict):
    input_task: str
    initial_output: Optional[str]
    reflection: Optional[str]
    refined_output: Optional[str]
    needs_refinement: bool
    final_answer: Optional[str]
    reflection_cycle: int
    max_reflection_cycles: int
    continue_reflection: bool

PlanAndSolveState:

class PlanAndSolveState(TypedDict):
    input_task: str
    plan: List[Dict[str, str]]
    current_step_index: int
    step_results: List[str]
    plan_done: bool
    final_result: Optional[str]

Action Types

Action

from typing import TypedDict

class Action(TypedDict):
    """Tool invocation specification."""
    tool_name: str
    tool_input: str

Example:

action: Action = {
    "tool_name": "search",
    "tool_input": "Python programming"
}

Result Types

AgentResult

from typing import Union

AgentResult = Union[str, Dict[str, Any]]

Most patterns return strings, but some may return structured data.

Pattern-Specific Types

ReAct Pattern

from typing import List, Tuple, Dict, Any, Optional

# Intermediate step: (thought, action, observation)
IntermediateStep = Tuple[str, Dict[str, str], Any]

class ReActConfig(TypedDict, total=False):
    llm_configs: Dict[str, Dict[str, Any]]
    tools: Dict[str, Callable[[str], str]]
    max_iterations: int
    prompt_dir: str
    custom_instructions: Optional[str]
    prompt_overrides: Optional[Dict[str, Dict[str, str]]]

Reflection Pattern

class ReflectionConfig(TypedDict, total=False):
    llm_configs: Dict[str, Dict[str, Any]]
    max_reflection_cycles: int
    prompt_dir: str
    custom_instructions: Optional[str]
    prompt_overrides: Optional[Dict[str, Dict[str, str]]]

Self-Discovery Pattern

from typing import List, Dict

class ReasoningModule(TypedDict):
    """Reasoning strategy definition."""
    name: str
    description: str
    template: str

class SelfDiscoveryConfig(TypedDict, total=False):
    llm_configs: Dict[str, Dict[str, Any]]
    reasoning_modules: Optional[List[ReasoningModule]]
    max_selected_modules: int
    prompt_dir: str
    custom_instructions: Optional[str]
    prompt_overrides: Optional[Dict[str, Dict[str, str]]]

STORM Pattern

class Perspective(TypedDict):
    """Viewpoint for multi-perspective analysis."""
    name: str
    description: str

class STORMConfig(TypedDict, total=False):
    llm_configs: Dict[str, Dict[str, Any]]
    retrieval_tools: Optional[Dict[str, Callable]]
    perspectives: Optional[List[Perspective]]
    prompt_dir: str
    custom_instructions: Optional[str]
    prompt_overrides: Optional[Dict[str, Dict[str, str]]]

LangChain/LangGraph Types

LLM Types

from langchain_core.language_models.chat_models import BaseChatModel
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic

# Base type for all chat models
LLMType = BaseChatModel

# Specific implementations
OpenAIModel = ChatOpenAI
AnthropicModel = ChatAnthropic

Message Types

from langchain_core.messages import (
    BaseMessage,
    SystemMessage,
    HumanMessage,
    AIMessage,
)

MessageType = BaseMessage
Messages = List[BaseMessage]

Example:

messages: Messages = [
    SystemMessage(content="You are helpful."),
    HumanMessage(content="Hello!"),
    AIMessage(content="Hi there!"),
]

Graph Types

from langgraph.graph.state import CompiledStateGraph
from langgraph.graph import StateGraph

Graph = CompiledStateGraph
GraphBuilder = StateGraph

Utility Types

Optional and Union

from typing import Optional, Union

# Optional value (can be None)
MaybeString = Optional[str]
MaybeConfig = Optional[Dict[str, Any]]

# Union of types
StringOrDict = Union[str, Dict[str, Any]]
IntOrFloat = Union[int, float]

Callable Types

from typing import Callable, Any

# Function signatures
EvaluatorFunction = Callable[[Any], bool]
ToolFunction = Callable[[str], str]
ProcessorFunction = Callable[[Dict], Dict]

Examples:

def my_evaluator(result: Any) -> bool:
    return len(result) > 0

def my_tool(input: str) -> str:
    return f"Processed: {input}"

def my_processor(state: Dict) -> Dict:
    state["processed"] = True
    return state

evaluator: EvaluatorFunction = my_evaluator
tool: ToolFunction = my_tool
processor: ProcessorFunction = my_processor

Generic Types

from typing import TypeVar, Generic, List, Dict

T = TypeVar('T')
K = TypeVar('K')
V = TypeVar('V')

# Generic list
GenericList = List[T]

# Generic dict
GenericDict = Dict[K, V]

Type Checking

Runtime Type Checking

from typing import get_type_hints

def validate_config(config: LLMConfig) -> bool:
    """Validate LLM configuration."""
    required = {"provider", "model_name"}
    return all(key in config for key in required)

Type Guards

from typing import TypeGuard

def is_llm_config(obj: Any) -> TypeGuard[LLMConfig]:
    """Check if object is valid LLM config."""
    return (
        isinstance(obj, dict) and
        "provider" in obj and
        "model_name" in obj
    )

Type Hints in Practice

Function Signatures

from typing import Dict, List, Optional, Any

def create_agent(
    llm_configs: LLMConfigs,
    tools: Optional[ToolDict] = None,
    max_iterations: int = 5
) -> BaseAgent:
    """Create agent with type hints."""
    pass

def process_state(
    state: State,
    llm: BaseChatModel
) -> State:
    """Process state with LLM."""
    pass

def format_messages(
    system_prompt: str,
    user_prompt: str
) -> List[BaseMessage]:
    """Format prompts into messages."""
    pass

Class Type Hints

from typing import Dict, Optional, Any

class MyAgent(BaseAgent):
    """Agent with proper type hints."""

    def __init__(
        self,
        llm_configs: LLMConfigs,
        custom_param: Optional[str] = None
    ) -> None:
        self.custom_param: Optional[str] = custom_param
        super().__init__(llm_configs=llm_configs)

    def build_graph(self) -> None:
        """Build graph (no return value)."""
        pass

    def run(self, input_data: str) -> str:
        """Run agent (returns string)."""
        return "result"

    def _helper(
        self,
        state: State,
        param: Optional[int] = None
    ) -> State:
        """Helper method with types."""
        return state

Type Aliases

Create readable aliases:

from typing import Dict, List, Tuple, Callable

# Configuration aliases
AgentConfig = Dict[str, Any]
ModelConfig = Dict[str, Any]

# State aliases
AgentState = Dict[str, Any]
WorkflowState = Dict[str, Any]

# Function aliases
StateProcessor = Callable[[AgentState], AgentState]
Evaluator = Callable[[Any], bool]
ToolCall = Callable[[str], str]

# Complex types
StepHistory = List[Tuple[str, Dict, Any]]
PlanSteps = List[Dict[str, str]]

Usage:

def process_workflow(
    state: WorkflowState,
    config: AgentConfig,
    processor: StateProcessor
) -> WorkflowState:
    """Process workflow with typed parameters."""
    return processor(state)

mypy Configuration

For type checking with mypy:

# mypy.ini or pyproject.toml
[tool.mypy]
python_version = "3.10"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
check_untyped_defs = true
ignore_missing_imports = true

Run type checking:

mypy agent_patterns/

Type Stubs

For third-party libraries without types:

# stubs/external_lib.pyi
from typing import Any, Dict

def external_function(param: str) -> Dict[str, Any]: ...

class ExternalClass:
    def __init__(self, config: Dict[str, Any]) -> None: ...
    def process(self, data: str) -> str: ...

Best Practices

1. Always Use Type Hints

# Good
def process(data: str, config: Dict[str, Any]) -> str:
    return data.upper()

# Bad
def process(data, config):
    return data.upper()

2. Use Optional for Nullable Values

# Good
def get_value(key: str) -> Optional[str]:
    return cache.get(key)

# Bad
def get_value(key: str) -> str:
    return cache.get(key)  # Could return None!

3. Use TypedDict for Structured Dicts

# Good
class Config(TypedDict):
    name: str
    value: int

# Bad
Config = Dict[str, Any]

4. Document Complex Types

from typing import Dict, List, Tuple

# Document meaning
StepHistory = List[Tuple[
    str,         # thought
    Dict,        # action
    Any          # observation
]]

See Also