airefactor #19
@ -1185,7 +1185,6 @@ class AIQueryInterface {
|
|||||||
keyInsights.push('Mehrheit der Analyseschritte mit hoher Sicherheit');
|
keyInsights.push('Mehrheit der Analyseschritte mit hoher Sicherheit');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate meaningful insights based on response quality
|
|
||||||
const responseQualityEntries = auditTrail.filter(e =>
|
const responseQualityEntries = auditTrail.filter(e =>
|
||||||
e.metadata?.responseConfidence && e.metadata.finalConfidence
|
e.metadata?.responseConfidence && e.metadata.finalConfidence
|
||||||
);
|
);
|
||||||
@ -1204,7 +1203,6 @@ class AIQueryInterface {
|
|||||||
potentialIssues.push(`${lowConfidenceSteps} Analyseschritte mit niedriger Konfidenz`);
|
potentialIssues.push(`${lowConfidenceSteps} Analyseschritte mit niedriger Konfidenz`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for truncated responses
|
|
||||||
const truncatedResponses = auditTrail.filter(e =>
|
const truncatedResponses = auditTrail.filter(e =>
|
||||||
e.output && typeof e.output === 'object' &&
|
e.output && typeof e.output === 'object' &&
|
||||||
e.output.response && e.output.response.includes('...')
|
e.output.response && e.output.response.includes('...')
|
||||||
@ -1230,7 +1228,6 @@ class AIQueryInterface {
|
|||||||
medium: mediumConfidenceSteps,
|
medium: mediumConfidenceSteps,
|
||||||
low: lowConfidenceSteps
|
low: lowConfidenceSteps
|
||||||
}
|
}
|
||||||
// aiTransparency removed entirely
|
|
||||||
},
|
},
|
||||||
analysisQuality,
|
analysisQuality,
|
||||||
keyInsights,
|
keyInsights,
|
||||||
@ -1339,7 +1336,6 @@ class AIQueryInterface {
|
|||||||
const details = [];
|
const details = [];
|
||||||
const metadata = entry.metadata || {};
|
const metadata = entry.metadata || {};
|
||||||
|
|
||||||
// The backend now provides meaningful inputSummary and outputSummary
|
|
||||||
if (metadata.inputSummary && metadata.inputSummary !== 'Leer') {
|
if (metadata.inputSummary && metadata.inputSummary !== 'Leer') {
|
||||||
details.push(`<div class="detail-item"><strong>Eingabe:</strong> ${escapeHtml(metadata.inputSummary)}</div>`);
|
details.push(`<div class="detail-item"><strong>Eingabe:</strong> ${escapeHtml(metadata.inputSummary)}</div>`);
|
||||||
}
|
}
|
||||||
@ -1348,12 +1344,10 @@ class AIQueryInterface {
|
|||||||
details.push(`<div class="detail-item"><strong>Ausgabe:</strong> ${escapeHtml(metadata.outputSummary)}</div>`);
|
details.push(`<div class="detail-item"><strong>Ausgabe:</strong> ${escapeHtml(metadata.outputSummary)}</div>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show meaningful reasoning (backend now avoids generic "completed with X%" messages)
|
|
||||||
if (metadata.reasoning && !metadata.reasoning.includes('completed with')) {
|
if (metadata.reasoning && !metadata.reasoning.includes('completed with')) {
|
||||||
details.push(`<div class="detail-item"><strong>Begründung:</strong> ${escapeHtml(metadata.reasoning)}</div>`);
|
details.push(`<div class="detail-item"><strong>Begründung:</strong> ${escapeHtml(metadata.reasoning)}</div>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action-specific additional details
|
|
||||||
if (entry.action === 'similarity-search' && metadata.similarityScores) {
|
if (entry.action === 'similarity-search' && metadata.similarityScores) {
|
||||||
const topScores = Object.entries(metadata.similarityScores)
|
const topScores = Object.entries(metadata.similarityScores)
|
||||||
.sort(([,a], [,b]) => (b) - (a))
|
.sort(([,a], [,b]) => (b) - (a))
|
||||||
@ -1597,11 +1591,9 @@ class AIQueryInterface {
|
|||||||
embeddingsSimilarities: {}
|
embeddingsSimilarities: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Enhanced export structure with proper audit trail handling
|
|
||||||
const exportData = {
|
const exportData = {
|
||||||
metadata: {
|
metadata: {
|
||||||
timestamp: new Date().toISOString(),
|
timestamp: new Date().toISOString(),
|
||||||
version: "1.1", // Increment version for improved structure
|
|
||||||
toolsDataHash: toolsDataHash,
|
toolsDataHash: toolsDataHash,
|
||||||
aiModel: aiModel,
|
aiModel: aiModel,
|
||||||
aiParameters: aiParameters,
|
aiParameters: aiParameters,
|
||||||
@ -1609,16 +1601,13 @@ class AIQueryInterface {
|
|||||||
mode: this.currentMode,
|
mode: this.currentMode,
|
||||||
processingStats: processingStats,
|
processingStats: processingStats,
|
||||||
exportedBy: 'ForensicPathways',
|
exportedBy: 'ForensicPathways',
|
||||||
auditTrailVersion: '1.1' // Track audit trail format version
|
|
||||||
},
|
},
|
||||||
recommendation: {
|
recommendation: {
|
||||||
// Export recommendation without auditTrail to avoid duplication
|
|
||||||
...this.currentRecommendation,
|
...this.currentRecommendation,
|
||||||
auditTrail: undefined // Remove from recommendation as it's at top level
|
auditTrail: undefined
|
||||||
},
|
},
|
||||||
auditTrail: this.currentRecommendation.auditTrail || [], // Extract to top level
|
auditTrail: this.currentRecommendation.auditTrail || [],
|
||||||
rawContext: rawContext,
|
rawContext: rawContext,
|
||||||
// Add validation checksum for integrity
|
|
||||||
checksum: this.calculateDataChecksum(this.currentRecommendation)
|
checksum: this.calculateDataChecksum(this.currentRecommendation)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1647,7 +1636,6 @@ class AIQueryInterface {
|
|||||||
if (!data) return 'empty';
|
if (!data) return 'empty';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Simple checksum based on key data properties
|
|
||||||
const keyData = {
|
const keyData = {
|
||||||
recommendedToolsCount: data.recommended_tools?.length || 0,
|
recommendedToolsCount: data.recommended_tools?.length || 0,
|
||||||
backgroundKnowledgeCount: data.background_knowledge?.length || 0,
|
backgroundKnowledgeCount: data.background_knowledge?.length || 0,
|
||||||
@ -1661,7 +1649,7 @@ class AIQueryInterface {
|
|||||||
for (let i = 0; i < dataString.length; i++) {
|
for (let i = 0; i < dataString.length; i++) {
|
||||||
const char = dataString.charCodeAt(i);
|
const char = dataString.charCodeAt(i);
|
||||||
hash = ((hash << 5) - hash) + char;
|
hash = ((hash << 5) - hash) + char;
|
||||||
hash = hash & hash; // Convert to 32-bit integer
|
hash = hash & hash;
|
||||||
}
|
}
|
||||||
return Math.abs(hash).toString(36);
|
return Math.abs(hash).toString(36);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@ -1680,14 +1668,13 @@ class AIQueryInterface {
|
|||||||
typeof data.metadata.timestamp === 'string' &&
|
typeof data.metadata.timestamp === 'string' &&
|
||||||
data.recommendation &&
|
data.recommendation &&
|
||||||
typeof data.recommendation === 'object' &&
|
typeof data.recommendation === 'object' &&
|
||||||
Array.isArray(data.auditTrail) // Audit trail at top level
|
Array.isArray(data.auditTrail)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced validation for audit trail structure
|
|
||||||
if (data.auditTrail.length > 0) {
|
if (data.auditTrail.length > 0) {
|
||||||
const sampleEntry = data.auditTrail[0];
|
const sampleEntry = data.auditTrail[0];
|
||||||
const hasRequiredFields = !!(
|
const hasRequiredFields = !!(
|
||||||
@ -1718,10 +1705,9 @@ class AIQueryInterface {
|
|||||||
|
|
||||||
this.showUploadedBanner(data.metadata);
|
this.showUploadedBanner(data.metadata);
|
||||||
|
|
||||||
// Fix: Ensure audit trail is available in recommendation for restoreAIResults
|
|
||||||
this.currentRecommendation = {
|
this.currentRecommendation = {
|
||||||
...data.recommendation,
|
...data.recommendation,
|
||||||
auditTrail: data.auditTrail // Restore audit trail to recommendation object
|
auditTrail: data.auditTrail
|
||||||
};
|
};
|
||||||
|
|
||||||
this.showResults();
|
this.showResults();
|
||||||
@ -1813,7 +1799,6 @@ class AIQueryInterface {
|
|||||||
throw new Error('Ungültiges Analyse-Dateiformat');
|
throw new Error('Ungültiges Analyse-Dateiformat');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store audit trail separately for restore function
|
|
||||||
this.uploadedAuditTrail = data.auditTrail;
|
this.uploadedAuditTrail = data.auditTrail;
|
||||||
|
|
||||||
console.log('[AI Interface] Valid previous analysis file uploaded:', {
|
console.log('[AI Interface] Valid previous analysis file uploaded:', {
|
||||||
@ -2282,7 +2267,6 @@ class AIQueryInterface {
|
|||||||
if (this.currentRecommendation && this.elements.results) {
|
if (this.currentRecommendation && this.elements.results) {
|
||||||
this.showResults();
|
this.showResults();
|
||||||
|
|
||||||
// Check both locations for audit trail for backward compatibility
|
|
||||||
const auditTrail = this.currentRecommendation.auditTrail || this.uploadedAuditTrail;
|
const auditTrail = this.currentRecommendation.auditTrail || this.uploadedAuditTrail;
|
||||||
|
|
||||||
if (auditTrail && Array.isArray(auditTrail) && auditTrail.length > 0) {
|
if (auditTrail && Array.isArray(auditTrail) && auditTrail.length > 0) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
// src/components/ContributionButton.astro - CLEANED: Removed duplicate auth script
|
// src/components/ContributionButton.astro
|
||||||
export interface Props {
|
export interface Props {
|
||||||
type: 'edit' | 'new' | 'write';
|
type: 'edit' | 'new' | 'write';
|
||||||
toolName?: string;
|
toolName?: string;
|
||||||
|
@ -4,7 +4,6 @@ import { getToolsData } from '../utils/dataService.js';
|
|||||||
const data = await getToolsData();
|
const data = await getToolsData();
|
||||||
const scenarios = data.scenarios || [];
|
const scenarios = data.scenarios || [];
|
||||||
|
|
||||||
// Configuration
|
|
||||||
const maxDisplayed = 9;
|
const maxDisplayed = 9;
|
||||||
const displayedScenarios = scenarios.slice(0, maxDisplayed);
|
const displayedScenarios = scenarios.slice(0, maxDisplayed);
|
||||||
---
|
---
|
||||||
|
@ -16,7 +16,7 @@ const knowledgebaseCollection = defineCollection({
|
|||||||
tags: z.array(z.string()).default([]),
|
tags: z.array(z.string()).default([]),
|
||||||
|
|
||||||
published: z.boolean().default(true),
|
published: z.boolean().default(true),
|
||||||
gated_content: z.boolean().default(false), // NEW: Gated content flag
|
gated_content: z.boolean().default(false),
|
||||||
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// src/pages/api/ai/embeddings-status.ts - Updated
|
// src/pages/api/ai/embeddings-status.ts
|
||||||
import type { APIRoute } from 'astro';
|
import type { APIRoute } from 'astro';
|
||||||
import { embeddingsService } from '../../../utils/embeddings.js';
|
import { embeddingsService } from '../../../utils/embeddings.js';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// src/pages/api/ai/enhance-input.ts - Updated to use refactored services
|
// src/pages/api/ai/enhance-input.ts
|
||||||
import type { APIRoute } from 'astro';
|
import type { APIRoute } from 'astro';
|
||||||
import { withAPIAuth } from '../../../utils/auth.js';
|
import { withAPIAuth } from '../../../utils/auth.js';
|
||||||
import { apiError, apiServerError, createAuthErrorResponse } from '../../../utils/api.js';
|
import { apiError, apiServerError, createAuthErrorResponse } from '../../../utils/api.js';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// src/pages/api/ai/query.ts - Updated to use refactored services
|
// src/pages/api/ai/query.ts
|
||||||
import type { APIRoute } from 'astro';
|
import type { APIRoute } from 'astro';
|
||||||
import { withAPIAuth } from '../../../utils/auth.js';
|
import { withAPIAuth } from '../../../utils/auth.js';
|
||||||
import { apiError, apiServerError, createAuthErrorResponse } from '../../../utils/api.js';
|
import { apiError, apiServerError, createAuthErrorResponse } from '../../../utils/api.js';
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
// src/pages/contribute/index.astro - Consolidated Auth
|
// src/pages/contribute/index.astro
|
||||||
import BaseLayout from '../../layouts/BaseLayout.astro';
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
||||||
import { withAuth } from '../../utils/auth.js';
|
import { withAuth } from '../../utils/auth.js';
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// src/utils/aiPipeline.ts - Fixed to remove hardcoded values and improve dynamics
|
// src/utils/aiPipeline.ts
|
||||||
import { getCompressedToolsDataForAI, getDataVersion } from './dataService.js';
|
import { getCompressedToolsDataForAI, getDataVersion } from './dataService.js';
|
||||||
import { aiService } from './aiService.js';
|
import { aiService } from './aiService.js';
|
||||||
import { toolSelector, type SelectionContext } from './toolSelector.js';
|
import { toolSelector, type SelectionContext } from './toolSelector.js';
|
||||||
@ -77,7 +77,6 @@ interface PipelineContext {
|
|||||||
}>;
|
}>;
|
||||||
seenToolNames: Set<string>;
|
seenToolNames: Set<string>;
|
||||||
embeddingsSimilarities: Map<string, number>;
|
embeddingsSimilarities: Map<string, number>;
|
||||||
// Add phase metadata for dynamic phase handling
|
|
||||||
phaseMetadata?: {
|
phaseMetadata?: {
|
||||||
phases: any[];
|
phases: any[];
|
||||||
criticalPhaseIds: string[];
|
criticalPhaseIds: string[];
|
||||||
@ -128,7 +127,6 @@ class AIPipeline {
|
|||||||
currentContextLength: 0,
|
currentContextLength: 0,
|
||||||
seenToolNames: new Set<string>(),
|
seenToolNames: new Set<string>(),
|
||||||
embeddingsSimilarities: new Map<string, number>(),
|
embeddingsSimilarities: new Map<string, number>(),
|
||||||
// Initialize phase metadata dynamically
|
|
||||||
phaseMetadata: this.initializePhaseMetadata(toolsData.phases)
|
phaseMetadata: this.initializePhaseMetadata(toolsData.phases)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -259,20 +257,17 @@ class AIPipeline {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamically determine critical phases based on typical_tools or key_activities
|
|
||||||
const criticalPhaseIds = phases
|
const criticalPhaseIds = phases
|
||||||
.filter(phase => {
|
.filter(phase => {
|
||||||
const typicalToolsCount = phase.typical_tools?.length || 0;
|
const typicalToolsCount = phase.typical_tools?.length || 0;
|
||||||
const keyActivitiesCount = phase.key_activities?.length || 0;
|
const keyActivitiesCount = phase.key_activities?.length || 0;
|
||||||
// Consider phases with many tools or activities as critical
|
|
||||||
return typicalToolsCount >= 3 || keyActivitiesCount >= 2;
|
return typicalToolsCount >= 3 || keyActivitiesCount >= 2;
|
||||||
})
|
})
|
||||||
.map(phase => phase.id);
|
.map(phase => phase.id);
|
||||||
|
|
||||||
// Calculate phase complexity based on metadata
|
|
||||||
const phaseComplexity = new Map<string, number>();
|
const phaseComplexity = new Map<string, number>();
|
||||||
phases.forEach(phase => {
|
phases.forEach(phase => {
|
||||||
let complexity = 1; // Base complexity
|
let complexity = 1;
|
||||||
|
|
||||||
if (phase.typical_tools?.length > 5) complexity += 1;
|
if (phase.typical_tools?.length > 5) complexity += 1;
|
||||||
if (phase.key_activities?.length > 3) complexity += 1;
|
if (phase.key_activities?.length > 3) complexity += 1;
|
||||||
@ -389,7 +384,6 @@ class AIPipeline {
|
|||||||
const moderatedTaskRelevance = this.moderateTaskRelevance(sel.taskRelevance);
|
const moderatedTaskRelevance = this.moderateTaskRelevance(sel.taskRelevance);
|
||||||
const priority = this.derivePriorityFromScore(moderatedTaskRelevance);
|
const priority = this.derivePriorityFromScore(moderatedTaskRelevance);
|
||||||
|
|
||||||
// Generate dynamic limitations based on context
|
|
||||||
const dynamicLimitations = this.generateDynamicLimitations(tool, phase, sel);
|
const dynamicLimitations = this.generateDynamicLimitations(tool, phase, sel);
|
||||||
|
|
||||||
this.addToolToSelection(context, tool, phase.id, priority, sel.justification, moderatedTaskRelevance, dynamicLimitations);
|
this.addToolToSelection(context, tool, phase.id, priority, sel.justification, moderatedTaskRelevance, dynamicLimitations);
|
||||||
@ -444,18 +438,15 @@ class AIPipeline {
|
|||||||
): number {
|
): number {
|
||||||
let confidence = 60;
|
let confidence = 60;
|
||||||
|
|
||||||
// Use dynamic phase metadata instead of hardcoded values
|
|
||||||
const isCritical = phaseMetadata?.criticalPhaseIds.includes(phaseId) || false;
|
const isCritical = phaseMetadata?.criticalPhaseIds.includes(phaseId) || false;
|
||||||
const phaseComplexity = phaseMetadata?.phaseComplexity.get(phaseId) || 1;
|
const phaseComplexity = phaseMetadata?.phaseComplexity.get(phaseId) || 1;
|
||||||
|
|
||||||
// Selection made
|
|
||||||
if (selectedCount > 0) {
|
if (selectedCount > 0) {
|
||||||
confidence += 20;
|
confidence += 20;
|
||||||
} else {
|
} else {
|
||||||
return 30;
|
return 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Selection ratio (for phases, 20-50% is reasonable)
|
|
||||||
const ratio = selectedCount / availableCount;
|
const ratio = selectedCount / availableCount;
|
||||||
if (ratio >= 0.2 && ratio <= 0.5) {
|
if (ratio >= 0.2 && ratio <= 0.5) {
|
||||||
confidence += 15;
|
confidence += 15;
|
||||||
@ -463,17 +454,14 @@ class AIPipeline {
|
|||||||
confidence += 10;
|
confidence += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dynamic critical phase handling
|
|
||||||
if (isCritical && selectedCount >= 2) {
|
if (isCritical && selectedCount >= 2) {
|
||||||
confidence += 10;
|
confidence += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase complexity factor
|
|
||||||
if (phaseComplexity > 2 && selectedCount >= phaseComplexity) {
|
if (phaseComplexity > 2 && selectedCount >= phaseComplexity) {
|
||||||
confidence += 5;
|
confidence += 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quality of selections (based on task relevance)
|
|
||||||
const avgRelevance = selections.length > 0 ?
|
const avgRelevance = selections.length > 0 ?
|
||||||
selections.reduce((sum, s) => sum + (s.taskRelevance || 70), 0) / selections.length : 0;
|
selections.reduce((sum, s) => sum + (s.taskRelevance || 70), 0) / selections.length : 0;
|
||||||
|
|
||||||
@ -489,12 +477,10 @@ class AIPipeline {
|
|||||||
private generateDynamicLimitations(tool: any, phase: any, selection: any): string[] {
|
private generateDynamicLimitations(tool: any, phase: any, selection: any): string[] {
|
||||||
const limitations: string[] = [];
|
const limitations: string[] = [];
|
||||||
|
|
||||||
// Add existing limitations if provided
|
|
||||||
if (selection.limitations && Array.isArray(selection.limitations)) {
|
if (selection.limitations && Array.isArray(selection.limitations)) {
|
||||||
limitations.push(...selection.limitations);
|
limitations.push(...selection.limitations);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate context-aware limitations
|
|
||||||
if (tool.type === 'software' && !tool.projectUrl) {
|
if (tool.type === 'software' && !tool.projectUrl) {
|
||||||
limitations.push('Installation und Konfiguration erforderlich');
|
limitations.push('Installation und Konfiguration erforderlich');
|
||||||
}
|
}
|
||||||
@ -507,12 +493,11 @@ class AIPipeline {
|
|||||||
limitations.push('Kommerzielle Lizenz erforderlich');
|
limitations.push('Kommerzielle Lizenz erforderlich');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase-specific limitations
|
|
||||||
if (phase.id === 'acquisition' && tool.type === 'method') {
|
if (phase.id === 'acquisition' && tool.type === 'method') {
|
||||||
limitations.push('Sorgfältige Dokumentation für Chain of Custody erforderlich');
|
limitations.push('Sorgfältige Dokumentation für Chain of Custody erforderlich');
|
||||||
}
|
}
|
||||||
|
|
||||||
return limitations.slice(0, 3); // Limit to 3 most relevant
|
return limitations.slice(0, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async processToolMode(
|
private async processToolMode(
|
||||||
@ -699,7 +684,6 @@ class AIPipeline {
|
|||||||
moderatedTaskRelevance = this.moderateTaskRelevance(75);
|
moderatedTaskRelevance = this.moderateTaskRelevance(75);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate dynamic limitations instead of hardcoded ones
|
|
||||||
const dynamicLimitations = this.generateCompletionLimitations(tool, phase, selection);
|
const dynamicLimitations = this.generateCompletionLimitations(tool, phase, selection);
|
||||||
|
|
||||||
this.addToolToSelection(
|
this.addToolToSelection(
|
||||||
@ -754,10 +738,8 @@ class AIPipeline {
|
|||||||
private generateCompletionLimitations(tool: any, phase: any, selection: any): string[] {
|
private generateCompletionLimitations(tool: any, phase: any, selection: any): string[] {
|
||||||
const limitations: string[] = [];
|
const limitations: string[] = [];
|
||||||
|
|
||||||
// Context-specific limitation for completion tools
|
|
||||||
limitations.push('Nachträgliche Ergänzung - ursprünglich nicht als Hauptmethode identifiziert');
|
limitations.push('Nachträgliche Ergänzung - ursprünglich nicht als Hauptmethode identifiziert');
|
||||||
|
|
||||||
// Tool-specific limitations
|
|
||||||
if (tool.skillLevel === 'expert') {
|
if (tool.skillLevel === 'expert') {
|
||||||
limitations.push('Erfordert Expertenwissen für optimale Nutzung');
|
limitations.push('Erfordert Expertenwissen für optimale Nutzung');
|
||||||
}
|
}
|
||||||
@ -766,7 +748,6 @@ class AIPipeline {
|
|||||||
limitations.push('Zusätzliche Setup-Zeit erforderlich');
|
limitations.push('Zusätzliche Setup-Zeit erforderlich');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Phase-specific context
|
|
||||||
if (phase.typical_tools && !phase.typical_tools.includes(tool.name)) {
|
if (phase.typical_tools && !phase.typical_tools.includes(tool.name)) {
|
||||||
limitations.push(`Nicht typisch für ${phase.name}-Phase - alternative Anwendung`);
|
limitations.push(`Nicht typisch für ${phase.name}-Phase - alternative Anwendung`);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// src/utils/auditService.ts - Fixed with meaningful confidence and reasoning
|
// src/utils/auditService.ts
|
||||||
import 'dotenv/config';
|
import 'dotenv/config';
|
||||||
|
|
||||||
function env(key: string, fallback: string | undefined = undefined): string | undefined {
|
function env(key: string, fallback: string | undefined = undefined): string | undefined {
|
||||||
@ -85,7 +85,6 @@ class AuditService {
|
|||||||
): void {
|
): void {
|
||||||
if (!this.config.enabled) return;
|
if (!this.config.enabled) return;
|
||||||
|
|
||||||
// Skip initialization and completion entries as they don't add transparency
|
|
||||||
if (action === 'pipeline-start' || action === 'pipeline-end') {
|
if (action === 'pipeline-start' || action === 'pipeline-end') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -152,7 +151,6 @@ class AuditService {
|
|||||||
startTime: number,
|
startTime: number,
|
||||||
metadata: Record<string, any> = {}
|
metadata: Record<string, any> = {}
|
||||||
): void {
|
): void {
|
||||||
// Calculate meaningful confidence based on selection quality
|
|
||||||
const calculatedConfidence = this.calculateSelectionConfidence(
|
const calculatedConfidence = this.calculateSelectionConfidence(
|
||||||
selectedTools,
|
selectedTools,
|
||||||
availableTools,
|
availableTools,
|
||||||
@ -164,7 +162,7 @@ class AuditService {
|
|||||||
'tool-selection',
|
'tool-selection',
|
||||||
'selection-decision',
|
'selection-decision',
|
||||||
{
|
{
|
||||||
availableTools: availableTools.slice(0, 10), // Show first 10 for context
|
availableTools: availableTools.slice(0, 10),
|
||||||
totalAvailable: availableTools.length,
|
totalAvailable: availableTools.length,
|
||||||
selectionMethod: selectionMethod
|
selectionMethod: selectionMethod
|
||||||
},
|
},
|
||||||
@ -191,7 +189,6 @@ class AuditService {
|
|||||||
startTime: number,
|
startTime: number,
|
||||||
metadata: Record<string, any> = {}
|
metadata: Record<string, any> = {}
|
||||||
): void {
|
): void {
|
||||||
// Only add if tools were actually added
|
|
||||||
if (!addedTools || addedTools.length === 0) {
|
if (!addedTools || addedTools.length === 0) {
|
||||||
console.log(`[AUDIT-SERVICE] Skipping phase completion for ${phaseId} - no tools added`);
|
console.log(`[AUDIT-SERVICE] Skipping phase completion for ${phaseId} - no tools added`);
|
||||||
return;
|
return;
|
||||||
@ -292,21 +289,18 @@ class AuditService {
|
|||||||
|
|
||||||
const selectionRatio = selectedTools.length / availableTools.length;
|
const selectionRatio = selectedTools.length / availableTools.length;
|
||||||
|
|
||||||
// Good selection ratio (5-20% of available tools)
|
|
||||||
if (selectionRatio >= 0.05 && selectionRatio <= 0.20) {
|
if (selectionRatio >= 0.05 && selectionRatio <= 0.20) {
|
||||||
confidence += 25;
|
confidence += 25;
|
||||||
} else if (selectionRatio < 0.05) {
|
} else if (selectionRatio < 0.05) {
|
||||||
confidence += 15; // Very selective is good
|
confidence += 15;
|
||||||
} else if (selectionRatio > 0.30) {
|
} else if (selectionRatio > 0.30) {
|
||||||
confidence -= 20; // Too many tools selected
|
confidence -= 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Embeddings usage bonus
|
|
||||||
if (selectionMethod.includes('embeddings')) {
|
if (selectionMethod.includes('embeddings')) {
|
||||||
confidence += 15;
|
confidence += 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reasonable number of tools selected
|
|
||||||
if (selectedTools.length >= 5 && selectedTools.length <= 25) {
|
if (selectedTools.length >= 5 && selectedTools.length <= 25) {
|
||||||
confidence += 10;
|
confidence += 10;
|
||||||
}
|
}
|
||||||
@ -321,22 +315,18 @@ class AuditService {
|
|||||||
): number {
|
): number {
|
||||||
let confidence = 60;
|
let confidence = 60;
|
||||||
|
|
||||||
// Tools actually added
|
|
||||||
if (addedTools.length > 0) {
|
if (addedTools.length > 0) {
|
||||||
confidence += 20;
|
confidence += 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Good reasoning provided
|
|
||||||
if (reasoning && reasoning.length > 50) {
|
if (reasoning && reasoning.length > 50) {
|
||||||
confidence += 15;
|
confidence += 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI reasoning was used successfully
|
|
||||||
if (metadata.aiReasoningUsed) {
|
if (metadata.aiReasoningUsed) {
|
||||||
confidence += 10;
|
confidence += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not too many tools added (indicates thoughtful selection)
|
|
||||||
if (addedTools.length <= 2) {
|
if (addedTools.length <= 2) {
|
||||||
confidence += 5;
|
confidence += 5;
|
||||||
}
|
}
|
||||||
@ -347,17 +337,14 @@ class AuditService {
|
|||||||
private calculateEmbeddingsConfidence(similarResults: any[], threshold: number): number {
|
private calculateEmbeddingsConfidence(similarResults: any[], threshold: number): number {
|
||||||
let confidence = 50;
|
let confidence = 50;
|
||||||
|
|
||||||
// Found relevant results
|
|
||||||
if (similarResults.length > 0) {
|
if (similarResults.length > 0) {
|
||||||
confidence += 20;
|
confidence += 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Good number of results (not too few, not too many)
|
|
||||||
if (similarResults.length >= 5 && similarResults.length <= 30) {
|
if (similarResults.length >= 5 && similarResults.length <= 30) {
|
||||||
confidence += 15;
|
confidence += 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
// High similarity scores
|
|
||||||
const avgSimilarity = similarResults.length > 0 ?
|
const avgSimilarity = similarResults.length > 0 ?
|
||||||
similarResults.reduce((sum, r) => sum + r.similarity, 0) / similarResults.length : 0;
|
similarResults.reduce((sum, r) => sum + r.similarity, 0) / similarResults.length : 0;
|
||||||
|
|
||||||
@ -367,7 +354,6 @@ class AuditService {
|
|||||||
confidence += 10;
|
confidence += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reasonable threshold
|
|
||||||
if (threshold >= 0.3 && threshold <= 0.5) {
|
if (threshold >= 0.3 && threshold <= 0.5) {
|
||||||
confidence += 5;
|
confidence += 5;
|
||||||
}
|
}
|
||||||
@ -378,7 +364,6 @@ class AuditService {
|
|||||||
private createSpecificSummary(data: any, action: string, type: 'input' | 'output'): string {
|
private createSpecificSummary(data: any, action: string, type: 'input' | 'output'): string {
|
||||||
if (!data) return 'Leer';
|
if (!data) return 'Leer';
|
||||||
|
|
||||||
// Action-specific summaries that show actual meaningful data
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'selection-decision':
|
case 'selection-decision':
|
||||||
if (type === 'input') {
|
if (type === 'input') {
|
||||||
@ -476,7 +461,6 @@ class AuditService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enhanced fallback that shows actual key-value content instead of just "X Eigenschaften"
|
|
||||||
if (typeof data === 'string') {
|
if (typeof data === 'string') {
|
||||||
return data.length > 100 ? data.slice(0, 100) + '...' : data;
|
return data.length > 100 ? data.slice(0, 100) + '...' : data;
|
||||||
}
|
}
|
||||||
@ -491,7 +475,6 @@ class AuditService {
|
|||||||
const keys = Object.keys(data);
|
const keys = Object.keys(data);
|
||||||
if (keys.length === 0) return 'Leeres Objekt';
|
if (keys.length === 0) return 'Leeres Objekt';
|
||||||
|
|
||||||
// Show actual key-value pairs for small objects instead of just counting properties
|
|
||||||
if (keys.length <= 2) {
|
if (keys.length <= 2) {
|
||||||
const pairs = keys.map(key => {
|
const pairs = keys.map(key => {
|
||||||
const value = data[key];
|
const value = data[key];
|
||||||
@ -505,7 +488,6 @@ class AuditService {
|
|||||||
});
|
});
|
||||||
return pairs.join(', ');
|
return pairs.join(', ');
|
||||||
} else {
|
} else {
|
||||||
// For larger objects, show key names and some sample values
|
|
||||||
const sampleKeys = keys.slice(0, 3);
|
const sampleKeys = keys.slice(0, 3);
|
||||||
const sampleValues = sampleKeys.map(key => {
|
const sampleValues = sampleKeys.map(key => {
|
||||||
const value = data[key];
|
const value = data[key];
|
||||||
@ -531,7 +513,6 @@ class AuditService {
|
|||||||
metadata: Record<string, any>,
|
metadata: Record<string, any>,
|
||||||
confidence: number
|
confidence: number
|
||||||
): string {
|
): string {
|
||||||
// Use provided reasoning if available and meaningful
|
|
||||||
if (metadata.reasoning && metadata.reasoning.length > 20 && !metadata.reasoning.includes('completed with')) {
|
if (metadata.reasoning && metadata.reasoning.length > 20 && !metadata.reasoning.includes('completed with')) {
|
||||||
return metadata.reasoning;
|
return metadata.reasoning;
|
||||||
}
|
}
|
||||||
@ -546,11 +527,9 @@ class AuditService {
|
|||||||
const totalMatches =
|
const totalMatches =
|
||||||
typeof metadata.totalMatches === 'number' ? metadata.totalMatches : 0;
|
typeof metadata.totalMatches === 'number' ? metadata.totalMatches : 0;
|
||||||
|
|
||||||
// Safely narrow & cast similarityScores to a number map
|
|
||||||
const scoresObj = (metadata.similarityScores ?? {}) as Record<string, number>;
|
const scoresObj = (metadata.similarityScores ?? {}) as Record<string, number>;
|
||||||
const scores = Object.values(scoresObj) as number[];
|
const scores = Object.values(scoresObj) as number[];
|
||||||
|
|
||||||
// Use totalMatches if it looks sensible; otherwise fall back to scores.length
|
|
||||||
const denom = totalMatches > 0 ? totalMatches : scores.length;
|
const denom = totalMatches > 0 ? totalMatches : scores.length;
|
||||||
|
|
||||||
const sum = scores.reduce((acc, v) => acc + (typeof v === 'number' ? v : 0), 0);
|
const sum = scores.reduce((acc, v) => acc + (typeof v === 'number' ? v : 0), 0);
|
||||||
@ -697,9 +676,7 @@ class AuditService {
|
|||||||
return Math.min(95, Math.max(25, confidence));
|
return Math.min(95, Math.max(25, confidence));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional utility methods remain the same...
|
|
||||||
getAuditStatistics(auditTrail: AuditEntry[]): any {
|
getAuditStatistics(auditTrail: AuditEntry[]): any {
|
||||||
// Implementation remains the same as before
|
|
||||||
if (!auditTrail || auditTrail.length === 0) {
|
if (!auditTrail || auditTrail.length === 0) {
|
||||||
return {
|
return {
|
||||||
totalTime: 0,
|
totalTime: 0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user