fix false truncation

This commit is contained in:
overcuriousity 2025-08-17 23:45:28 +02:00
parent 6b09eb062f
commit 3d5d2506e9
2 changed files with 50 additions and 24 deletions

View File

@ -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 {

View File

@ -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',