Tool Parameter Types

Use Optional, Union, Literal, Enum, List and Dict in tool signatures and the agent sees the right schema

Use expressive Python type annotations in tool signatures and agents understand exactly what parameters they can pass.

python
from typing import Literal
from praisonaiagents import Agent, tool

@tool
def analyse(text: str, mode: Literal["fast", "deep"] = "fast") -> str:
    """Analyse text with a fast or deep mode."""
    return f"{mode} analysis of: {text}"

agent = Agent(name="Analyst", tools=[analyse])
agent.start("Analyse this document in deep mode")

The user asks the agent to call a typed tool; annotations become JSON Schema so the model passes valid parameters.

Diagram

Tool Parameter Type System

Python Annotation

annotation_to_json_schema

JSON Schema

LLM Tool Schema

Quick Start

  1. Optional Parameter

    Create a tool where parameters can be omitted by the agent:

    python
    from typing import Optional
    from praisonaiagents import Agent, tool
    
    @tool
    def search(query: str, max_results: Optional[int] = None) -> str:
        """Search the web. Leave max_results blank to use the default."""
        limit = max_results or 10
        return f"Searched '{query}' (limit={limit})"
    
    agent = Agent(
        instructions="You search the web for information",
        tools=[search]
    )
    
    agent.start("Find AI news")
  2. Literal for Fixed Choices

    Restrict parameter values to specific literal options:

    python
    from typing import Literal
    from praisonaiagents import Agent, tool
    
    @tool
    def analyze(text: str, mode: Literal["fast", "deep"] = "fast") -> str:
        """Analyze text with different modes."""
        if mode == "deep":
            return f"Deep analysis of: {text}"
        return f"Quick analysis of: {text}"
    
    agent = Agent(
        instructions="You analyze text content",
        tools=[analyze]
    )
    
    agent.start("Analyze this document in deep mode")
  3. Enum for Choices

    Use Enum classes for reusable choice sets across tools:

    python
    from enum import Enum
    from praisonaiagents import Agent, tool
    
    class Priority(str, Enum):
        LOW = "low"
        MEDIUM = "medium"
        HIGH = "high"
    
    @tool
    def create_task(title: str, priority: Priority = Priority.MEDIUM) -> str:
        """Create a new task with specified priority."""
        return f"Created task '{title}' with priority: {priority.value}"
    
    agent = Agent(
        instructions="You manage tasks",
        tools=[create_task]
    )
    
    agent.start("Create a high priority task for the meeting")

How It Works

The agent converts your Python type annotations into JSON Schema before the LLM sees the tool definition.

Python AnnotationJSON Schema Output
str, int, float, bool{"type": "string"} and related primitives
Optional[int]{"anyOf": [{"type": "integer"}, {"type": "null"}]}
Union[str, int]{"anyOf": [{"type": "string"}, {"type": "integer"}]}
Literal["fast", "deep"]{"type": "string", "enum": ["fast", "deep"]}
Enum subclass (str-valued){"type": "string", "enum": ["low", "medium", "high"]}
List[int]{"type": "array", "items": {"type": "integer"}}
Dict[str, int]{"type": "object", "additionalProperties": {"type": "integer"}}

Common Patterns

Mode Flags with Defaults

python
@tool
def process_data(data: str, mode: Literal["fast", "thorough"] = "fast") -> str:
    """Process data with different thoroughness levels."""
    if mode == "thorough":
        return f"Thoroughly processed: {data}"
    return f"Quick processing: {data}"

Shared Choice Sets

python
class Format(str, Enum):
    JSON = "json"
    CSV = "csv"
    XML = "xml"

@tool
def export_data(data: str, format: Format) -> str:
    """Export data in specified format."""
    return f"Exported as {format.value}: {data}"

@tool
def import_data(file_path: str, format: Format) -> str:
    """Import data from specified format."""
    return f"Imported {format.value} file: {file_path}"

Structured Collections

python
from typing import List, Dict

@tool
def batch_process(items: List[str], config: Dict[str, str]) -> str:
    """Process multiple items with configuration."""
    return f"Processed {len(items)} items with config: {config}"

Best Practices

Prefer Optional types over bare parameters

Use Optional[int] with a default of None instead of leaving parameters untyped. This tells the agent the parameter can be omitted and what type to use when provided.

python
# Good
def search(query: str, limit: Optional[int] = None) -> str:
    pass

# Avoid
def search(query: str, limit=None) -> str:
    pass
Use Literal for small fixed sets, Enum for reusable choices

Choose Literal[...] when values are unique to one tool. Use Enum when the same choices appear across multiple tools.

python
# Literal for one-off choices
def analyze(text: str, depth: Literal["surface", "deep"] = "surface"):
    pass

# Enum for shared choices
class Priority(str, Enum):
    LOW = "low"
    HIGH = "high"

def create_task(title: str, priority: Priority):
    pass

def update_task(id: str, priority: Priority):
    pass
Avoid Union for unrelated types

Don’t use Union[str, dict] for “either a string or a dict” – the LLM struggles with such choices. Create separate tools instead.

python
# Avoid
def process(input: Union[str, Dict[str, str]]):
    pass

# Prefer
def process_text(text: str):
    pass

def process_data(data: Dict[str, str]):
    pass
Parameterize your collections

Write List[str] instead of bare list so the agent knows what elements to include.

python
# Good - agent knows to pass strings
def process_items(items: List[str]) -> str:
    pass

# Avoid - agent doesn't know element type
def process_items(items: list) -> str:
    pass

Related