capsule-ai-cli
Version:
The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing
82 lines • 2.34 kB
JavaScript
import { configManager } from '../core/config.js';
export class AnalyticsService {
baseUrl;
queue = [];
flushInterval = null;
constructor(baseUrl = process.env.CAPSULE_API_URL || 'https://api.capsule.dev') {
this.baseUrl = baseUrl;
this.startPeriodicFlush();
}
async track(event) {
const config = configManager.getConfig();
if (!config.costs.trackUsage || !config.auth?.token) {
return;
}
const enrichedEvent = {
...event,
timestamp: new Date().toISOString(),
tier: config.auth.tier,
email: config.auth.email,
};
this.queue.push(enrichedEvent);
if (this.queue.length >= 10) {
await this.flush();
}
}
async flush() {
if (this.queue.length === 0)
return;
const config = configManager.getConfig();
if (!config.auth?.token)
return;
const events = [...this.queue];
this.queue = [];
try {
await fetch(`${this.baseUrl}/api/analytics/track`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${config.auth.token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ events }),
});
}
catch (error) {
this.queue.unshift(...events);
}
}
startPeriodicFlush() {
this.flushInterval = setInterval(() => {
this.flush().catch(() => {
});
}, 30000);
}
async trackCompletion(provider, model, usage, cost) {
await this.track({
event: 'completion',
provider,
model,
usage,
cost,
});
}
async trackError(provider, model, error) {
await this.track({
event: 'error',
provider,
model,
error,
});
}
async shutdown() {
if (this.flushInterval) {
clearInterval(this.flushInterval);
}
await this.flush();
}
}
export const analyticsService = new AnalyticsService();
process.on('beforeExit', async () => {
await analyticsService.shutdown();
});
//# sourceMappingURL=analytics.js.map