Skip to content

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.

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

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.ts

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": []
}
  • id: Unique UUID for the agent (generate with uuidv4())
  • name: Internal name used in admin interfaces
  • chatDisplayName: Name displayed in chat interfaces
  • description: Brief description of the agent’s purpose
  • initialMessage: First message shown when starting a conversation
  • avatar: Path to agent avatar image (use /agentpress.svg as default)
  • prompt: Main system prompt defining the agent’s behavior and personality
  • voicePrompt: Specialized prompt for voice interactions (should be more conversational)
  • enabled: Whether the agent is active and available
  • archived: Whether the agent is archived (hidden but preserved)
  • type: Agent type (typically “code” for custom agents)
  • 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
  • voiceProvider: Voice provider (“openai”)
  • voiceModel: Voice model (“gpt-realtime”)
  • voiceId: Voice identity (“alloy”, “echo”, “fable”, “onyx”, “nova”, “shimmer”)
  • voiceTemperature: Voice creativity level
  • toolsAllEnabled: If true, agent has access to all available tools
  • toolsEnabled: Array of specific tool names the agent can use
  • ragAllEnabled: If true, agent has access to all RAG sources
  • ragEnabled: Array of specific RAG source IDs
  • mcpAllEnabled: If true, agent has access to all MCP services
  • mcpEnabled: Array of specific MCP service names
{
  "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": []
}
{
  "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": []
}

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;
  }
}
{
  "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

Section titled “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": []
}

Agents are automatically discovered and loaded by the agent registry when the API server starts. The registry scans /packages/custom/src/agents/ and loads:

  1. Configuration: The config.json file is parsed and validated
  2. Custom Class: If an agent.ts file exists, the custom class is instantiated
  3. Default Class: If no custom class exists, the BaseAgent class is used

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..."
}

Only enable tools relevant to the agent’s purpose:

{
  "toolsEnabled": ["getWeather", "getWeatherForecast", "getWeatherAlerts"]
}
  • Use gpt-4.1-mini-2025-04-14 for 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

Choose appropriate voices:

  • alloy: Neutral, professional
  • echo: Calm, measured
  • fable: Warm, engaging
  • nova: Energetic, friendly
  • onyx: Deep, authoritative
  • shimmer: Light, cheerful

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]."
}
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.";
    }
  }
}

Ensure your config.json is valid:

# Test JSON validity
cat packages/custom/src/agents/my-agent/config.json | jq .

Verify the agent can access its configured tools:

  1. Start the API server
  2. Test the agent in the console interface
  3. Try using each enabled tool
  4. Verify tool outputs display correctly

Test various conversation flows:

  • Initial greeting
  • Tool usage scenarios
  • Error handling
  • Edge cases

If voice is enabled:

  • Test voice responses
  • Verify appropriate voice selection
  • Check voice prompt effectiveness
  • Check that config.json is valid JSON
  • Ensure the agent ID is unique
  • Verify enabled: true
  • Restart the API server
  • Verify tool names in toolsEnabled match exactly
  • Check that tools are properly exported
  • Ensure tools are registered in the tool registry
  • Check that the custom class extends BaseAgent
  • Verify the constructor calls super(config)
  • Ensure proper TypeScript types are used
  • Validate all required fields are present
  • Check model names are correct
  • Verify voice IDs are valid
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()}`;
  }
}
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);
  }
}
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!

Creating agents in AgentPress involves:

  1. Define Purpose: Clear role and capabilities
  2. Create Configuration: Complete config.json with all settings
  3. Choose Tools: Select relevant tools for the agent’s domain
  4. Write Prompts: Craft effective system and voice prompts
  5. Optional Customization: Add custom agent class if needed
  6. 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.