Dynamic Agents
Load agents at runtime using the dynamic_agents parameter and resolver functions.
Overview
Dynamic agents enable runtime agent loading without pre-registration:
- On-Demand Creation - Agents created when first requested
- Configuration-Driven - Load from external sources (DB, API, files)
- Flexible Updates - Change agent behavior without redeployment
- Memory Efficient - Only create agents that are actually used
Dynamic Agent Resolver
The dynamic_agents parameter accepts a resolver function that creates agents by name:
import { BaseAgent } from 'webagents';
import { createAgentApp } from 'webagents/server';
import { serve } from 'webagents/server/node';
async function resolveAgent(agentName: string): Promise<BaseAgent | null> {
const config = await loadConfig(agentName);
if (!config) return null;
return new BaseAgent({
name: config.name,
instructions: config.instructions,
model: config.model,
});
}
const app = createAgentApp({
title: 'Dynamic Server',
dynamicAgents: resolveAgent,
});
await serve(app, { host: '0.0.0.0', port: 8000 });Resolver Function Signature
The resolver function must match this signature:
type AgentResolver = (agentName: string) => Promise<BaseAgent | null> | BaseAgent | null;Parameters:
agent_name: The agent name from the URL path- Returns:
BaseAgentinstance orNoneif not found
Resolution Flow
- Request arrives for
/agent-name/chat/completions - Static Check - Look for pre-registered agents first
- Dynamic Call - Call
dynamic_agents(agent_name)if not found - Agent Creation - Resolver creates and returns BaseAgent
- Request Processing - Server uses the resolved agent
Configuration Sources
Database Resolver
async function dbResolver(agentName: string): Promise<BaseAgent | null> {
const row = await db.query(
'SELECT * FROM agents WHERE name = $1',
[agentName],
);
if (!row) return null;
return new BaseAgent({
name: row.name,
instructions: row.instructions,
model: row.model,
});
}File-Based Resolver
import { readFile } from 'node:fs/promises';
import { existsSync } from 'node:fs';
async function fileResolver(agentName: string): Promise<BaseAgent | null> {
const path = `agents/${agentName}.json`;
if (!existsSync(path)) return null;
const config = JSON.parse(await readFile(path, 'utf8'));
return new BaseAgent(config);
}API Resolver
async function apiResolver(agentName: string): Promise<BaseAgent | null> {
const res = await fetch(`https://api.example.com/agents/${agentName}`);
if (!res.ok) return null;
const config = await res.json();
return new BaseAgent(config);
}Combined Static and Dynamic
Use both static agents and dynamic resolution:
const staticAgents = [
new BaseAgent({ name: 'assistant', model: 'openai/gpt-4o' }),
new BaseAgent({ name: 'support', model: 'openai/gpt-4o' }),
];
async function dynamicResolver(agentName: string): Promise<BaseAgent | null> {
return loadFromDatabase(agentName);
}
const app = createAgentApp({
agents: staticAgents,
dynamicAgents: dynamicResolver,
});Error Handling
Handle errors gracefully in resolvers:
async function safeResolver(agentName: string): Promise<BaseAgent | null> {
try {
const config = await loadConfig(agentName);
if (!config) {
console.info(`Agent '${agentName}' not found`);
return null;
}
const agent = new BaseAgent(config);
console.info(`Created agent '${agentName}'`);
return agent;
} catch (err) {
console.error(`Failed to resolve agent '${agentName}':`, err);
return null;
}
}See Also
- Server Overview - Basic server setup
- Agent Overview - Agent setup options
- Server Architecture - Production deployment