airefactor #19
@ -1194,7 +1194,7 @@ class AIQueryInterface {
|
||||
) / responseQualityEntries.length;
|
||||
|
||||
if (avgResponseQuality >= 70) {
|
||||
keyInsights.push(`Hohe AI-Antwortqualität (Ø ${Math.round(avgResponseQuality)}%)`);
|
||||
keyInsights.push(`Hohe AI-Antwortqualität (∅ ${Math.round(avgResponseQuality)}%)`);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1203,12 +1203,41 @@ class AIQueryInterface {
|
||||
potentialIssues.push(`${lowConfidenceSteps} Analyseschritte mit niedriger Konfidenz`);
|
||||
}
|
||||
|
||||
const truncatedResponses = auditTrail.filter(e =>
|
||||
e.output && typeof e.output === 'object' &&
|
||||
e.output.response && e.output.response.includes('...')
|
||||
// FIXED: Only detect actual AI incompleteness, not display truncation
|
||||
// The old code incorrectly flagged display truncation as incomplete responses:
|
||||
// OLD (WRONG): e.output.response && e.output.response.includes('...')
|
||||
|
||||
// NEW (CORRECT): Check metadata.aiResponse for actual incompleteness
|
||||
const incompleteAIResponses = auditTrail.filter(e =>
|
||||
e.action === 'ai-decision' &&
|
||||
e.metadata?.aiResponse &&
|
||||
(
|
||||
// Detect actual AI incompleteness patterns:
|
||||
e.metadata.aiResponse.trim().length < 10 || // Very short response
|
||||
e.metadata.aiResponse.endsWith('...') || // AI itself truncated (rare but possible)
|
||||
e.metadata.aiResponse.includes('[TRUNCATED]') || // Explicit truncation marker
|
||||
e.metadata.aiResponse.includes('I cannot continue') || // AI stopped unexpectedly
|
||||
e.metadata.aiResponse.includes('I need to stop here') || // AI indicated incompleteness
|
||||
e.metadata.aiResponse.includes('[RESPONSE_TOO_LONG]') || // Length limit hit
|
||||
// Also check if the AI response seems cut off mid-sentence
|
||||
(e.metadata.aiResponse.length > 50 &&
|
||||
!e.metadata.aiResponse.trim().match(/[.!?:]$/)) // Doesn't end with proper punctuation
|
||||
)
|
||||
).length;
|
||||
if (truncatedResponses > 0) {
|
||||
potentialIssues.push(`${truncatedResponses} möglicherweise unvollständige AI-Antworten`);
|
||||
|
||||
if (incompleteAIResponses > 0) {
|
||||
potentialIssues.push(`${incompleteAIResponses} möglicherweise unvollständige AI-Antworten`);
|
||||
}
|
||||
|
||||
// Additional quality checks
|
||||
const veryShortResponses = auditTrail.filter(e =>
|
||||
e.action === 'ai-decision' &&
|
||||
e.metadata?.aiResponse &&
|
||||
e.metadata.aiResponse.trim().length < 20
|
||||
).length;
|
||||
|
||||
if (veryShortResponses > 1) {
|
||||
potentialIssues.push(`${veryShortResponses} ungewöhnlich kurze AI-Antworten`);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -129,15 +129,15 @@ class AuditService {
|
||||
this.addEntry(
|
||||
phase,
|
||||
'ai-decision',
|
||||
{ prompt: this.truncatePrompt(aiPrompt) },
|
||||
{ response: this.truncateResponse(aiResponse) },
|
||||
{ prompt: this.createPromptSummary(aiPrompt) }, // Summary for display only
|
||||
{ response: aiResponse }, // STORE FULL RESPONSE - NO TRUNCATION
|
||||
confidence,
|
||||
startTime,
|
||||
{
|
||||
...metadata,
|
||||
reasoning,
|
||||
aiPrompt: aiPrompt,
|
||||
aiResponse: aiResponse,
|
||||
aiPrompt: aiPrompt, // Full prompt in metadata
|
||||
aiResponse: aiResponse, // Full response in metadata
|
||||
decisionBasis: 'ai-analysis'
|
||||
}
|
||||
);
|
||||
@ -425,13 +425,13 @@ class AuditService {
|
||||
if (type === 'input') {
|
||||
if (data.prompt) {
|
||||
const promptPreview = data.prompt.slice(0, 80).replace(/\n/g, ' ');
|
||||
return `KI-Prompt: ${promptPreview}...`;
|
||||
return `KI-Prompt: ${promptPreview}${data.prompt.length > 80 ? ' [Vorschau]' : ''}`;
|
||||
}
|
||||
return 'KI-Analyse angefordert';
|
||||
} else {
|
||||
if (data.response) {
|
||||
const responsePreview = data.response.slice(0, 80).replace(/\n/g, ' ');
|
||||
return `KI-Antwort: ${responsePreview}...`;
|
||||
return `KI-Antwort: ${responsePreview}${data.response.length > 80 ? ' [Vorschau]' : ''}`;
|
||||
}
|
||||
return 'KI-Analyse abgeschlossen';
|
||||
}
|
||||
@ -446,8 +446,10 @@ class AuditService {
|
||||
}
|
||||
|
||||
case 'tool-added-to-phase':
|
||||
if (type === 'input') {
|
||||
return `${data.toolName} → ${data.phaseId} (${data.taskRelevance}% Relevanz, ${data.priority})`;
|
||||
if (type === 'output') {
|
||||
const justificationPreview = data.justification ?
|
||||
data.justification.slice(0, 60).replace(/\n/g, ' ') + (data.justification.length > 60 ? ' [Vorschau]' : '') : 'Hinzugefügt';
|
||||
return `Begründung: ${justificationPreview}`;
|
||||
} else {
|
||||
const justificationPreview = data.justification ?
|
||||
data.justification.slice(0, 60).replace(/\n/g, ' ') + '...' : 'Hinzugefügt';
|
||||
@ -512,6 +514,11 @@ class AuditService {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
private createPromptSummary(prompt: string): string {
|
||||
if (!prompt || prompt.length <= 200) return prompt;
|
||||
return prompt.slice(0, 200) + ' [Eingabe-Vorschau]';
|
||||
}
|
||||
|
||||
private generateSpecificReasoning(
|
||||
action: string,
|
||||
input: any,
|
||||
@ -572,16 +579,6 @@ class AuditService {
|
||||
}
|
||||
}
|
||||
|
||||
private truncatePrompt(prompt: string): string {
|
||||
if (!prompt || prompt.length <= 200) return prompt;
|
||||
return prompt.slice(0, 200) + '...[gekürzt]';
|
||||
}
|
||||
|
||||
private truncateResponse(response: string): string {
|
||||
if (!response || response.length <= 300) return response;
|
||||
return response.slice(0, 300) + '...[gekürzt]';
|
||||
}
|
||||
|
||||
private getPhaseDisplayName(phaseId: string): string {
|
||||
const phaseNames: Record<string, string> = {
|
||||
'preparation': 'Vorbereitung',
|
||||
|
Loading…
x
Reference in New Issue
Block a user