When integrating your custom FastAPI application with AgentOS, route conflicts can occur if both your app and AgentOS define the same endpoint paths. For example, both might define a /health endpoint or a root / route.
AgentOS provides the on_route_conflict parameter to control how these conflicts are resolved, allowing you to choose whether your custom routes or AgentOS routes take precedence.
When to Use
Override routes when you need:
- Custom health checks: Replace AgentOS’s
/health endpoint with your own monitoring logic
- Branded landing pages: Serve a custom homepage at
/ instead of the default AgentOS interface
- Custom authentication: Implement your own auth endpoints that conflict with AgentOS defaults
- API versioning: Control which version of an endpoint is exposed
- Custom error handlers: Define specialized error handling for specific routes
Configuration Options
AgentOS provides two values for the on_route_conflict parameter for handling route conflicts:
| Option | Custom Routes | AgentOS Routes | Warnings Logged |
|---|
preserve_base_app | ✓ Preserved | ✗ Skipped (conflicts only) | Yes |
preserve_agentos (default) | ✗ Overridden | ✓ Preserved | Yes |
Non-conflicting routes from both your app and AgentOS are always included regardless of the mode.
Example
This example demonstrates using on_route_conflict="preserve_base_app" to preserve custom routes for the home page and health endpoint.
from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.models.anthropic import Claude
from agno.os import AgentOS
from agno.tools.duckduckgo import DuckDuckGoTools
from fastapi import FastAPI
# Set up the database
db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")
web_research_agent = Agent(
id="web-research-agent",
name="Web Research Agent",
model=Claude(id="claude-sonnet-4-0"),
db=db,
tools=[DuckDuckGoTools()],
add_history_to_context=True,
num_history_runs=3,
add_datetime_to_context=True,
markdown=True,
)
# Create custom FastAPI app
app: FastAPI = FastAPI(
title="Custom FastAPI App",
version="1.0.0",
)
# Custom landing page (conflicts with AgentOS home route)
@app.get("/")
async def get_custom_home():
return {
"message": "Custom FastAPI App",
"note": "Using on_route_conflict=\"preserve_base_app\" to preserve custom routes",
}
# Custom health endpoint (conflicts with AgentOS health route)
@app.get("/health")
async def get_custom_health():
return {"status": "custom_ok", "note": "This is your custom health endpoint"}
# Set up the AgentOS app by passing your FastAPI app
# Use on_route_conflict="preserve_base_app" to preserve your custom routes over AgentOS routes
agent_os = AgentOS(
description="Example app with route replacement",
agents=[web_research_agent],
base_app=app,
on_route_conflict="preserve_base_app", # Skip conflicting AgentOS routes, keep your custom routes
)
app = agent_os.get_app()
if __name__ == "__main__":
"""Run the AgentOS application.
With on_route_conflict="preserve_base_app":
- Your custom routes are preserved: http://localhost:7777/ and http://localhost:7777/health
- AgentOS routes are available at other paths: http://localhost:7777/sessions, etc.
- Conflicting AgentOS routes (GET / and GET /health) are skipped
- API docs: http://localhost:7777/docs
Try changing on_route_conflict to "preserve_agentos" to see AgentOS routes override your custom ones.
"""
agent_os.serve(app="override_routes:app", reload=True)