Production Agent Runtime: Build Stateful AI Agents That Actually Work
Stop building chatbots. Start building production-grade AI agents with stateful execution, tool orchestration, memory integration, and human-in-the-loop workflows. See real examples of support agents, sales agents, and multi-agent systems.
⚙️ Production-Grade Agent Runtime
Build stateful AI agents that actually work in production. Not chatbots—real agents with tools, memory, and workflows.
🎯 The Problem with Chatbots
Most AI applications are just chatbots—they respond to queries but forget everything, can't execute actions safely, and break under load. They're stateless, forgetful, and limited.
Production AI agents need:
- ✅ Stateful execution that remembers context
- ✅ Safe tool execution with approval workflows
- ✅ Memory integration for conversation continuity
- ✅ Pause/resume for long-running tasks
- ✅ Observability for monitoring and debugging
- ✅ Production features: circuit breakers, rate limiting, retries
That's exactly what HazelJS Agent Runtime provides—a production-grade execution engine for building real AI agents.
🚀 What is Agent Runtime?
Agent Runtime is a dedicated execution engine for stateful AI agents. Unlike stateless request handlers, it manages the entire agent lifecycle:
Runtime Capabilities
- Controlled Execution Loop: Prevents infinite loops, enforces state transitions
- State Persistence: Maintains context across steps and sessions
- Tool Orchestration: Safe execution with approval workflows
- Memory Integration: Automatic conversation tracking and entity memory
- Event System: Comprehensive observability for monitoring
- Production Features: Circuit breakers, rate limiting, retries, health checks
💼 Example 1: Customer Support Agent
Let's build a customer support agent that handles tickets, looks up orders, and processes refunds with approval:
import { Agent, Tool } from '@hazeljs/agent';
import { AgentRuntime } from '@hazeljs/agent';
@Agent({
name: 'support-agent',
description: 'Customer support agent for handling tickets',
systemPrompt: 'You are a helpful customer support agent. Be friendly and professional.',
enableMemory: true,
enableRAG: true,
})
export class SupportAgent {
@Tool({
description: 'Look up order information by order ID',
parameters: [
{
name: 'orderId',
type: 'string',
description: 'The order ID to lookup',
required: true,
},
],
})
async lookupOrder(input: { orderId: string }) {
// Query your order database
return {
orderId: input.orderId,
status: 'shipped',
trackingNumber: 'TRACK123',
items: ['Product A', 'Product B'],
};
}
@Tool({
description: 'Process a refund for an order',
requiresApproval: true, // Requires human approval
parameters: [
{
name: 'orderId',
type: 'string',
description: 'The order ID to refund',
required: true,
},
{
name: 'amount',
type: 'number',
description: 'Refund amount',
required: true,
},
],
})
async processRefund(input: { orderId: string; amount: number }) {
// This will wait for approval before executing
return {
success: true,
refundId: 'REF123',
amount: input.amount,
};
}
@Tool({
description: 'Create a support ticket',
parameters: [
{
name: 'subject',
type: 'string',
description: 'Ticket subject',
required: true,
},
{
name: 'description',
type: 'string',
description: 'Ticket description',
required: true,
},
],
})
async createTicket(input: { subject: string; description: string }) {
// Create ticket in your system
return {
ticketId: 'TICKET-123',
status: 'open',
createdAt: new Date(),
};
}
}Key Features Demonstrated:
- ✅ Multiple tools with different capabilities
- ✅ Approval workflow for sensitive operations (refunds)
- ✅ Memory and RAG enabled for context-aware responses
- ✅ Type-safe parameters with validation
💼 Example 2: Sales Agent with Approval Workflow
A sales agent that qualifies leads, schedules meetings, and creates quotes—with approval for high-value deals:
@Agent({
name: 'sales-agent',
description: 'Sales agent for lead qualification and deal management',
systemPrompt: 'You are a professional sales agent. Qualify leads and create opportunities.',
enableMemory: true,
})
export class SalesAgent {
@Tool({
description: 'Qualify a lead based on company size and budget',
parameters: [
{ name: 'companyName', type: 'string', required: true },
{ name: 'companySize', type: 'string', required: true },
{ name: 'budget', type: 'number', required: true },
],
})
async qualifyLead(input: { companyName: string; companySize: string; budget: number }) {
const score = input.budget > 100000 ? 'high' : input.budget > 50000 ? 'medium' : 'low';
return {
companyName: input.companyName,
qualificationScore: score,
recommendedAction: score === 'high' ? 'immediate_followup' : 'nurture',
};
}
@Tool({
description: 'Create a sales quote',
requiresApproval: true, // Requires manager approval
parameters: [
{ name: 'leadId', type: 'string', required: true },
{ name: 'amount', type: 'number', required: true },
{ name: 'products', type: 'array', required: true },
],
})
async createQuote(input: { leadId: string; amount: number; products: string[] }) {
// Waits for approval before creating quote
return {
quoteId: 'QUOTE-123',
leadId: input.leadId,
amount: input.amount,
status: 'pending_approval',
};
}
@Tool({
description: 'Schedule a meeting with a lead',
parameters: [
{ name: 'leadId', type: 'string', required: true },
{ name: 'date', type: 'string', required: true },
{ name: 'duration', type: 'number', required: true },
],
})
async scheduleMeeting(input: { leadId: string; date: string; duration: number }) {
return {
meetingId: 'MEET-123',
leadId: input.leadId,
scheduledAt: input.date,
duration: input.duration,
};
}
}Runtime Features in Action:
- ✅ Approval workflow for high-value quotes
- ✅ Memory tracks lead interactions across sessions
- ✅ Stateful execution maintains conversation context
- ✅ Event system for tracking sales activities
💼 Example 3: Multi-Agent System
Coordinate multiple specialized agents working together:
// Research Agent - finds information
@Agent({ name: 'research-agent', enableRAG: true })
export class ResearchAgent {
@Tool({ description: 'Research a topic' })
async research(topic: string) {
// Use RAG to find relevant information
return { findings: '...' };
}
}
// Writing Agent - creates content
@Agent({ name: 'writing-agent', enableMemory: true })
export class WritingAgent {
@Tool({ description: 'Write an article' })
async writeArticle(topic: string, findings: string) {
// Generate content based on research
return { article: '...' };
}
}
// Coordinator - orchestrates agents
const runtime = new AgentRuntime({ /* ... */ });
// Register all agents
runtime.registerAgent(ResearchAgent);
runtime.registerAgent(WritingAgent);
// Execute research agent
const research = await runtime.execute('research-agent', 'AI trends 2024');
// Execute writing agent with research results
const article = await runtime.execute('writing-agent',
`Write article about: ${research.response}`,
{ initialContext: { research: research.response } }
);Multi-Agent Benefits:
- ✅ Specialized agents for different tasks
- ✅ Runtime coordinates agent communication
- ✅ Shared context and memory across agents
- ✅ Event system tracks multi-agent workflows
💼 Example 4: RAG-Powered Research Agent
An agent that combines RAG retrieval with tool execution for comprehensive research:
@Agent({
name: 'research-agent',
description: 'Research agent with RAG integration',
enableRAG: true,
ragTopK: 5, // Retrieve top 5 relevant documents
})
export class ResearchAgent {
constructor(private ragService: RAGService) {}
@Tool({
description: 'Search knowledge base for information',
parameters: [
{ name: 'query', type: 'string', required: true },
],
})
async searchKnowledgeBase(input: { query: string }) {
// RAG automatically retrieves relevant context before tool execution
const results = await this.ragService.search(input.query, { topK: 5 });
return {
documents: results.documents,
totalResults: results.totalResults,
};
}
@Tool({
description: 'Summarize research findings',
parameters: [
{ name: 'findings', type: 'array', required: true },
],
})
async summarizeFindings(input: { findings: string[] }) {
// Agent uses RAG context + findings to create summary
return {
summary: '...',
keyPoints: ['...'],
};
}
}RAG Integration Benefits:
- ✅ Automatic context retrieval before reasoning
- ✅ Knowledge base integration
- ✅ Context-aware responses
- ✅ Memory of previous research queries
🔧 Runtime Features Deep Dive
1. Stateful Execution
Unlike stateless handlers, the runtime maintains state across steps:
// First interaction
const result1 = await runtime.execute('support-agent',
'My name is John and I need help with order #12345',
{ sessionId: 'user-123' }
);
// Later interaction - agent remembers
const result2 = await runtime.execute('support-agent',
'What was my order status?',
{ sessionId: 'user-123' }
);
// Agent remembers: "John's order #12345 status is shipped"2. Tool Approval Workflow
Human-in-the-loop for sensitive operations:
// Subscribe to approval requests
runtime.on(AgentEventType.TOOL_APPROVAL_REQUESTED, async (event) => {
const { requestId, toolName, input } = event.data;
console.log(`Approval needed for ${toolName}:`, input);
// Your approval logic
if (shouldApprove(input)) {
runtime.approveToolExecution(requestId, 'admin-user');
} else {
runtime.rejectToolExecution(requestId);
}
});
// Agent execution pauses until approval
const result = await runtime.execute('sales-agent',
'Create a quote for $500,000 deal'
);
// Execution pauses, waits for approval, then continues3. Pause and Resume
Support for long-running workflows:
// Execute agent
const result = await runtime.execute('agent', 'Start complex task');
// Agent might pause for user input
if (result.state === 'waiting_for_input') {
// Get user response
const userResponse = await getUserInput();
// Resume execution
const resumed = await runtime.resume(result.executionId, userResponse);
}4. Comprehensive Observability
Monitor everything with the event system:
// Track execution lifecycle
runtime.on(AgentEventType.EXECUTION_STARTED, (event) => {
logger.info('Agent started', { executionId: event.executionId });
});
runtime.on(AgentEventType.STEP_COMPLETED, (event) => {
logger.info('Step completed', {
step: event.data.stepNumber,
action: event.data.action
});
});
runtime.on(AgentEventType.TOOL_EXECUTION_COMPLETED, (event) => {
metrics.trackToolUsage(event.data.toolName, event.data.duration);
});
// Get metrics
const metrics = runtime.getMetrics();
console.log('Success rate:', metrics.executions.successRate);
console.log('Average latency:', metrics.performance.averageDuration);5. Production Features
Built-in resilience and reliability:
const runtime = new AgentRuntime({
// Circuit breaker - prevents cascading failures
enableCircuitBreaker: true,
circuitBreakerConfig: {
failureThreshold: 5,
resetTimeout: 30000,
},
// Rate limiting - control resource usage
enableRateLimiting: true,
rateLimitConfig: {
tokensPerMinute: 60,
burstSize: 10,
},
// Metrics - track performance
enableMetrics: true,
// Health checks
healthCheckConfig: {
enabled: true,
interval: 60000,
},
});📊 Real-World Use Cases
Customer Support
- • Handle support tickets
- • Look up orders and accounts
- • Process refunds with approval
- • Maintain conversation history
- • Escalate to human agents
Sales Automation
- • Qualify leads automatically
- • Schedule meetings
- • Create quotes with approval
- • Track deal progression
- • Generate sales reports
Research & Analysis
- • Research topics with RAG
- • Generate reports
- • Analyze data
- • Multi-hop reasoning
- • Source verification
Workflow Automation
- • Multi-step business processes
- • Pause/resume long tasks
- • Human-in-the-loop approvals
- • State persistence
- • Error recovery
🎨 Getting Started
Ready to build your first production agent? Here's how:
# 1. Install packages
npm install @hazeljs/agent @hazeljs/rag @hazeljs/ai
# 2. Generate your first agent
npx @hazeljs/cli generate agent support-agent
# 3. Customize the generated agent
# 4. Set up the runtime
# 5. Execute your agent!🚀 Why Agent Runtime Matters
Building production AI agents without a runtime means:
- ❌ Manual state management (error-prone)
- ❌ No tool orchestration (unsafe)
- ❌ No memory integration (forgetful)
- ❌ No observability (hard to debug)
- ❌ No production features (unreliable)
With Agent Runtime:
- ✅ Automatic state management
- ✅ Safe tool orchestration with approval
- ✅ Automatic memory integration
- ✅ Comprehensive observability
- ✅ Production-ready features built-in
Build Production Agents Today
Start building stateful AI agents with HazelJS Agent Runtime
🎯 Conclusion
Agent Runtime is more than a library—it's a production-grade execution engine that handles everything your agents need: state management, tool orchestration, memory integration, and observability.
Whether you're building customer support agents, sales automation, research assistants, or workflow automation, Agent Runtime provides the foundation for building real, production-ready AI agents.
Stop building chatbots. Start building agents.