Skip to main content
PraisonAI provides two mechanisms for responding to agent events: Hooks (control flow) and Callbacks (observation). Understanding the difference is key to building effective integrations.

Hooks (Control)

Intercept and modify agent behavior. Can allow, deny, or block execution.

Callbacks (Observe)

Receive notifications about events. Cannot modify or block execution.

Quick Comparison

FeatureHooksCallbacks
PurposeControl flowObservation
Can modify input?✅ Yes❌ No
Can block execution?✅ Yes❌ No
Return value matters?✅ Yes (decisions)❌ No
When usedBefore/during executionAfter events
Typical useValidation, policies, guardrailsLogging, UI, monitoring

When to Use Each

You need to control behavior:
from praisonaiagents.hooks import add_hook, HookResult

@add_hook('before_tool')
def block_dangerous_tools(event):
    if event.tool_name == "delete_file":
        return HookResult.deny("Deletion not allowed")
    return HookResult.allow()
Examples:
  • Block specific tool calls
  • Modify prompts before LLM
  • Validate tool arguments
  • Implement rate limiting
  • Enforce security policies

Code Examples

Hook: Block and Modify

from praisonaiagents import Agent
from praisonaiagents.hooks import add_hook, HookResult

# Block dangerous tools
@add_hook('before_tool')
def security_policy(event):
    blocked = ["delete_file", "execute_command"]
    if event.tool_name in blocked:
        return HookResult.deny(f"Tool '{event.tool_name}' is blocked")
    return HookResult.allow()

# Modify prompt before LLM
@add_hook('before_llm')
def add_context(event):
    event.prompt = f"[System: Be helpful and safe]\n{event.prompt}"
    return HookResult.allow()

agent = Agent(name="safe_agent", instructions="You help users")
agent.start("Delete all files")  # Blocked by hook

Callback: Log and Notify

from praisonaiagents import Agent, Task, register_display_callback
import logging

logging.basicConfig(filename='agent.log', level=logging.INFO)

# Log all interactions
def log_callback(message=None, response=None, **kwargs):
    logging.info(f"User: {message}")
    logging.info(f"Agent: {response}")

register_display_callback('interaction', log_callback)

# Task completion callback
def task_done(output):
    print(f"✅ Task completed: {output.description}")

task = Task(
    description="Say hello",
    on_task_complete=task_done  # Callback on completion
)

Decision Flow


Hook Decisions

Hooks return HookResult with a decision:
DecisionEffect
allow()Execution proceeds normally
deny(reason)Execution blocked, error returned
block()Silent block, no error
ask(prompt)Request human confirmation
from praisonaiagents.hooks import HookResult

# Allow (default)
return HookResult.allow()

# Deny with reason
return HookResult.deny("Not permitted by policy")

# Ask user for confirmation
return HookResult.ask("Are you sure you want to delete?")

Summary Table

ScenarioUseExample
Block tools based on policyHookHookResult.deny()
Log all interactionsCallbackregister_display_callback()
Modify prompt before LLMHookModify event.prompt
Show progress in UICallbackDisplay callback
Validate tool argumentsHookCheck args, return allow/deny
Track completionCallbackon_task_complete
Rate limit callsHookCount and deny after limit
Send webhook notificationsCallbackHTTP POST in callback