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.

LLM failures are now raised as structured LLMError exceptions instead of returning None, enabling proper error handling and retry policies.

Quick Start

1

Handle LLM Errors

from praisonaiagents import Agent
from praisonaiagents.errors import LLMError

agent = Agent(
    name="Error Handler",
    instructions="Process user requests",
    on_error=lambda error: print(f"LLM failed: {error.message}")
)

try:
    result = agent.start("Hello world")
except LLMError as e:
    if e.is_retryable:
        print(f"Can retry: {e.message}")
    else:
        print(f"Fatal error: {e.message}")
2

Custom Error Classification

from praisonaiagents import Agent

def handle_llm_error(error):
    """Custom error handler with context logging"""
    print(f"Model: {error.model_name}")
    print(f"Agent: {error.agent_id}")
    print(f"Session: {error.session_id}")
    print(f"Retryable: {error.is_retryable}")

agent = Agent(
    name="Custom Handler",
    instructions="Process requests",
    on_error=handle_llm_error
)

How It Works

ComponentPurpose
LLMErrorStructured exception with retry classification
on_error HookIntercept errors before propagation
is_retryableBoolean flag for orchestration decisions
Context OverflowRecursive depth limit of 2

Error Classification

LLM errors are automatically classified as retryable or non-retryable based on error messages:

Retryable Errors

  • Rate limits: 429, rate limit, too many requests
  • Network issues: timeout, connection reset, socket error
  • Server errors: 500, 502, 503, 504, service unavailable
  • DNS/Network: dns, network, connection refused

Non-Retryable Errors

  • Authentication: 401, 403, unauthorized, invalid_api_key
  • Client errors: Most 4xx status codes

Default Behavior

Unknown errors default to is_retryable=True for resilience.

LLMError Structure

The LLMError class provides structured error information:
FieldTypeDescription
messagestrError description
model_namestrLLM model that failed
agent_idstrAgent identifier
session_idstrSession identifier
is_retryableboolWhether error can be retried
from praisonaiagents.errors import LLMError

# Error structure
error = LLMError(
    message="Rate limit exceeded",
    model_name="gpt-4",
    agent_id="research_agent",
    is_retryable=True,
    session_id="session_123"
)

Context Overflow Protection

LLM context overflow triggers automatic retry with truncated messages, limited to depth 2:
# Automatic context management
agent = Agent(
    name="Long Context Agent",
    instructions="Process very long inputs"
)

# Automatically handles context overflow:
# 1. First overflow: truncate and retry
# 2. Second overflow: truncate and retry  
# 3. Third overflow: raise LLMError with is_retryable=False

Migration Guide

Before (returned None):
response = agent._chat_completion(messages)
if response is None:
    # Handle failure
    print("LLM call failed")
After (raises LLMError):
try:
    response = agent._chat_completion(messages)
except LLMError as e:
    if e.is_retryable:
        # Orchestration will retry
        raise
    else:
        # Handle fatal error
        print(f"Fatal: {e.message}")

Best Practices

Implement the on_error hook to log errors without interrupting the retry flow:
def log_llm_errors(error):
    """Log errors for debugging without stopping retries"""
    import logging
    logging.error(f"LLM Error: {error.message} (retryable: {error.is_retryable})")

agent = Agent(on_error=log_llm_errors)
Authentication errors are non-retryable and need immediate attention:
def handle_auth_errors(error):
    if "401" in error.message or "invalid_api_key" in error.message:
        print("Check your API key configuration")
        # Could trigger key rotation logic here
Track error patterns to identify systemic issues:
error_counts = {"rate_limit": 0, "auth": 0, "network": 0}

def track_errors(error):
    if "rate limit" in error.message.lower():
        error_counts["rate_limit"] += 1
    elif "401" in error.message:
        error_counts["auth"] += 1
    # Send to monitoring system
Use error information to implement graceful degradation:
def fallback_handler(error):
    if error.model_name == "gpt-4" and error.is_retryable:
        # Could switch to backup model
        print("Switching to backup model")

Task Retry Policy

Configure task-level retry behavior

Hooks

Agent lifecycle hooks and events