Files

89 lines
3.1 KiB
JavaScript

"use strict";
/**
* ClaudeProvider — AI enrichment using Anthropic API.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClaudeProvider = void 0;
const DEFAULT_MODEL = 'claude-haiku-4-5-20251001';
class ClaudeProvider {
constructor(apiKey, model = DEFAULT_MODEL) {
this.name = 'claude';
this.apiKey = apiKey;
this.model = model;
}
async enrich(anomaly, context) {
const prompt = buildPrompt(anomaly, context);
const res = await fetch('https://api.anthropic.com/v1/messages', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': this.apiKey,
'anthropic-version': '2023-06-01',
},
body: JSON.stringify({
model: this.model,
max_tokens: 1024,
messages: [{ role: 'user', content: prompt }],
}),
});
if (!res.ok) {
throw new Error(`Anthropic API error: ${res.status} ${await res.text()}`);
}
const data = await res.json();
const text = data.content.find((c) => c.type === 'text')?.text ?? '';
return parseEnrichment(text, this.name, this.model);
}
}
exports.ClaudeProvider = ClaudeProvider;
function buildPrompt(anomaly, context) {
return `You are a senior software engineer analyzing a bug report from an automated web testing tool.
Bug Report:
- Type: ${anomaly.type}
- Severity: ${anomaly.severity}
- Description: ${anomaly.description}
- URL: ${context.url}
- Page Title: ${context.pageTitle}
- Action Trace: ${JSON.stringify(anomaly.actionTrace.slice(-5), null, 2)}
${context.httpLog.length > 0 ? `- HTTP Log: ${JSON.stringify(context.httpLog.slice(-3), null, 2)}` : ''}
${context.consoleErrors.length > 0 ? `- Console Errors: ${context.consoleErrors.slice(-3).join('\n')}` : ''}
Please provide a concise analysis in exactly this JSON format:
{
"rootCause": "One sentence explaining the likely root cause",
"userImpact": "One sentence describing the impact on users",
"suggestedFix": "One to two sentences with a concrete fix suggestion",
"confidence": "low|medium|high"
}`;
}
function parseEnrichment(text, provider, model) {
const debugPrompt = `Bug analysis:\n${text}`;
try {
const match = text.match(/\{[\s\S]*\}/);
if (match) {
const parsed = JSON.parse(match[0]);
return {
rootCause: parsed.rootCause ?? 'Unknown root cause',
userImpact: parsed.userImpact ?? 'Unknown impact',
suggestedFix: parsed.suggestedFix ?? 'No fix suggested',
debugPrompt,
confidence: parsed.confidence ?? 'medium',
generatedAt: Date.now(),
provider,
model,
};
}
}
catch { /* fallback below */ }
return {
rootCause: text.slice(0, 200) || 'Could not parse root cause',
userImpact: 'See full response',
suggestedFix: 'See full response',
debugPrompt,
confidence: 'low',
generatedAt: Date.now(),
provider,
model,
};
}