89 lines
3.1 KiB
JavaScript
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,
|
|
};
|
|
}
|