contextual-agent-sdk
Version:
SDK for building AI agents with seamless voice-text context switching
282 lines • 11.3 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ToolRegistry = void 0;
class ToolRegistry {
providers = new Map();
usageRecords = [];
initialized = false;
constructor() {
this.initialized = true;
console.log('[ToolRegistry] Initialized tool registry');
this.registerBuiltInProviders();
}
registerBuiltInProviders() {
try {
Promise.resolve().then(() => __importStar(require('./providers/TwilioToolProvider'))).then(({ TwilioToolProvider }) => {
this.registerProvider(new TwilioToolProvider());
}).catch(error => {
console.warn('[ToolRegistry] Failed to load TwilioToolProvider:', error);
});
console.log('[ToolRegistry] Built-in providers registration initiated');
}
catch (error) {
console.warn('[ToolRegistry] Failed to register built-in providers:', error);
}
}
registerProvider(provider) {
if (this.providers.has(provider.id)) {
console.warn(`[ToolRegistry] Provider '${provider.id}' is already registered. Overwriting.`);
}
this.providers.set(provider.id, provider);
console.log(`[ToolRegistry] Registered provider: ${provider.id} (${provider.name})`);
}
unregisterProvider(providerId) {
if (this.providers.has(providerId)) {
const provider = this.providers.get(providerId);
this.providers.delete(providerId);
console.log(`[ToolRegistry] Unregistered provider: ${providerId} (${provider.name})`);
provider.cleanup?.().catch(error => {
console.warn(`[ToolRegistry] Failed to cleanup provider ${providerId}:`, error);
});
}
else {
console.warn(`[ToolRegistry] Attempted to unregister unknown provider: ${providerId}`);
}
}
getProvider(providerId) {
return this.providers.get(providerId);
}
getProviders() {
return Array.from(this.providers.values());
}
getAvailableTools() {
const availableProviders = this.getProviders();
const tools = [];
for (const provider of availableProviders) {
try {
const providerTools = provider.getAvailableTools();
tools.push(...providerTools);
}
catch (error) {
console.warn(`[ToolRegistry] Failed to get tools from provider ${provider.id}:`, error);
}
}
return tools;
}
getToolsByCategory(category) {
const allTools = this.getAvailableTools();
return allTools.filter(tool => tool.category === category);
}
findTool(toolId) {
for (const provider of this.providers.values()) {
try {
const tool = provider.getTool(toolId);
if (tool) {
return tool;
}
}
catch (error) {
console.warn(`[ToolRegistry] Error finding tool ${toolId} in provider ${provider.id}:`, error);
}
}
return undefined;
}
searchTools(query) {
const allTools = this.getAvailableTools();
const lowercaseQuery = query.toLowerCase();
return allTools.filter(tool => {
return tool.name.toLowerCase().includes(lowercaseQuery) ||
tool.description.toLowerCase().includes(lowercaseQuery) ||
tool.tags?.some(tag => tag.toLowerCase().includes(lowercaseQuery));
});
}
async getToolUsageStats(toolId, timeRange) {
let filteredRecords = this.usageRecords.filter(record => record.toolId === toolId);
if (timeRange) {
filteredRecords = filteredRecords.filter(record => record.timestamp >= timeRange.start && record.timestamp <= timeRange.end);
}
const totalExecutions = filteredRecords.length;
const successfulExecutions = filteredRecords.filter(r => r.success).length;
const failedExecutions = totalExecutions - successfulExecutions;
const successRate = totalExecutions > 0 ? (successfulExecutions / totalExecutions) * 100 : 0;
const totalExecutionTime = filteredRecords.reduce((sum, record) => sum + record.executionTime, 0);
const averageExecutionTime = totalExecutions > 0 ? totalExecutionTime / totalExecutions : 0;
const totalCost = filteredRecords.reduce((sum, record) => sum + (record.cost || 0), 0);
const dailyUsageMap = new Map();
for (const record of filteredRecords) {
const date = record.timestamp.toISOString().split('T')[0];
if (!dailyUsageMap.has(date)) {
dailyUsageMap.set(date, {
date,
executions: 0,
successful: 0,
totalExecutionTime: 0
});
}
const daily = dailyUsageMap.get(date);
daily.executions++;
if (record.success)
daily.successful++;
daily.totalExecutionTime += record.executionTime;
}
const dailyUsage = Array.from(dailyUsageMap.values()).map(daily => ({
date: daily.date,
executions: daily.executions,
successRate: daily.executions > 0 ? (daily.successful / daily.executions) * 100 : 0,
averageExecutionTime: daily.executions > 0 ? daily.totalExecutionTime / daily.executions : 0
}));
const errorCounts = new Map();
const failedRecords = filteredRecords.filter(r => !r.success && r.error);
for (const record of failedRecords) {
const error = record.error;
errorCounts.set(error, (errorCounts.get(error) || 0) + 1);
}
const commonErrors = Array.from(errorCounts.entries())
.map(([error, count]) => ({
error,
count,
percentage: failedExecutions > 0 ? (count / failedExecutions) * 100 : 0
}))
.sort((a, b) => b.count - a.count)
.slice(0, 5);
return {
toolId,
timeRange: timeRange || {
start: new Date(0),
end: new Date()
},
totalExecutions,
successfulExecutions,
failedExecutions,
successRate,
averageExecutionTime,
totalCost: totalCost > 0 ? totalCost : undefined,
dailyUsage,
commonErrors
};
}
recordUsage(record) {
this.usageRecords.push(record);
const maxRecords = 10000;
if (this.usageRecords.length > maxRecords) {
this.usageRecords = this.usageRecords.slice(-maxRecords);
}
}
getStats() {
const allTools = this.getAvailableTools();
const toolsByCategory = {};
const toolsByTier = {};
for (const tool of allTools) {
toolsByCategory[tool.category] = (toolsByCategory[tool.category] || 0) + 1;
toolsByTier[tool.minimumTier] = (toolsByTier[tool.minimumTier] || 0) + 1;
}
const toolUsageCount = new Map();
for (const record of this.usageRecords) {
toolUsageCount.set(record.toolId, (toolUsageCount.get(record.toolId) || 0) + 1);
}
const popularTools = Array.from(toolUsageCount.entries())
.map(([toolId, usageCount]) => {
const tool = this.findTool(toolId);
return {
toolId,
name: tool?.name || 'Unknown',
usageCount
};
})
.sort((a, b) => b.usageCount - a.usageCount)
.slice(0, 10);
return {
totalProviders: this.providers.size,
totalTools: allTools.length,
toolsByCategory,
toolsByTier,
popularTools
};
}
getHealth() {
const providerHealth = {};
let healthyProviders = 0;
let totalResponseTime = 0;
let totalErrors = 0;
let totalOperations = 0;
for (const [providerId, provider] of this.providers) {
const health = provider.getHealthStatus();
providerHealth[providerId] = health.status;
if (health.status === 'healthy') {
healthyProviders++;
}
totalResponseTime += health.details.averageResponseTime;
totalErrors += health.details.errorRate;
totalOperations++;
}
const overallHealthy = healthyProviders / this.providers.size;
let status = 'healthy';
if (overallHealthy < 0.5) {
status = 'unhealthy';
}
else if (overallHealthy < 0.8) {
status = 'degraded';
}
return {
status,
providerHealth,
metrics: {
averageResponseTime: totalOperations > 0 ? totalResponseTime / totalOperations : 0,
errorRate: totalOperations > 0 ? totalErrors / totalOperations : 0,
activeInstances: this.providers.size
},
lastHealthCheck: new Date()
};
}
async cleanup() {
console.log('[ToolRegistry] Cleaning up all providers...');
const cleanupPromises = Array.from(this.providers.values()).map(async (provider) => {
try {
await provider.cleanup?.();
}
catch (error) {
console.warn(`[ToolRegistry] Failed to cleanup provider ${provider.id}:`, error);
}
});
await Promise.allSettled(cleanupPromises);
this.providers.clear();
this.usageRecords = [];
this.initialized = false;
console.log('[ToolRegistry] Cleanup completed');
}
}
exports.ToolRegistry = ToolRegistry;
//# sourceMappingURL=ToolRegistry.js.map