Creating Agents
Agents are specialized AI assistants with custom personalities, capabilities, and configurations. They can be equipped with specific tools, knowledge, and behaviors to excel in particular domains or use cases.
Overview
AgentPress agents are highly configurable AI entities that combine:
- Custom Prompts: Define personality and behavior
- Tool Access: Specify which tools the agent can use
- Model Configuration: Choose AI models and parameters
- Voice Capabilities: Configure voice interactions
- Knowledge Sources: Connect to RAG data sources
File Structure
Agents are created in /packages/custom/src/agents/ with each agent having its own directory:
packages/custom/src/agents/
├── hr-assistant/
│ ├── config.json # Agent configuration
│ └── agent.ts # Custom agent class (optional)
├── weather-bot/
│ ├── config.json
│ └── agent.ts
└── default/
├── config.json
└── agent.tsBasic Agent Configuration
Every agent requires a config.json file with the following structure:
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"name": "HR Assistant",
"chatDisplayName": "HR Bot",
"description": "Helps employees understand company policies and procedures",
"initialMessage": "Hello! I'm your HR assistant. How can I help you with company policies today?",
"avatar": "/agentpress.svg",
"prompt": "You are an HR assistant that helps employees understand company policies, benefits, and procedures. Be helpful, professional, and accurate.",
"voicePrompt": "You are a friendly HR assistant. Speak clearly and helpfully about company policies.",
"enabled": true,
"archived": false,
"type": "code",
"primaryModelProvider": "openai",
"primaryModel": "gpt-4.1-mini-2025-04-14",
"primaryModelTemperature": 0.7,
"primaryModelMaxTokens": 10000,
"voiceProvider": "openai",
"voiceModel": "gpt-realtime",
"voiceId": "ash",
"voiceTemperature": 0.7,
"toolsAllEnabled": false,
"toolsEnabled": ["getCompanyPolicy", "searchEmployeeHandbook"],
"ragAllEnabled": false,
"ragEnabled": [],
"mcpAllEnabled": false,
"mcpEnabled": []
}Configuration Fields Explained
Basic Information
id: Unique UUID for the agent (generate withuuidv4())name: Internal name used in admin interfaceschatDisplayName: Name displayed in chat interfacesdescription: Brief description of the agent’s purposeinitialMessage: First message shown when starting a conversationavatar: Path to agent avatar image (use/agentpress.svgas default)
Prompts
prompt: Main system prompt defining the agent’s behavior and personalityvoicePrompt: Specialized prompt for voice interactions (should be more conversational)
Status
enabled: Whether the agent is active and availablearchived: Whether the agent is archived (hidden but preserved)type: Agent type (typically “code” for custom agents)
Model Configuration
primaryModelProvider: AI provider (“openai”, “anthropic”, etc.)primaryModel: Model to use ("gpt-4.1-mini-2025-04-14"recommended)primaryModelTemperature: Creativity level (0.0-1.0, typically 0.7)primaryModelMaxTokens: Maximum tokens per response
Voice Configuration
voiceProvider: Voice provider (“openai”)voiceModel: Voice model (“gpt-realtime”)voiceId: Voice identity (“alloy”, “echo”, “fable”, “onyx”, “nova”, “shimmer”)voiceTemperature: Voice creativity level
Tool Access
toolsAllEnabled: If true, agent has access to all available toolstoolsEnabled: Array of specific tool names the agent can use
Knowledge Sources
ragAllEnabled: If true, agent has access to all RAG sourcesragEnabled: Array of specific RAG source IDs
MCP Integration
mcpAllEnabled: If true, agent has access to all MCP servicesmcpEnabled: Array of specific MCP service names
Real-World Examples
Weather Assistant Agent
{
"id": "weather-bot-2024-001",
"name": "Weather Assistant",
"chatDisplayName": "WeatherBot",
"description": "Provides weather information and forecasts for any location",
"initialMessage": "Hi! I'm your weather assistant. Ask me about the weather in any city!",
"avatar": "/agentpress.svg",
"prompt": "You are a helpful weather assistant. Provide accurate, up-to-date weather information. Always include relevant details like temperature, conditions, and helpful advice about what to expect or wear. Be friendly and conversational.",
"voicePrompt": "You are a friendly weather assistant. Speak clearly about weather conditions and give helpful advice in a warm, conversational tone.",
"enabled": true,
"archived": false,
"type": "code",
"primaryModelProvider": "openai",
"primaryModel": "gpt-4.1-mini-2025-04-14",
"primaryModelTemperature": 0.7,
"primaryModelMaxTokens": 8000,
"voiceProvider": "openai",
"voiceModel": "gpt-realtime",
"voiceId": "nova",
"voiceTemperature": 0.8,
"toolsAllEnabled": false,
"toolsEnabled": ["getWeather", "getWeatherForecast"],
"ragAllEnabled": false,
"ragEnabled": [],
"mcpAllEnabled": false,
"mcpEnabled": []
}Technical Support Agent
{
"id": "tech-support-agent-001",
"name": "Technical Support",
"chatDisplayName": "TechBot",
"description": "Provides technical support and troubleshooting assistance",
"initialMessage": "Hello! I'm here to help with technical issues. What problem are you experiencing?",
"avatar": "/agentpress.svg",
"prompt": "You are a knowledgeable technical support agent. Help users troubleshoot problems step by step. Ask clarifying questions, provide clear instructions, and escalate complex issues when appropriate. Be patient and thorough.",
"voicePrompt": "You are a helpful tech support agent. Speak clearly and patiently, giving step-by-step instructions for technical problems.",
"enabled": true,
"archived": false,
"type": "code",
"primaryModelProvider": "openai",
"primaryModel": "gpt-4.1-mini-2025-04-14",
"primaryModelTemperature": 0.5,
"primaryModelMaxTokens": 12000,
"voiceProvider": "openai",
"voiceModel": "gpt-realtime",
"voiceId": "alloy",
"voiceTemperature": 0.6,
"toolsAllEnabled": false,
"toolsEnabled": ["searchKnowledgeBase", "createTicket", "checkSystemStatus"],
"ragAllEnabled": true,
"ragEnabled": [],
"mcpAllEnabled": false,
"mcpEnabled": []
}Custom Agent Classes (Optional)
For simple agents, the configuration file is sufficient. However, you can create custom agent classes for advanced behavior:
// packages/custom/src/agents/my-agent/agent.ts
import { BaseAgent } from "@agentpress/api/agents/baseAgent";
import { TAgentConfig } from "@agentpress/lib/types";
export class CustomAgent extends BaseAgent {
constructor(config: TAgentConfig) {
super(config);
}
// Override the prompt method for dynamic prompts
async getPrompt(): Promise<string> {
const basePrompt = this.config.prompt;
const currentTime = new Date().toLocaleString();
return `${basePrompt}\n\nCurrent time: ${currentTime}. Use this context when relevant.`;
}
// Override voice prompt for different voice behavior
async getVoicePrompt(): Promise<string> {
const baseVoicePrompt = this.config.voicePrompt;
// Add time-based variations
const hour = new Date().getHours();
const greeting = hour < 12 ? "Good morning!" : hour < 18 ? "Good afternoon!" : "Good evening!";
return `${greeting} ${baseVoicePrompt}`;
}
// Add custom initialization logic
async initialize(): Promise<void> {
await super.initialize();
// Custom initialization code
console.log(`Custom agent ${this.config.name} initialized`);
}
// Override message processing for custom behavior
async processMessage(message: string): Promise<string> {
// Pre-process the message
const processedMessage = message.trim().toLowerCase();
// Call the parent method
const response = await super.processMessage(processedMessage);
// Post-process the response
return this.addPersonalityToResponse(response);
}
private addPersonalityToResponse(response: string): string {
// Add personality quirks or formatting
if (response.includes("error") || response.includes("problem")) {
return `🚨 ${response}`;
}
if (response.includes("success") || response.includes("completed")) {
return `✅ ${response}`;
}
return response;
}
}Advanced Configuration Patterns
Multi-Tool Specialist Agent
{
"id": "data-analyst-agent-001",
"name": "Data Analyst",
"chatDisplayName": "DataBot",
"description": "Analyzes data, creates visualizations, and generates insights",
"initialMessage": "Hello! I'm your data analyst. I can help you analyze data, create charts, and find insights. What would you like to explore?",
"avatar": "/agentpress.svg",
"prompt": "You are an expert data analyst. Help users understand their data through analysis, visualization, and clear explanations. Always provide actionable insights and suggest next steps. Use the available tools to fetch, process, and visualize data.",
"voicePrompt": "You are a data analyst. Explain data insights clearly and suggest practical actions based on findings.",
"enabled": true,
"archived": false,
"type": "code",
"primaryModelProvider": "openai",
"primaryModel": "gpt-4.1-mini-2025-04-14",
"primaryModelTemperature": 0.3,
"primaryModelMaxTokens": 15000,
"voiceProvider": "openai",
"voiceModel": "gpt-realtime",
"voiceId": "echo",
"voiceTemperature": 0.4,
"toolsAllEnabled": false,
"toolsEnabled": [
"fetchDatabaseData",
"createChart",
"calculateStatistics",
"generateReport",
"exportData"
],
"ragAllEnabled": false,
"ragEnabled": ["analytics-kb", "data-dictionary"],
"mcpAllEnabled": false,
"mcpEnabled": []
}Customer Service Agent with Knowledge Base
{
"id": "customer-service-001",
"name": "Customer Service",
"chatDisplayName": "SupportBot",
"description": "Handles customer inquiries and provides support using company knowledge",
"initialMessage": "Welcome! I'm here to help with any questions about our products and services. How can I assist you today?",
"avatar": "/agentpress.svg",
"prompt": "You are a professional customer service representative. Always be polite, helpful, and solution-oriented. Use the knowledge base to provide accurate information about products, policies, and procedures. If you cannot solve an issue, guide the customer to the appropriate next steps.",
"voicePrompt": "You are a friendly customer service agent. Speak professionally but warmly, and always try to resolve customer issues.",
"enabled": true,
"archived": false,
"type": "code",
"primaryModelProvider": "openai",
"primaryModel": "gpt-4.1-mini-2025-04-14",
"primaryModelTemperature": 0.6,
"primaryModelMaxTokens": 10000,
"voiceProvider": "openai",
"voiceModel": "gpt-realtime",
"voiceId": "shimmer",
"voiceTemperature": 0.7,
"toolsAllEnabled": false,
"toolsEnabled": [
"searchKnowledgeBase",
"createSupportTicket",
"checkOrderStatus",
"processRefund"
],
"ragAllEnabled": true,
"ragEnabled": [],
"mcpAllEnabled": false,
"mcpEnabled": []
}Agent Registration
Agents are automatically discovered and loaded by the agent registry when the API server starts. The registry scans /packages/custom/src/agents/ and loads:
- Configuration: The
config.jsonfile is parsed and validated - Custom Class: If an
agent.tsfile exists, the custom class is instantiated - Default Class: If no custom class exists, the
BaseAgentclass is used
Best Practices
1. Clear Agent Purpose
Define a single, clear purpose for each agent:
{
"name": "Weather Assistant",
"description": "Provides weather information and forecasts",
"prompt": "You are a weather assistant focused solely on providing accurate weather information..."
}2. Appropriate Tool Selection
Only enable tools relevant to the agent’s purpose:
{
"toolsEnabled": ["getWeather", "getWeatherForecast", "getWeatherAlerts"]
}3. Model Selection
- Use
gpt-4.1-mini-2025-04-14for most agents (good balance of capability and cost) - Lower temperature (0.3-0.5) for factual agents
- Higher temperature (0.7-0.9) for creative agents
4. Voice Configuration
Choose appropriate voices:
- alloy: Neutral, professional
- echo: Calm, measured
- fable: Warm, engaging
- nova: Energetic, friendly
- onyx: Deep, authoritative
- shimmer: Light, cheerful
5. Prompt Engineering
Structure prompts clearly:
{
"prompt": "You are a [ROLE] who [PRIMARY_FUNCTION]. Your personality is [PERSONALITY_TRAITS]. When users ask you to [SPECIFIC_TASK], you should [SPECIFIC_INSTRUCTIONS]. Always [BEHAVIORAL_GUIDELINES]."
}6. Error Handling in Custom Classes
export class RobustAgent extends BaseAgent {
async processMessage(message: string): Promise<string> {
try {
return await super.processMessage(message);
} catch (error) {
console.error(`Agent ${this.config.name} error:`, error);
return "I apologize, but I encountered an error. Please try rephrasing your request.";
}
}
}Testing Agents
1. Configuration Validation
Ensure your config.json is valid:
# Test JSON validity
cat packages/custom/src/agents/my-agent/config.json | jq .2. Tool Access Testing
Verify the agent can access its configured tools:
- Start the API server
- Test the agent in the console interface
- Try using each enabled tool
- Verify tool outputs display correctly
3. Conversation Testing
Test various conversation flows:
- Initial greeting
- Tool usage scenarios
- Error handling
- Edge cases
4. Voice Testing
If voice is enabled:
- Test voice responses
- Verify appropriate voice selection
- Check voice prompt effectiveness
Troubleshooting
Agent Not Appearing
- Check that
config.jsonis valid JSON - Ensure the agent ID is unique
- Verify
enabled: true - Restart the API server
Tool Access Issues
- Verify tool names in
toolsEnabledmatch exactly - Check that tools are properly exported
- Ensure tools are registered in the tool registry
Custom Class Issues
- Check that the custom class extends
BaseAgent - Verify the constructor calls
super(config) - Ensure proper TypeScript types are used
Configuration Errors
- Validate all required fields are present
- Check model names are correct
- Verify voice IDs are valid
Advanced Features
Dynamic Prompts
export class DynamicAgent extends BaseAgent {
async getPrompt(): Promise<string> {
const userContext = await this.getUserContext();
const timeContext = this.getTimeContext();
return `${this.config.prompt}\n\nUser context: ${userContext}\nTime: ${timeContext}`;
}
private async getUserContext(): Promise<string> {
// Fetch user-specific context
return "user preferences and history";
}
private getTimeContext(): string {
const now = new Date();
return `Current time: ${now.toLocaleString()}`;
}
}State Management
export class StatefulAgent extends BaseAgent {
private conversationState: Map<string, any> = new Map();
async processMessage(message: string, userId: string): Promise<string> {
const state = this.conversationState.get(userId) || {};
// Update state based on message
state.lastMessage = message;
state.messageCount = (state.messageCount || 0) + 1;
this.conversationState.set(userId, state);
// Process message with state context
return await super.processMessage(message);
}
}Integration with External Services
export class IntegratedAgent extends BaseAgent {
private apiClient: ExternalAPIClient;
constructor(config: TAgentConfig) {
super(config);
this.apiClient = new ExternalAPIClient(process.env.API_KEY);
}
async processMessage(message: string): Promise<string> {
// Enhance message with external data
const enrichedContext = await this.apiClient.getContext(message);
const enhancedMessage = `${message}\n\nAdditional context: ${enrichedContext}`;
return await super.processMessage(enhancedMessage);
}
}Your custom agents will now be automatically discovered and available in the AgentPress system!
Summary
Creating agents in AgentPress involves:
- Define Purpose: Clear role and capabilities
- Create Configuration: Complete
config.jsonwith all settings - Choose Tools: Select relevant tools for the agent’s domain
- Write Prompts: Craft effective system and voice prompts
- Optional Customization: Add custom agent class if needed
- Test Thoroughly: Verify all functionality works as expected
Agents are the core of the AgentPress experience - they bring AI capabilities to life with personality, purpose, and specialized knowledge.