Framework Integrations
Integrate AgentSudo with popular AI agent frameworks.
AgentSudo is framework-agnostic—the core @sudo decorator works with any Python function. Just stack it with your framework's decorator.
LangChain
from langchain.tools import tool
from agentsudo import Agent, sudo
@tool
@sudo(scope="orders:read")
def get_order(order_id: str) -> dict:
"""Retrieve order details by ID."""
return {"order_id": order_id, "status": "shipped"}
agent = Agent(name="SupportBot", scopes=["orders:read"])
with agent.start_session():
result = get_order.invoke({"order_id": "123"})
LlamaIndex
from llama_index.core.tools import FunctionTool
from agentsudo import Agent, sudo
@sudo(scope="email:write")
def send_email(to: str, subject: str) -> dict:
"""Send an email."""
return {"sent": True, "to": to}
email_tool = FunctionTool.from_defaults(fn=send_email)
agent = Agent(name="EmailBot", scopes=["email:write"])
with agent.start_session():
response = email_tool.call(to="bob@example.com", subject="Hello")
FastAPI
For REST APIs, use the FastAPI adapter for HTTP header-based agent authentication:
from fastapi import FastAPI, Depends
from agentsudo import Agent
from agentsudo.adapters.fastapi import AgentSudoMiddleware, require_scope, register_agent
app = FastAPI()
reader = Agent(name="ReaderBot", scopes=["read:*"])
register_agent(reader, "reader-001")
app.add_middleware(AgentSudoMiddleware, agent_header="X-Agent-ID")
@app.get("/orders/{order_id}")
async def get_order(order_id: str, agent = Depends(require_scope("read:orders"))):
return {"order_id": order_id, "agent": agent.name}
curl -H "X-Agent-ID: reader-001" http://localhost:8000/orders/123
CrewAI
from crewai import Crew, Agent as CrewAgent, Task
from agentsudo import Agent, sudo
@sudo(scope="write:refunds")
def refund_order(order_id: str, amount: float) -> dict:
return {"status": "refunded", "order_id": order_id, "amount": amount}
support_crew_agent = CrewAgent(
role="Customer Support",
goal="Help customers with refunds",
tools=[refund_order]
)
task = Task(description="Process refund for order 456", agent=support_crew_agent)
crew = Crew(agents=[support_crew_agent], tasks=[task])
agentsudo_agent = Agent(name="CrewSupportBot", scopes=["write:refunds"])
with agentsudo_agent.start_session():
result = crew.kickoff()
AutoGen
from autogen import AssistantAgent, UserProxyAgent
from agentsudo import Agent, sudo
@sudo(scope="db:read")
def fetch_user(user_id: str) -> dict:
return {"user_id": user_id, "name": "Alice"}
assistant = AssistantAgent(name="assistant", llm_config={"model": "gpt-4"})
assistant.register_for_execution(fetch_user)
user_proxy = UserProxyAgent(name="user", human_input_mode="NEVER")
db_agent = Agent(name="DBAgent", scopes=["db:read"])
with db_agent.start_session():
user_proxy.initiate_chat(assistant, message="Get user 123")
Custom Frameworks
from agentsudo import Agent, sudo
@sudo(scope="action:perform")
def my_tool(param: str) -> str:
"""Your custom tool."""
return f"Result: {param}"
agent = Agent(name="CustomBot", scopes=["action:perform"])
with agent.start_session():
result = my_tool("test") # Works with ANY Python code
Best Practices
1. Scope Naming Convention
Use consistent scope names across frameworks:
# ✅ Good - consistent pattern
"orders:read"
"orders:write"
"refunds:create"
# ❌ Bad - inconsistent
"get_orders"
"writeOrder"
"REFUND_CREATE"
2. Wrap Framework Execution
Always wrap framework execution in an AgentSudo session:
agent = Agent(name="MyAgent", scopes=["..."])
with agent.start_session():
# All tool calls within this block are permission-checked
result = framework_agent.run(input)
3. Handle Permission Errors
Gracefully handle denied permissions:
from agentsudo import PermissionDeniedError
try:
result = agent_executor.invoke({"input": query})
except PermissionDeniedError as e:
# Log the denial
logger.warning(f"Permission denied: {e}")
# Return helpful message to user
return "I don't have permission to perform that action."