Advanced Features
Advanced Features
Hooks & Lifecycle Events
Lifecycle Hooks (via AgentConfig)
beforeCompaction is the wired Agent lifecycle preservation hook. Other legacy
lifecycleHooks slots can be assigned but currently have no managed-loop callers;
do not use them to enforce tool authorization or promise observability. Use
execution hooks, context/Agent events, and the tool execution pipeline instead.
const agent = Agent.create({
connector: 'openai', model: 'gpt-4.1',
lifecycleHooks: {
beforeCompaction: async ({ agentId, estimatedTokensToFree }) => {
console.log(agentId, estimatedTokensToFree);
},
},
});
Execution Hooks (via HookConfig)
For finer control over the agentic loop, use the hooks config with named hook points:
const agent = Agent.create({
connector: 'openai',
model: 'gpt-4.1',
hooks: {
'before:tool': async (context) => {
console.log(`Calling ${context.toolCall.function.name}`);
return {}; // Return a ToolModification, e.g. { modified: { function: { ...context.toolCall.function, arguments: '...' } } }
},
'after:tool': async (context) => {
console.log(`Result: ${JSON.stringify(context.result)}`);
return {}; // Return a ToolResultModification, e.g. { modified: { content: '...' } }
},
'approve:tool': async (context) => {
// Return approval decision
return { approved: true, reason: 'Approved' };
},
},
});
Context Events
Subscribe to context events for monitoring or host UI updates:
const ctx = agent.context;
ctx.on('compaction:starting', ({ timestamp, targetTokensToFree }) => {
console.log(`Compaction starting: need to free ~${targetTokensToFree} tokens`);
});
ctx.on('context:compacted', ({ tokensFreed }) => {
console.log(`Compaction complete: freed ${tokensFreed} tokens`);
});
Circuit Breaker
Protect external services:
import { CircuitBreaker } from 'oneringai';
const breaker = new CircuitBreaker('my-breaker', {
failureThreshold: 5, // Open after 5 failures
successThreshold: 2, // Close after 2 successes
resetTimeoutMs: 30000, // Try again after 30 seconds
});
// Wrap API calls
const result = await breaker.execute(async () => {
return await externalAPI.call();
});
// Monitor state
breaker.on('opened', ({ name, failureCount, nextRetryTime }) => {
console.log(`Circuit '${name}' opened after ${failureCount} failures`);
});
// Get metrics
const metrics = breaker.getMetrics();
console.log(metrics);
// {
// state: 'closed',
// failureCount: 0,
// successCount: 10,
// totalRequests: 10,
// consecutiveSuccesses: 10
// }
Retry with Backoff
import { retryWithBackoff } from 'oneringai';
const result = await retryWithBackoff(
async () => {
// Your operation
return await apiCall();
},
{
strategy: 'exponential',
initialDelayMs: 1000, // Start with 1 second
maxDelayMs: 30000, // Cap at 30 seconds
multiplier: 2, // Double each time
jitter: true, // Add randomness
},
5 // maxAttempts (separate 3rd argument)
);
Logging
import { logger } from 'oneringai';
// Set log level
logger.updateConfig({ level: 'debug' }); // 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent'
// Log messages
logger.debug('Debug message');
logger.info('Info message');
logger.warn('Warning message');
logger.error('Error message');
// Structured logging
logger.info({ userId: '123', action: 'login' }, 'User action');
Metrics
import { metrics, setMetricsCollector, ConsoleMetrics } from 'oneringai';
// Use console metrics
setMetricsCollector(new ConsoleMetrics());
// Track metrics
metrics.increment('requests', 1, { endpoint: '/api/chat' });
metrics.gauge('active_connections', 42);
metrics.histogram('response_time', 125.5, { endpoint: '/api/chat' });
// Custom metrics collector
class CustomMetrics implements MetricsCollector {
increment(name: string, value: number, tags?: Record<string, string>) {
// Send to your metrics service
}
gauge(name: string, value: number, tags?: Record<string, string>) {
// Send to your metrics service
}
timing(name: string, duration: number, tags?: Record<string, string>) {
// Send to your metrics service
}
histogram(name: string, value: number, tags?: Record<string, string>) {
// Send to your metrics service
}
}
setMetricsCollector(new CustomMetrics());