72 lines
2.9 KiB
JavaScript
72 lines
2.9 KiB
JavaScript
"use strict";
|
|
/**
|
|
* AIEnrichmentService — selects AI provider and runs enrichment asynchronously.
|
|
* Triggered manually (POST /api/anomalies/:id/enrich) or automatically for high/critical.
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.AIEnrichmentService = void 0;
|
|
const ClaudeProvider_1 = require("./ClaudeProvider");
|
|
const OpenAIProvider_1 = require("./OpenAIProvider");
|
|
const OllamaProvider_1 = require("./OllamaProvider");
|
|
const logger_1 = require("../logger");
|
|
class AIEnrichmentService {
|
|
constructor(emitter) {
|
|
this.emitter = emitter;
|
|
this.autoEnrich = process.env['ABE_AI_AUTO_ENRICH'] === 'true';
|
|
const minSev = process.env['ABE_AI_MIN_SEVERITY'] ?? 'high';
|
|
this.minSeverityRank = AIEnrichmentService.SEVERITY_RANK[minSev] ?? 2;
|
|
this.provider = this.createProvider();
|
|
}
|
|
createProvider() {
|
|
const providerName = process.env['ABE_AI_PROVIDER'] ?? 'none';
|
|
const model = process.env['ABE_AI_MODEL'];
|
|
if (providerName === 'claude') {
|
|
const key = process.env['ABE_AI_API_KEY'];
|
|
if (!key)
|
|
return null;
|
|
return new ClaudeProvider_1.ClaudeProvider(key, model);
|
|
}
|
|
if (providerName === 'openai') {
|
|
const key = process.env['ABE_OPENAI_API_KEY'];
|
|
if (!key)
|
|
return null;
|
|
return new OpenAIProvider_1.OpenAIProvider(key, model);
|
|
}
|
|
if (providerName === 'ollama') {
|
|
const url = process.env['ABE_OLLAMA_URL'] ?? 'http://localhost:11434';
|
|
return new OllamaProvider_1.OllamaProvider(url, model);
|
|
}
|
|
return null;
|
|
}
|
|
/** Check if auto-enrichment should run for this anomaly. */
|
|
shouldAutoEnrich(anomaly) {
|
|
if (!this.autoEnrich || !this.provider)
|
|
return false;
|
|
const rank = AIEnrichmentService.SEVERITY_RANK[anomaly.severity] ?? 0;
|
|
return rank >= this.minSeverityRank;
|
|
}
|
|
/** Enrich an anomaly asynchronously and emit WebSocket event when done. */
|
|
async enrich(anomaly, context) {
|
|
if (!this.provider) {
|
|
logger_1.log.warn({ anomalyId: anomaly.id }, 'No AI provider configured');
|
|
return;
|
|
}
|
|
try {
|
|
const enrichment = await this.provider.enrich(anomaly, context);
|
|
anomaly.aiEnrichment = enrichment;
|
|
this.emitter('anomaly:enriched', { anomalyId: anomaly.id, enrichment });
|
|
logger_1.log.info({ anomalyId: anomaly.id, provider: this.provider.name }, 'Anomaly enriched');
|
|
}
|
|
catch (err) {
|
|
logger_1.log.error({ anomalyId: anomaly.id, err: err instanceof Error ? err.message : String(err) }, 'AI enrichment failed');
|
|
}
|
|
}
|
|
hasProvider() {
|
|
return this.provider !== null;
|
|
}
|
|
}
|
|
exports.AIEnrichmentService = AIEnrichmentService;
|
|
AIEnrichmentService.SEVERITY_RANK = {
|
|
low: 0, medium: 1, high: 2, critical: 3,
|
|
};
|