Building Blocks
Routers
Organize reasoners and skills into namespaced modules with AgentRouter
Organize reasoners and skills into reusable, namespaced modules -- like FastAPI's APIRouter for agents.
Routers matter once an agent grows beyond a handful of functions. They do not just organize code. They shape the public callable surface of your agent by turning prefixes into namespaced function IDs.
from agentfield import Agent, AgentRouter
users = AgentRouter(prefix="users", tags=["users"])
billing = AgentRouter(prefix="billing", tags=["billing"])
@users.reasoner()
async def analyze_behavior(user_id: str) -> dict:
return await users.ai(
system="Summarize this user's activity and churn risk.",
user=user_id,
)
@billing.skill()
def current_plan(user_id: str) -> dict:
return {"user_id": user_id, "plan": "growth"}
app = Agent(node_id="user-agent")
app.include_router(users)
app.include_router(billing)
app.run()
# Callable targets: user-agent.users_analyze_behavior
# user-agent.billing_current_planimport { Agent, AgentRouter } from '@agentfield/sdk';
const users = new AgentRouter({ prefix: 'users', tags: ['users'] });
const billing = new AgentRouter({ prefix: 'billing', tags: ['billing'] });
users.reasoner('analyzeBehavior', async (ctx) => {
return ctx.ai(ctx.input.userId, {
system: 'Summarize this user\'s activity and churn risk.',
});
});
billing.skill('currentPlan', (ctx) => {
return { userId: ctx.input.userId, plan: 'growth' };
});
const agent = new Agent({ nodeId: 'user-agent' });
agent.includeRouter(users);
agent.includeRouter(billing);
agent.serve();
// Registered as: users_analyzeBehavior, billing_currentPlanWhat just happened
- Two logical domains became one agent with a cleaner public API
- Router prefixes became part of the callable function identity
- The same router pattern can be reused across multiple agents or packages
Concrete target examples:
user-agent.users_analyze_behavior
user-agent.billing_current_plan