Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.praison.ai/llms.txt

Use this file to discover all available pages before exploring further.

Schema validation catches broken custom tools at import time, before they confuse the LLM at runtime.

Quick Start

1

Automatic validation with @tool

from praisonaiagents import Agent, tool

@tool
def search(query: str) -> str:
    """Search the web."""
    return f"Results for: {query}"

# @tool already validated the schema for you.
agent = Agent(instructions="You search the web", tools=[search])
agent.start("Find AI news")
2

Explicit validation of a custom BaseTool

from praisonaiagents import BaseTool

class WeatherTool(BaseTool):
    name = "weather"
    description = "Get current weather"

    def run(self, location: str) -> str:
        return f"Weather in {location}: 72°F"

tool = WeatherTool()
tool.validate()                    # raises ToolValidationError on bad schema
tool.validate_schema_roundtrip()   # confirms JSON serializability
3

Validate a list of tools at once

from praisonaiagents.tools.base import validate_tool_schema_consistency

validate_tool_schema_consistency([search, WeatherTool(), my_other_tool])
# Raises if any tool is invalid OR if any two tools share a name.

How It Works

PhaseWhat Happens
@tool decorationValidates schema structure and JSON compatibility
Agent creationChecks for duplicate names across tool list
LLM interactionClean, validated schemas prevent runtime errors

What Gets Checked

CheckWhat it catches
parameters.type presentMissing schema scaffold
parameters.properties presentMost common OpenAI-incompatible bug
get_schema() returns {type: "function", function: {...}}Wrong top-level shape
function.parameters is a dict with propertiesInner shape broken
JSON round-trip preserves structureNon-serializable values (functions, sets, etc.)
required is a list when presentCommon typo (string instead of list)
Unique names across a listDuplicate registration

Common Errors & Fixes

Error: 'parameters' must have a 'properties' field for OpenAI compatibilityBroken Code:
class BadTool(BaseTool):
    name = "bad"
    description = "..."
    parameters = {"type": "object"}  # missing 'properties'
    
    def run(self, q: str) -> str: 
        return q
Fix:
class GoodTool(BaseTool):
    name = "good"
    description = "..."
    parameters = {
        "type": "object",
        "properties": {
            "q": {"type": "string"}
        },
        "required": ["q"]
    }
    
    def run(self, q: str) -> str: 
        return q
Error: get_schema() must return schema with type='function'Broken Code:
class BadTool(BaseTool):
    name = "bad"
    description = "..."
    
    def get_schema(self):
        return {"name": self.name}  # Wrong shape
    
    def run(self, q: str) -> str: 
        return q
Fix:
class GoodTool(BaseTool):
    name = "good"
    description = "..."
    
    def get_schema(self):
        return {
            "type": "function",
            "function": {
                "name": self.name,
                "description": self.description,
                "parameters": self.parameters
            }
        }
    
    def run(self, q: str) -> str: 
        return q
Error: Schema round-trip validation failedBroken Code:
from datetime import datetime

@tool
def process_data(data: str, timestamp=datetime.now()) -> str:
    """Process data with timestamp."""
    return f"{data} at {timestamp}"
Fix:
from datetime import datetime

@tool
def process_data(data: str, timestamp: str = None) -> str:
    """Process data with timestamp."""
    if timestamp is None:
        timestamp = datetime.now().isoformat()
    return f"{data} at {timestamp}"
Error: Duplicate tool name 'search' found in tool listBroken Code:
@tool(name="search")
def web_search(query: str) -> str:
    return "web results"

@tool(name="search")  # Same name!
def file_search(query: str) -> str:
    return "file results"

agent = Agent(tools=[web_search, file_search])  # Error
Fix:
@tool(name="web_search")
def web_search(query: str) -> str:
    return "web results"

@tool(name="file_search")  # Unique name
def file_search(query: str) -> str:
    return "file results"

agent = Agent(tools=[web_search, file_search])  # Works

Behavior of @tool Validation Failures

When the @tool decorator encounters validation errors, they are logged as warnings, not raised. The tool is still constructed, but may not work properly with the LLM.Check your logs for messages like:
Tool validation warning for my_tool: 'parameters' must have a 'properties' field for OpenAI compatibility
This early detection helps you fix schema issues during development instead of discovering them when the LLM calls the tool.

Custom Tools

Learn to create custom BaseTool and @tool implementations

Tool Reliability

Runtime error handling and tool safety patterns