cleanup
This commit is contained in:
		
							parent
							
								
									1d91dbf478
								
							
						
					
					
						commit
						6160620e24
					
				@ -51,7 +51,7 @@ function cleanupExpiredRateLimits(): void {
 | 
			
		||||
setInterval(cleanupExpiredRateLimits, 5 * 60 * 1000);
 | 
			
		||||
 | 
			
		||||
function createEnhancementPrompt(input: string): string {
 | 
			
		||||
  return `Sie sind ein DFIR-Experte mit Spezialisierung auf forensische Methodik. Ein Nutzer beschreibt ein forensisches Szenario oder Problem. Analysieren Sie die Eingabe auf Vollständigkeit für eine wissenschaftlich fundierte forensische Untersuchung.
 | 
			
		||||
  return `Sie sind ein DFIR-Experte mit Spezialisierung auf forensische Methodik. Ein Nutzer beschreibt ein Szenario oder Problem. Analysieren Sie die Eingabe auf Vollständigkeit für eine wissenschaftlich fundierte Untersuchung.
 | 
			
		||||
 | 
			
		||||
ANALYSIEREN SIE DIESE FORENSISCHEN KATEGORIEN:
 | 
			
		||||
1. **Incident Context**: Was ist passiert? Welche Angriffsvektoren oder technischen Probleme liegen vor?
 | 
			
		||||
@ -64,12 +64,12 @@ ANALYSIEREN SIE DIESE FORENSISCHEN KATEGORIEN:
 | 
			
		||||
 | 
			
		||||
WENN die Beschreibung alle kritischen forensischen Aspekte abdeckt: Geben Sie eine leere Liste [] zurück.
 | 
			
		||||
 | 
			
		||||
WENN wichtige forensische Details fehlen: Formulieren Sie 2-3 präzise Fragen, die die kritischsten Lücken für eine wissenschaftlich fundierte forensische Analyse schließen.
 | 
			
		||||
WENN wichtige Details fehlen: Formulieren Sie 2-3 präzise Fragen, die die kritischsten Lücken für eine wissenschaftlich fundierte Analyse schließen.
 | 
			
		||||
 | 
			
		||||
QUALITÄTSKRITERIEN FÜR FRAGEN:
 | 
			
		||||
- Forensisch spezifisch, nicht allgemein (NICHT: "Mehr Details?")
 | 
			
		||||
- Methodisch relevant (NICHT: "Wann passierte das?")
 | 
			
		||||
- Priorisiert nach Auswirkung auf die forensische Untersuchungsqualität
 | 
			
		||||
- Priorisiert nach Auswirkung auf die Untersuchungsqualität
 | 
			
		||||
- Die Frage soll maximal 20 Wörter umfassen
 | 
			
		||||
 | 
			
		||||
ANTWORTFORMAT (NUR JSON, KEIN ZUSÄTZLICHER TEXT):
 | 
			
		||||
@ -116,7 +116,6 @@ export const POST: APIRoute = async ({ request }) => {
 | 
			
		||||
    
 | 
			
		||||
    const aiResponse = await enqueueApiCall(() => 
 | 
			
		||||
      aiService.callAI(systemPrompt, { 
 | 
			
		||||
        maxTokens: 300, 
 | 
			
		||||
        temperature: 0.7 
 | 
			
		||||
      }), taskId);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -107,7 +107,6 @@ class AIPipeline {
 | 
			
		||||
      const aiConfig = aiService.getConfig();
 | 
			
		||||
      const toolsDataHash = getDataVersion?.() || 'unknown';
 | 
			
		||||
      
 | 
			
		||||
      // Record the tools.yaml version being used
 | 
			
		||||
      auditService.addEntry(
 | 
			
		||||
        'initialization',
 | 
			
		||||
        'tools-data-loaded',
 | 
			
		||||
@ -747,7 +746,7 @@ class AIPipeline {
 | 
			
		||||
        prompt,
 | 
			
		||||
        result.content,
 | 
			
		||||
        confidence,
 | 
			
		||||
        `Analysierte ${isWorkflow ? 'Szenario' : 'Problem'} basierend auf Nutzereingabe: "${context.userQuery.slice(0, 100)}..." - Identifizierte Kernaspekte und Herausforderungen für forensische Untersuchung`,
 | 
			
		||||
        `Analysierte ${isWorkflow ? 'Szenario' : 'Problem'} basierend auf Nutzereingabe: "${context.userQuery.slice(0, 100)}..." - Identifizierte Kernaspekte und Herausforderungen für Untersuchung`,
 | 
			
		||||
        taskStart,
 | 
			
		||||
        {
 | 
			
		||||
          toolsDataHash: toolsDataHash,
 | 
			
		||||
@ -1184,21 +1183,18 @@ class AIPipeline {
 | 
			
		||||
    try {
 | 
			
		||||
      const response = await aiService.callMicroTaskAI(contextPrompt);
 | 
			
		||||
      
 | 
			
		||||
      // FIX: Ensure ALL AI calls generate audit entries
 | 
			
		||||
      const toolsDataHash = getDataVersion?.() || 'unknown';
 | 
			
		||||
      const aiConfig = aiService.getConfig();
 | 
			
		||||
      
 | 
			
		||||
      // Calculate response confidence for audit trail
 | 
			
		||||
      const responseConfidence = auditService.calculateAIResponseConfidence(
 | 
			
		||||
        response.content,
 | 
			
		||||
        this.getExpectedLengthForTaskType(taskType),
 | 
			
		||||
        taskType
 | 
			
		||||
      );
 | 
			
		||||
      
 | 
			
		||||
      // FIX: Always add AI decision audit entry for micro-tasks
 | 
			
		||||
      auditService.addAIDecision(
 | 
			
		||||
        this.getPhaseForTaskType(taskType),
 | 
			
		||||
        prompt, // Store original prompt without context
 | 
			
		||||
        prompt,
 | 
			
		||||
        response.content,
 | 
			
		||||
        responseConfidence,
 | 
			
		||||
        this.getReasoningForTaskType(taskType, response.content),
 | 
			
		||||
@ -1224,7 +1220,6 @@ class AIPipeline {
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      // FIX: Also audit failed AI calls for completeness
 | 
			
		||||
      auditService.addEntry(
 | 
			
		||||
        this.getPhaseForTaskType(taskType),
 | 
			
		||||
        'ai-decision-failed',
 | 
			
		||||
@ -1237,7 +1232,7 @@ class AIPipeline {
 | 
			
		||||
          error: error.message,
 | 
			
		||||
          success: false
 | 
			
		||||
        },
 | 
			
		||||
        0, // Zero confidence for failed calls
 | 
			
		||||
        0,
 | 
			
		||||
        startTime,
 | 
			
		||||
        {
 | 
			
		||||
          toolsDataHash: getDataVersion?.() || 'unknown',
 | 
			
		||||
@ -1299,7 +1294,7 @@ class AIPipeline {
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    const taskName = taskNames[taskType] || taskType;
 | 
			
		||||
    return `KI generierte ${taskName} (${responseLength} Zeichen) - forensisch fundierte Analyse mit methodischer Begründung`;
 | 
			
		||||
    return `KI generierte ${taskName} (${responseLength} Zeichen) - Analyse mit methodischer Begründung`;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private addToContextHistory(context: PipelineContext, newEntry: string): void {
 | 
			
		||||
 | 
			
		||||
@ -26,7 +26,6 @@ export interface AuditEntry {
 | 
			
		||||
    completionTokens?: number;
 | 
			
		||||
    toolsDataHash?: string;
 | 
			
		||||
    embeddingsUsed?: boolean;
 | 
			
		||||
    //selectionMethod?: string;
 | 
			
		||||
    microTaskType?: string;
 | 
			
		||||
    confidenceFactors?: string[];
 | 
			
		||||
    reasoning?: string;
 | 
			
		||||
@ -129,15 +128,15 @@ class AuditService {
 | 
			
		||||
    this.addEntry(
 | 
			
		||||
      phase,
 | 
			
		||||
      'ai-decision',
 | 
			
		||||
      { prompt: this.createPromptSummary(aiPrompt) }, // Summary for display only
 | 
			
		||||
      { response: aiResponse }, // STORE FULL RESPONSE - NO TRUNCATION
 | 
			
		||||
      { prompt: this.createPromptSummary(aiPrompt) },
 | 
			
		||||
      { response: aiResponse },
 | 
			
		||||
      confidence,
 | 
			
		||||
      startTime,
 | 
			
		||||
      {
 | 
			
		||||
        ...metadata,
 | 
			
		||||
        reasoning,
 | 
			
		||||
        aiPrompt: aiPrompt, // Full prompt in metadata
 | 
			
		||||
        aiResponse: aiResponse, // Full response in metadata
 | 
			
		||||
        aiPrompt: aiPrompt,
 | 
			
		||||
        aiResponse: aiResponse,
 | 
			
		||||
        decisionBasis: 'ai-analysis'
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
@ -146,7 +145,6 @@ class AuditService {
 | 
			
		||||
  addToolSelection(
 | 
			
		||||
    selectedTools: string[],
 | 
			
		||||
    availableTools: string[],
 | 
			
		||||
    //selectionMethod: string,
 | 
			
		||||
    confidence: number,
 | 
			
		||||
    startTime: number,
 | 
			
		||||
    metadata: Record<string, any> = {}
 | 
			
		||||
@ -154,7 +152,6 @@ class AuditService {
 | 
			
		||||
    const calculatedConfidence = this.calculateSelectionConfidence(
 | 
			
		||||
      selectedTools, 
 | 
			
		||||
      availableTools, 
 | 
			
		||||
      //selectionMethod, 
 | 
			
		||||
      metadata
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@ -169,7 +166,6 @@ class AuditService {
 | 
			
		||||
      { 
 | 
			
		||||
        availableTools: availableTools.slice(0, 10),
 | 
			
		||||
        totalAvailable: availableTools.length,
 | 
			
		||||
        //selectionMethod: selectionMethod
 | 
			
		||||
      },
 | 
			
		||||
      { 
 | 
			
		||||
        selectedTools: selectedTools,
 | 
			
		||||
@ -179,10 +175,8 @@ class AuditService {
 | 
			
		||||
      startTime,
 | 
			
		||||
      {
 | 
			
		||||
        ...metadata,
 | 
			
		||||
        //selectionMethod,
 | 
			
		||||
        availableToolsCount: availableTools.length,
 | 
			
		||||
        selectedToolsCount: selectedTools.length,
 | 
			
		||||
        //decisionBasis: selectionMethod.includes('embeddings') ? 'semantic-search' : 'ai-analysis'
 | 
			
		||||
        decisionBasis
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
@ -288,7 +282,6 @@ class AuditService {
 | 
			
		||||
  private calculateSelectionConfidence(
 | 
			
		||||
    selectedTools: string[], 
 | 
			
		||||
    availableTools: string[], 
 | 
			
		||||
    //selectionMethod: string, 
 | 
			
		||||
    metadata: Record<string, any>
 | 
			
		||||
  ): number {
 | 
			
		||||
    let confidence = 50;
 | 
			
		||||
@ -303,10 +296,6 @@ class AuditService {
 | 
			
		||||
      confidence -= 20;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /*if (selectionMethod.includes('embeddings')) {
 | 
			
		||||
      confidence += 15;
 | 
			
		||||
    }*/
 | 
			
		||||
    
 | 
			
		||||
    if (selectedTools.length >= 5 && selectedTools.length <= 25) {
 | 
			
		||||
      confidence += 10;
 | 
			
		||||
    }
 | 
			
		||||
@ -562,9 +551,9 @@ class AuditService {
 | 
			
		||||
            'background-knowledge': 'Hintergrundwissen-Auswahl',
 | 
			
		||||
            'final-recommendations': 'Abschließende Empfehlungen'
 | 
			
		||||
          };
 | 
			
		||||
          return `KI analysierte ${typeNames[taskType] || taskType} mit ${confidence}% Vertrauen - fundierte forensische Methodikempfehlung`;
 | 
			
		||||
          return `KI analysierte ${typeNames[taskType] || taskType} mit ${confidence}% Vertrauen - fundierte Empfehlung`;
 | 
			
		||||
        }
 | 
			
		||||
        return `KI-Entscheidung mit ${confidence}% Vertrauen basierend auf forensischer Expertenanalyse`;
 | 
			
		||||
        return `KI-Entscheidung mit ${confidence}% Vertrauen basierend auf agentischer Expertenanalyse`;
 | 
			
		||||
      
 | 
			
		||||
      case 'phase-enhancement':
 | 
			
		||||
        const phaseData = input?.phaseName || input?.phaseId;
 | 
			
		||||
@ -593,7 +582,6 @@ class AuditService {
 | 
			
		||||
 | 
			
		||||
  private inferDecisionBasis(metadata: Record<string, any>): string {
 | 
			
		||||
    if (metadata.embeddingsUsed) return 'semantic-search';
 | 
			
		||||
    //if (metadata.embeddingsUsed || metadata.selectionMethod?.includes('embeddings')) return 'semantic-search';
 | 
			
		||||
    if (metadata.aiPrompt || metadata.microTaskType) return 'ai-analysis';
 | 
			
		||||
    if (metadata.semanticQuery && metadata.aiReasoningUsed) return 'hybrid';
 | 
			
		||||
    return 'rule-based';
 | 
			
		||||
 | 
			
		||||
@ -31,7 +31,6 @@ interface EmbeddingsDatabase {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface EmbeddingsConfig {
 | 
			
		||||
  //enabled: boolean;
 | 
			
		||||
  endpoint?: string;
 | 
			
		||||
  apiKey?: string;
 | 
			
		||||
  model?: string;
 | 
			
		||||
@ -49,14 +48,12 @@ class EmbeddingsService {
 | 
			
		||||
  constructor() {
 | 
			
		||||
    this.config = this.loadConfig();
 | 
			
		||||
    console.log('[EMBEDDINGS-SERVICE] Initialized:', {
 | 
			
		||||
      //enabled: this.config.enabled,
 | 
			
		||||
      hasEndpoint: !!this.config.endpoint,
 | 
			
		||||
      hasModel: !!this.config.model
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private loadConfig(): EmbeddingsConfig {
 | 
			
		||||
    //const enabled = process.env.AI_EMBEDDINGS_ENABLED === 'true';
 | 
			
		||||
    const endpoint = process.env.AI_EMBEDDINGS_ENDPOINT;
 | 
			
		||||
    const apiKey = process.env.AI_EMBEDDINGS_API_KEY;
 | 
			
		||||
    const model = process.env.AI_EMBEDDINGS_MODEL;
 | 
			
		||||
@ -64,7 +61,6 @@ class EmbeddingsService {
 | 
			
		||||
    const batchDelay = parseInt(process.env.AI_EMBEDDINGS_BATCH_DELAY_MS || '1000', 10);
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
      //enabled,
 | 
			
		||||
      endpoint,
 | 
			
		||||
      apiKey,
 | 
			
		||||
      model,
 | 
			
		||||
@ -344,21 +340,8 @@ class EmbeddingsService {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /*isEnabled(): boolean {
 | 
			
		||||
    return this.config.enabled;
 | 
			
		||||
  }*/
 | 
			
		||||
 | 
			
		||||
  /*getStats(): { enabled: boolean; initialized: boolean; count: number } {
 | 
			
		||||
    return {
 | 
			
		||||
      enabled: this.config.enabled,
 | 
			
		||||
      initialized: this.isInitialized,
 | 
			
		||||
      count: this.embeddings.length
 | 
			
		||||
    };
 | 
			
		||||
  }*/
 | 
			
		||||
 | 
			
		||||
  getStats(): {initialized: boolean; count: number } {
 | 
			
		||||
    return {
 | 
			
		||||
      //enabled: this.config.enabled,
 | 
			
		||||
      initialized: this.isInitialized,
 | 
			
		||||
      count: this.embeddings.length
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -99,7 +99,6 @@ class ToolSelector {
 | 
			
		||||
    
 | 
			
		||||
    console.log('[TOOL-SELECTOR] Using embeddings for candidate selection');
 | 
			
		||||
    
 | 
			
		||||
    // FIX: Record the start time for audit trail
 | 
			
		||||
    const embeddingsSearchStart = Date.now();
 | 
			
		||||
    
 | 
			
		||||
    const similarItems = await embeddingsService.findSimilar(
 | 
			
		||||
@ -110,13 +109,11 @@ class ToolSelector {
 | 
			
		||||
    
 | 
			
		||||
    console.log('[TOOL-SELECTOR] Embeddings found', similarItems.length, 'similar items');
 | 
			
		||||
    
 | 
			
		||||
    // FIX: Import and use auditService to record this embeddings search
 | 
			
		||||
    const { auditService } = await import('./auditService.js');
 | 
			
		||||
    const { getDataVersion } = await import('./dataService.js');
 | 
			
		||||
    
 | 
			
		||||
    const toolsDataHash = getDataVersion() || 'unknown';
 | 
			
		||||
    
 | 
			
		||||
    // FIX: Add audit entry for initial embeddings search that happens in BOTH modes
 | 
			
		||||
    auditService.addEmbeddingsSearch(
 | 
			
		||||
      userQuery,
 | 
			
		||||
      similarItems,
 | 
			
		||||
@ -197,13 +194,11 @@ class ToolSelector {
 | 
			
		||||
    const softwareWithFullData = candidateSoftware.map(this.createToolData);
 | 
			
		||||
    const conceptsWithFullData = candidateConcepts.map(this.createConceptData);
 | 
			
		||||
 | 
			
		||||
    // Unified selection limits (method-agnostic)
 | 
			
		||||
    const maxTools = Math.min(this.config.embeddingSelectionLimit, this.config.noEmbeddingsToolLimit);
 | 
			
		||||
    const maxConcepts = Math.min(this.config.embeddingConceptsLimit, this.config.noEmbeddingsConceptLimit);
 | 
			
		||||
    const methodLimit = Math.ceil(maxTools * this.config.methodSelectionRatio);
 | 
			
		||||
    const softwareLimit = Math.floor(maxTools * this.config.softwareSelectionRatio);
 | 
			
		||||
 | 
			
		||||
    // Build tool list to send
 | 
			
		||||
    const toolsToSend: any[] = [
 | 
			
		||||
      ...methodsWithFullData.slice(0, methodLimit),
 | 
			
		||||
      ...softwareWithFullData.slice(0, softwareLimit),
 | 
			
		||||
@ -211,7 +206,6 @@ class ToolSelector {
 | 
			
		||||
 | 
			
		||||
    const remainingCapacity = maxTools - toolsToSend.length;
 | 
			
		||||
    if (remainingCapacity > 0) {
 | 
			
		||||
      // Fill remainder from whichever bucket still has items
 | 
			
		||||
      const extraMethods = methodsWithFullData.slice(methodLimit, methodLimit + remainingCapacity);
 | 
			
		||||
      const extraSoftware = softwareWithFullData.slice(softwareLimit, softwareLimit + (remainingCapacity - extraMethods.length));
 | 
			
		||||
      toolsToSend.push(...extraMethods, ...extraSoftware);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user