improvements
This commit is contained in:
		
							parent
							
								
									8c9bdf0710
								
							
						
					
					
						commit
						1b9d9b437b
					
				
							
								
								
									
										78
									
								
								.env.example
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								.env.example
									
									
									
									
									
								
							@ -13,68 +13,60 @@ OIDC_ENDPOINT=https://your-oidc-provider.com
 | 
			
		||||
OIDC_CLIENT_ID=your-client-id
 | 
			
		||||
OIDC_CLIENT_SECRET=your-client-secret
 | 
			
		||||
 | 
			
		||||
# === AI Configuration ===
 | 
			
		||||
# ===================================================================
 | 
			
		||||
# AI CONFIGURATION - Complete Reference for Improved Pipeline
 | 
			
		||||
# ===================================================================
 | 
			
		||||
 | 
			
		||||
# Selector AI (for selection stage, choode a good model) 
 | 
			
		||||
AI_SELECTOR_ENDPOINT=https://llm.mikoshi.de
 | 
			
		||||
AI_SELECTOR_API_KEY=sk-DzREDACTEDHA
 | 
			
		||||
AI_SELECTOR_MODEL=mistral/mistral-medium-latest
 | 
			
		||||
# === CORE AI ENDPOINTS & MODELS ===
 | 
			
		||||
AI_API_ENDPOINT=https://llm.mikoshi.de
 | 
			
		||||
AI_API_KEY=sREDACTED3w
 | 
			
		||||
AI_MODEL='mistral/mistral-small-latest'
 | 
			
		||||
 | 
			
		||||
# Analyzer AI (for analysis stage, choose a smaller model)
 | 
			
		||||
# === IMPROVED PIPELINE: Use separate analyzer model (mistral-small is fine) ===
 | 
			
		||||
AI_ANALYZER_ENDPOINT=https://llm.mikoshi.de
 | 
			
		||||
AI_ANALYZER_API_KEY=sk-DzREDACTEDnHA
 | 
			
		||||
AI_ANALYZER_MODEL=mistral/mistral-small-latest
 | 
			
		||||
AI_ANALYZER_API_KEY=skREDACTEDw3w  
 | 
			
		||||
AI_ANALYZER_MODEL='mistral/mistral-small-latest'
 | 
			
		||||
 | 
			
		||||
# === Embeddings Configuration ===
 | 
			
		||||
# Enable/disable semantic embeddings pre-selection
 | 
			
		||||
# === EMBEDDINGS CONFIGURATION ===
 | 
			
		||||
AI_EMBEDDINGS_ENABLED=true
 | 
			
		||||
 | 
			
		||||
# Embeddings API (Mistral recommended)
 | 
			
		||||
AI_EMBEDDINGS_ENDPOINT=https://api.mistral.ai/v1/embeddings
 | 
			
		||||
AI_EMBEDDINGS_API_KEY=ZSpREDACTED3wL
 | 
			
		||||
AI_EMBEDDINGS_API_KEY=ZREDACTED3wL
 | 
			
		||||
AI_EMBEDDINGS_MODEL=mistral-embed
 | 
			
		||||
 | 
			
		||||
# Embeddings performance settings
 | 
			
		||||
AI_EMBEDDINGS_BATCH_SIZE=20
 | 
			
		||||
AI_EMBEDDINGS_BATCH_DELAY_MS=1000
 | 
			
		||||
AI_EMBEDDING_CANDIDATES=30
 | 
			
		||||
AI_SIMILARITY_THRESHOLD=0.3
 | 
			
		||||
 | 
			
		||||
# Delay between micro-tasks to respect rate limits (milliseconds)
 | 
			
		||||
AI_MICRO_TASK_DELAY_MS=500
 | 
			
		||||
# === PIPELINE: VectorIndex (HNSW) Configuration ===
 | 
			
		||||
AI_MAX_SELECTED_ITEMS=60                    # Tools visible to each micro-task 
 | 
			
		||||
AI_EMBEDDING_CANDIDATES=60                  # VectorIndex candidates (HNSW is more efficient)
 | 
			
		||||
AI_SIMILARITY_THRESHOLD=0.3                # Not used by VectorIndex (uses cosine distance internally)
 | 
			
		||||
 | 
			
		||||
# Micro-task specific rate limiting (requests per minute per user)
 | 
			
		||||
AI_MICRO_TASK_RATE_LIMIT=30
 | 
			
		||||
# === MICRO-TASK CONFIGURATION ===
 | 
			
		||||
AI_MICRO_TASK_DELAY_MS=500                 # Delay between micro-tasks  
 | 
			
		||||
AI_MICRO_TASK_TIMEOUT_MS=25000             # Timeout per micro-task (increased for full context)
 | 
			
		||||
 | 
			
		||||
# Maximum parallel micro-tasks (for future parallel processing)
 | 
			
		||||
AI_MAX_PARALLEL_TASKS=3
 | 
			
		||||
# === RATE LIMITING ===
 | 
			
		||||
AI_RATE_LIMIT_DELAY_MS=3000                # Main rate limit delay
 | 
			
		||||
AI_RATE_LIMIT_MAX_REQUESTS=6               # Main requests per minute (reduced - fewer but richer calls)
 | 
			
		||||
AI_MICRO_TASK_RATE_LIMIT=15                # Micro-task requests per minute (was 30)
 | 
			
		||||
 | 
			
		||||
# Micro-task timeout settings (milliseconds)
 | 
			
		||||
AI_MICRO_TASK_TIMEOUT_MS=15000
 | 
			
		||||
 | 
			
		||||
# ENHANCED: Rate Limiting Configuration
 | 
			
		||||
# Main query rate limiting (reduced due to micro-tasks)
 | 
			
		||||
AI_RATE_LIMIT_DELAY_MS=3000
 | 
			
		||||
AI_RATE_LIMIT_MAX_REQUESTS=8
 | 
			
		||||
 | 
			
		||||
# Smart prompting rate limiting 
 | 
			
		||||
AI_SMART_PROMPTING_RATE_LIMIT=5
 | 
			
		||||
AI_SMART_PROMPTING_WINDOW_MS=60000
 | 
			
		||||
 | 
			
		||||
# Queue management settings
 | 
			
		||||
# === QUEUE MANAGEMENT ===
 | 
			
		||||
AI_QUEUE_MAX_SIZE=50
 | 
			
		||||
AI_QUEUE_CLEANUP_INTERVAL_MS=300000
 | 
			
		||||
 | 
			
		||||
# === Performance & Monitoring ===
 | 
			
		||||
# Enable detailed micro-task logging
 | 
			
		||||
AI_MICRO_TASK_DEBUG=false
 | 
			
		||||
 | 
			
		||||
# Enable performance metrics collection
 | 
			
		||||
# === PERFORMANCE & MONITORING ===
 | 
			
		||||
AI_MICRO_TASK_DEBUG=true
 | 
			
		||||
AI_PERFORMANCE_METRICS=true
 | 
			
		||||
 | 
			
		||||
# Cache settings for AI responses
 | 
			
		||||
AI_RESPONSE_CACHE_TTL_MS=3600000
 | 
			
		||||
 | 
			
		||||
# ===================================================================
 | 
			
		||||
# LEGACY VARIABLES (still used but less important)
 | 
			
		||||
# ===================================================================
 | 
			
		||||
 | 
			
		||||
# These are still used by other parts of the system:
 | 
			
		||||
AI_RESPONSE_CACHE_TTL_MS=3600000           # For caching responses
 | 
			
		||||
AI_QUEUE_MAX_SIZE=50                       # Queue management
 | 
			
		||||
AI_QUEUE_CLEANUP_INTERVAL_MS=300000       # Queue cleanup
 | 
			
		||||
 | 
			
		||||
# === Application Configuration ===
 | 
			
		||||
PUBLIC_BASE_URL=http://localhost:4321
 | 
			
		||||
NODE_ENV=development
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
// src/utils/aiPipeline.ts
 | 
			
		||||
// src/utils/aiPipeline.ts - FIXED: Restore proper structure with context continuity
 | 
			
		||||
 | 
			
		||||
import { getCompressedToolsDataForAI } from './dataService.js';
 | 
			
		||||
import { embeddingsService, type EmbeddingData } from './embeddings.js';
 | 
			
		||||
import { vectorIndex } from "./vectorIndex.js";
 | 
			
		||||
import { vectorIndex } from './vectorIndex.js';
 | 
			
		||||
 | 
			
		||||
interface AIConfig {
 | 
			
		||||
  endpoint: string;
 | 
			
		||||
@ -31,15 +31,15 @@ interface AnalysisResult {
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Context object that builds up through pipeline
 | 
			
		||||
// FIXED: Context object that builds up through pipeline
 | 
			
		||||
interface AnalysisContext {
 | 
			
		||||
  userQuery: string;
 | 
			
		||||
  mode: string;
 | 
			
		||||
  filteredData: any;
 | 
			
		||||
  // Context continuity 
 | 
			
		||||
  // ADDED: Context continuity 
 | 
			
		||||
  contextHistory: string[];
 | 
			
		||||
  
 | 
			
		||||
  // Results
 | 
			
		||||
  // Results (same as original)
 | 
			
		||||
  scenarioAnalysis?: string;
 | 
			
		||||
  problemAnalysis?: string;
 | 
			
		||||
  investigationApproach?: string;
 | 
			
		||||
@ -48,9 +48,6 @@ interface AnalysisContext {
 | 
			
		||||
  backgroundKnowledge?: Array<{concept: any, relevance: string}>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Improved DFIR micro‑task pipeline – 2025‑08‑01 revision (bug‑fixed)
 | 
			
		||||
 */
 | 
			
		||||
class ImprovedMicroTaskAIPipeline {
 | 
			
		||||
  private config: AIConfig;
 | 
			
		||||
  private maxSelectedItems: number;
 | 
			
		||||
@ -65,46 +62,59 @@ class ImprovedMicroTaskAIPipeline {
 | 
			
		||||
      model: this.getEnv('AI_ANALYZER_MODEL')
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Candidate selection tuned for higher precision
 | 
			
		||||
    // FIXED: Optimized for vectorIndex (HNSW) usage
 | 
			
		||||
    this.maxSelectedItems = parseInt(process.env.AI_MAX_SELECTED_ITEMS || '60', 10);
 | 
			
		||||
    this.embeddingCandidates = parseInt(process.env.AI_EMBEDDING_CANDIDATES || '40', 10);
 | 
			
		||||
    this.similarityThreshold = parseFloat(process.env.AI_SIMILARITY_THRESHOLD || '0.5');
 | 
			
		||||
    this.embeddingCandidates = parseInt(process.env.AI_EMBEDDING_CANDIDATES || '60', 10); // HNSW is more efficient
 | 
			
		||||
    this.similarityThreshold = 0.3; // Not used by vectorIndex, kept for fallback compatibility
 | 
			
		||||
    this.microTaskDelay = parseInt(process.env.AI_MICRO_TASK_DELAY_MS || '500', 10);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getEnv(key: string): string {
 | 
			
		||||
    const value = process.env[key];
 | 
			
		||||
    if (!value) throw new Error(`Missing environment variable: ${key}`);
 | 
			
		||||
    if (!value) {
 | 
			
		||||
      throw new Error(`Missing environment variable: ${key}`);
 | 
			
		||||
    }
 | 
			
		||||
    return value;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Embedding → LLM blended selector */
 | 
			
		||||
  // IMPROVED: AI-driven selection (no hard-coded keywords)
 | 
			
		||||
  private async getIntelligentCandidates(userQuery: string, toolsData: any, mode: string) {
 | 
			
		||||
    const candidateTools = new Set<string>();
 | 
			
		||||
    const candidateConcepts = new Set<string>();
 | 
			
		||||
    let candidateTools = new Set<string>();
 | 
			
		||||
    let candidateConcepts = new Set<string>();
 | 
			
		||||
    
 | 
			
		||||
    // Method 1: Embeddings-based selection (primary)
 | 
			
		||||
    if (embeddingsService.isEnabled()) {
 | 
			
		||||
      const similarItems = await vectorIndex.findSimilar(userQuery, this.embeddingCandidates);
 | 
			
		||||
      const similarItems = await embeddingsService.findSimilar(
 | 
			
		||||
        userQuery, 
 | 
			
		||||
        this.embeddingCandidates, 
 | 
			
		||||
        this.similarityThreshold
 | 
			
		||||
      );
 | 
			
		||||
      
 | 
			
		||||
      similarItems.forEach(item => {
 | 
			
		||||
        if (item.type === 'tool') candidateTools.add(item.name);
 | 
			
		||||
        if (item.type === 'concept') candidateConcepts.add(item.name);
 | 
			
		||||
      });
 | 
			
		||||
      
 | 
			
		||||
      console.log(`[PIPELINE] Embedding hits → ${candidateTools.size} tools / ${candidateConcepts.size} concepts`);
 | 
			
		||||
      console.log(`[IMPROVED PIPELINE] Embeddings selected: ${candidateTools.size} tools, ${candidateConcepts.size} concepts`);
 | 
			
		||||
      
 | 
			
		||||
      if (candidateTools.size >= 20) {
 | 
			
		||||
        return {
 | 
			
		||||
          tools: toolsData.tools.filter((tool: any) => candidateTools.has(tool.name)),
 | 
			
		||||
          concepts: toolsData.concepts.filter((concept: any) => candidateConcepts.has(concept.name)),
 | 
			
		||||
          domains: toolsData.domains,
 | 
			
		||||
          phases: toolsData.phases,
 | 
			
		||||
          'domain-agnostic-software': toolsData['domain-agnostic-software']
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const reducedData = {
 | 
			
		||||
      ...toolsData,
 | 
			
		||||
      tools: candidateTools.size ? toolsData.tools.filter((t: any) => candidateTools.has(t.name)) : toolsData.tools,
 | 
			
		||||
      concepts: candidateConcepts.size ? toolsData.concepts.filter((c: any) => candidateConcepts.has(c.name)) : toolsData.concepts
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return this.aiSelection(userQuery, reducedData, mode);
 | 
			
		||||
    // Method 2: Fallback AI selection (like original selector)
 | 
			
		||||
    console.log(`[IMPROVED PIPELINE] Using AI selector fallback`);
 | 
			
		||||
    return await this.fallbackAISelection(userQuery, toolsData, mode);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Language‑model based selector (no 50‑item cap) */
 | 
			
		||||
  private async aiSelection(userQuery: string, toolsData: any, mode: string) {
 | 
			
		||||
  // Fallback AI selection
 | 
			
		||||
  private async fallbackAISelection(userQuery: string, toolsData: any, mode: string) {
 | 
			
		||||
    const toolsList = toolsData.tools.map((tool: any) => ({
 | 
			
		||||
      name: tool.name,
 | 
			
		||||
      type: tool.type,
 | 
			
		||||
@ -124,17 +134,16 @@ class ImprovedMicroTaskAIPipeline {
 | 
			
		||||
      tags: concept.tags?.slice(0, 5) || []
 | 
			
		||||
    }));
 | 
			
		||||
 | 
			
		||||
    const modeInstruction =
 | 
			
		||||
      mode === 'workflow'
 | 
			
		||||
        ? 'The user wants a COMPREHENSIVE WORKFLOW with multiple tools/methods across different phases.'
 | 
			
		||||
        : 'The user wants SPECIFIC TOOLS/METHODS that directly solve their particular problem.';
 | 
			
		||||
    const modeInstruction = mode === 'workflow' 
 | 
			
		||||
      ? 'The user wants a COMPREHENSIVE WORKFLOW with multiple tools/methods across different phases.'
 | 
			
		||||
      : 'The user wants SPECIFIC TOOLS/METHODS that directly solve their particular problem.';
 | 
			
		||||
 | 
			
		||||
    const prompt = `You are a DFIR expert tasked with selecting the most relevant tools and concepts for a user query.
 | 
			
		||||
 | 
			
		||||
${modeInstruction}
 | 
			
		||||
 | 
			
		||||
AVAILABLE TOOLS:
 | 
			
		||||
${JSON.stringify(toolsList, null, 2)}
 | 
			
		||||
${JSON.stringify(toolsList.slice(0, 50), null, 2)}
 | 
			
		||||
 | 
			
		||||
AVAILABLE CONCEPTS:
 | 
			
		||||
${JSON.stringify(conceptsList, null, 2)}
 | 
			
		||||
@ -161,12 +170,13 @@ Respond with ONLY this JSON format:
 | 
			
		||||
 | 
			
		||||
      const totalSelected = result.selectedTools.length + result.selectedConcepts.length;
 | 
			
		||||
      if (totalSelected > this.maxSelectedItems) {
 | 
			
		||||
        console.warn(`[PIPELINE] Selection exceeded limit (${totalSelected}), truncating`);
 | 
			
		||||
        console.warn(`[IMPROVED PIPELINE] Selection exceeded limit (${totalSelected}), truncating`);
 | 
			
		||||
        result.selectedTools = result.selectedTools.slice(0, Math.floor(this.maxSelectedItems * 0.8));
 | 
			
		||||
        result.selectedConcepts = result.selectedConcepts.slice(0, Math.ceil(this.maxSelectedItems * 0.2));
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      console.log(`[PIPELINE] LLM selector → ${result.selectedTools.length} tools / ${result.selectedConcepts.length} concepts`);
 | 
			
		||||
      console.log(`[IMPROVED PIPELINE] AI selector: ${result.selectedTools.length} tools, ${result.selectedConcepts.length} concepts`);
 | 
			
		||||
      console.log(`[IMPROVED PIPELINE] AI reasoning: ${result.reasoning}`);
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        tools: toolsData.tools.filter((tool: any) => result.selectedTools.includes(tool.name)),
 | 
			
		||||
@ -175,25 +185,43 @@ Respond with ONLY this JSON format:
 | 
			
		||||
        phases: toolsData.phases,
 | 
			
		||||
        'domain-agnostic-software': toolsData['domain-agnostic-software']
 | 
			
		||||
      };
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      console.error('[PIPELINE] Failed to parse selector response');
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      console.error('[IMPROVED PIPELINE] Failed to parse selector response');
 | 
			
		||||
      throw new Error('Invalid JSON response from selector AI');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private delay(ms: number) { return new Promise(res => setTimeout(res, ms)); }
 | 
			
		||||
  private async delay(ms: number): Promise<void> {
 | 
			
		||||
    return new Promise(resolve => setTimeout(resolve, ms));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private async callMicroTaskAI(prompt: string, context: AnalysisContext, maxTokens = 300): Promise<MicroTaskResult> {
 | 
			
		||||
    const start = Date.now();
 | 
			
		||||
    const contextPrompt = context.contextHistory.length
 | 
			
		||||
      ? `BISHERIGE ANALYSE:\n${context.contextHistory.join('\n\n')}\n\nAKTUELLE AUFGABE:\n${prompt}`
 | 
			
		||||
      : prompt;
 | 
			
		||||
  // IMPROVED: Enhanced micro-task with context history
 | 
			
		||||
  private async callMicroTaskAI(prompt: string, context: AnalysisContext, maxTokens: number = 300): Promise<MicroTaskResult> {
 | 
			
		||||
    const startTime = Date.now();
 | 
			
		||||
    
 | 
			
		||||
    // ADDED: Include context history for continuity
 | 
			
		||||
    const contextPrompt = context.contextHistory.length > 0 ? 
 | 
			
		||||
      `BISHERIGE ANALYSE:\n${context.contextHistory.join('\n\n')}\n\nAKTUELLE AUFGABE:\n${prompt}` : 
 | 
			
		||||
      prompt;
 | 
			
		||||
    
 | 
			
		||||
    try {
 | 
			
		||||
      const response = await this.callAI(contextPrompt, maxTokens);
 | 
			
		||||
      return { taskType: 'micro-task', content: response.trim(), processingTimeMs: Date.now() - start, success: true };
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      return { taskType: 'micro-task', content: '', processingTimeMs: Date.now() - start, success: false, error: (e as Error).message };
 | 
			
		||||
      
 | 
			
		||||
      return {
 | 
			
		||||
        taskType: 'micro-task',
 | 
			
		||||
        content: response.trim(),
 | 
			
		||||
        processingTimeMs: Date.now() - startTime,
 | 
			
		||||
        success: true
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      return {
 | 
			
		||||
        taskType: 'micro-task',
 | 
			
		||||
        content: '',
 | 
			
		||||
        processingTimeMs: Date.now() - startTime,
 | 
			
		||||
        success: false,
 | 
			
		||||
        error: error.message
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -210,8 +238,13 @@ ${isWorkflow ? 'FORENSISCHES SZENARIO' : 'TECHNISCHES PROBLEM'}: "${context.user
 | 
			
		||||
Führen Sie eine systematische ${isWorkflow ? 'Szenario-Analyse' : 'Problem-Analyse'} durch und berücksichtigen Sie dabei:
 | 
			
		||||
 | 
			
		||||
${isWorkflow ? 
 | 
			
		||||
  `- Auf das Szenario bezogene Problemstellungen` :
 | 
			
		||||
  `- konkrete problembezogene Aufgabenstellung`
 | 
			
		||||
  `- Angriffsvektoren und Bedrohungsmodellierung nach MITRE ATT&CK
 | 
			
		||||
- Betroffene Systeme und kritische Infrastrukturen
 | 
			
		||||
- Zeitkritische Faktoren und Beweiserhaltung
 | 
			
		||||
- Forensische Artefakte und Datenquellen` :
 | 
			
		||||
  `- Spezifische forensische Herausforderungen
 | 
			
		||||
- Verfügbare Datenquellen und deren Integrität
 | 
			
		||||
- Methodische Anforderungen für rechtssichere Analyse`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen, Aufzählungen oder Markdown-Formatierung. Maximum 150 Wörter.`;
 | 
			
		||||
@ -237,16 +270,19 @@ WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen, Aufzählun
 | 
			
		||||
    const isWorkflow = context.mode === 'workflow';
 | 
			
		||||
    const analysis = isWorkflow ? context.scenarioAnalysis : context.problemAnalysis;
 | 
			
		||||
    
 | 
			
		||||
    const prompt = `Basierend auf der Analyse entwickeln Sie einen fundierten ${isWorkflow ? 'Untersuchungsansatz' : 'Lösungsansatz'}.
 | 
			
		||||
    const prompt = `Basierend auf der Analyse entwickeln Sie einen fundierten ${isWorkflow ? 'Untersuchungsansatz' : 'Lösungsansatz'} nach NIST SP 800-86 Methodik.
 | 
			
		||||
 | 
			
		||||
${isWorkflow ? 'SZENARIO' : 'PROBLEM'}: "${context.userQuery}"
 | 
			
		||||
 | 
			
		||||
Entwickeln Sie einen systematischen ${isWorkflow ? 'Untersuchungsansatz' : 'Lösungsansatz'} unter Berücksichtigung von:
 | 
			
		||||
 | 
			
		||||
${isWorkflow ?
 | 
			
		||||
  `- Triage-Prioritäten nach forensischer Dringlichkeit (wenn zutreffend)
 | 
			
		||||
- Phasenabfolge nach NIST SP 800-86-Methodik (Datensammlung - Auswertung - Analyse - Report)` :
 | 
			
		||||
  `- pragmatischer, zielorientierter Lösungsansatz im benehmen mit Anforderungen an die Reproduzierbarkeit`
 | 
			
		||||
  `- Triage-Prioritäten nach forensischer Dringlichkeit
 | 
			
		||||
- Phasenabfolge nach NIST-Methodik
 | 
			
		||||
- Kontaminationsvermeidung und forensische Isolierung` :
 | 
			
		||||
  `- Methodik-Auswahl nach wissenschaftlichen Kriterien
 | 
			
		||||
- Validierung und Verifizierung der gewählten Ansätze
 | 
			
		||||
- Integration in bestehende forensische Workflows`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen oder Markdown. Maximum 150 Wörter.`;
 | 
			
		||||
@ -269,11 +305,17 @@ WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen oder Markdo
 | 
			
		||||
 | 
			
		||||
${isWorkflow ? 'SZENARIO' : 'PROBLEM'}: "${context.userQuery}"
 | 
			
		||||
 | 
			
		||||
Berücksichtigen Sie folgende Aspekte:
 | 
			
		||||
Berücksichtigen Sie folgende forensische Aspekte:
 | 
			
		||||
 | 
			
		||||
${isWorkflow ?
 | 
			
		||||
  `- Szenariobezogene typische Problemstellungen, die auftreten können` :
 | 
			
		||||
  `- Problembezogene Schwierigkeiten, die das Ergebnis negativ beeinträchtigen könnten`
 | 
			
		||||
  `- Time-sensitive evidence preservation
 | 
			
		||||
- Chain of custody requirements und rechtliche Verwertbarkeit
 | 
			
		||||
- Incident containment vs. evidence preservation Dilemma
 | 
			
		||||
- Privacy- und Compliance-Anforderungen` :
 | 
			
		||||
  `- Tool-Validierung und Nachvollziehbarkeit
 | 
			
		||||
- False positive/negative Risiken bei der gewählten Methodik
 | 
			
		||||
- Qualifikationsanforderungen für die Durchführung
 | 
			
		||||
- Dokumentations- und Reporting-Standards`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen oder Markdown. Maximum 120 Wörter.`;
 | 
			
		||||
@ -311,9 +353,10 @@ VERFÜGBARE TOOLS FÜR ${phase.name.toUpperCase()}:
 | 
			
		||||
${phaseTools.map((tool: any) => `- ${tool.name}: ${tool.description.slice(0, 100)}...`).join('\n')}
 | 
			
		||||
 | 
			
		||||
Wählen Sie Methoden/Tools nach forensischen Kriterien aus:
 | 
			
		||||
- Eignung für die spezifische Lösung des Problems
 | 
			
		||||
- besondere Fähigkeiten der Methode/des Tools, das sie von anderen abgrenzt
 | 
			
		||||
- Reproduzierbarkeit und Objektivität
 | 
			
		||||
- Court admissibility und Chain of Custody Kompatibilität  
 | 
			
		||||
- Integration in forensische Standard-Workflows
 | 
			
		||||
- Reproduzierbarkeit und Dokumentationsqualität
 | 
			
		||||
- Objektivität
 | 
			
		||||
 | 
			
		||||
Antworten Sie AUSSCHLIESSLICH mit diesem JSON-Format (kein zusätzlicher Text):
 | 
			
		||||
[
 | 
			
		||||
@ -363,7 +406,7 @@ Antworten Sie AUSSCHLIESSLICH mit diesem JSON-Format (kein zusätzlicher Text):
 | 
			
		||||
 | 
			
		||||
  // MICRO-TASK 5: Tool Evaluation (Tool mode)
 | 
			
		||||
  private async evaluateSpecificTool(context: AnalysisContext, tool: any, rank: number): Promise<MicroTaskResult> {
 | 
			
		||||
    const prompt = `Bewerten Sie diese Methode/Tool fallbezogen für das spezifische Problem.
 | 
			
		||||
    const prompt = `Bewerten Sie diese Methode/Tool fallbezogen für das spezifische Problem nach forensischen Qualitätskriterien.
 | 
			
		||||
 | 
			
		||||
PROBLEM: "${context.userQuery}"
 | 
			
		||||
 | 
			
		||||
@ -437,13 +480,13 @@ EMPFOHLENE TOOLS: ${selectedToolNames.join(', ')}
 | 
			
		||||
VERFÜGBARE KONZEPTE:
 | 
			
		||||
${availableConcepts.slice(0, 15).map((concept: any) => `- ${concept.name}: ${concept.description.slice(0, 80)}...`).join('\n')}
 | 
			
		||||
 | 
			
		||||
Wählen Sie 2-4 Konzepte aus, die für die Lösung des Problems essentiell sind.
 | 
			
		||||
Wählen Sie 2-4 Konzepte aus, die für das Verständnis der forensischen Methodik essentiell sind.
 | 
			
		||||
 | 
			
		||||
Antworten Sie AUSSCHLIESSLICH mit diesem JSON-Format:
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "conceptName": "Exakter Konzept-Name",
 | 
			
		||||
    "relevance": "Forensische Relevanz: Warum dieses Konzept für die Lösung des Problems kritisch ist"
 | 
			
		||||
    "relevance": "Forensische Relevanz: Warum dieses Konzept für das Verständnis der Methodik kritisch ist"
 | 
			
		||||
  }
 | 
			
		||||
]`;
 | 
			
		||||
 | 
			
		||||
@ -478,21 +521,21 @@ Antworten Sie AUSSCHLIESSLICH mit diesem JSON-Format:
 | 
			
		||||
    const isWorkflow = context.mode === 'workflow';
 | 
			
		||||
    
 | 
			
		||||
    const prompt = isWorkflow ? 
 | 
			
		||||
      `Erstellen Sie eine forensisch fundierte Workflow-Empfehlung unter Anwendung der gewählten Methoden/Tools.
 | 
			
		||||
      `Erstellen Sie eine forensisch fundierte Workflow-Empfehlung basierend auf DFIR-Prinzipien.
 | 
			
		||||
 | 
			
		||||
SZENARIO: "${context.userQuery}"
 | 
			
		||||
AUSGEWÄHLTE TOOLS: ${context.selectedTools?.map(st => st.tool.name).join(', ') || 'Keine Tools ausgewählt'}
 | 
			
		||||
 | 
			
		||||
Erstellen Sie konkrete Workflow-Schritte für dieses spezifische Szenario unter Berücksichtigung von Objektivität und rechtlicher Verwertbarkeit (Reproduzierbarkeit, Transparenz).
 | 
			
		||||
Erstellen Sie konkrete methodische Workflow-Schritte für dieses spezifische Szenario unter Berücksichtigung forensischer Best Practices, Objektivität und rechtlicher Verwertbarkeit.
 | 
			
		||||
 | 
			
		||||
WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen oder Markdown. Maximum 120 Wörter.` :
 | 
			
		||||
      
 | 
			
		||||
      `Erstellen Sie wichtige Überlegungen für die korrekte Methoden-/Tool-Anwendung.
 | 
			
		||||
      `Erstellen Sie wichtige methodische Überlegungen für die korrekte Methoden-/Tool-Anwendung.
 | 
			
		||||
 | 
			
		||||
PROBLEM: "${context.userQuery}"
 | 
			
		||||
EMPFOHLENE TOOLS: ${context.selectedTools?.map(st => st.tool.name).join(', ') || 'Keine Methoden/Tools ausgewählt'}
 | 
			
		||||
 | 
			
		||||
Geben Sie kritische Überlegungen für die korrekte Anwendung der empfohlenen Methoden/Tools.
 | 
			
		||||
Geben Sie kritische methodische Überlegungen, Validierungsanforderungen und Qualitätssicherungsmaßnahmen für die korrekte Anwendung der empfohlenen Methoden/Tools.
 | 
			
		||||
 | 
			
		||||
WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen oder Markdown. Maximum 100 Wörter.`;
 | 
			
		||||
 | 
			
		||||
@ -531,16 +574,26 @@ WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen oder Markdo
 | 
			
		||||
    return content;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // MAIN PROCESSING: Restored original structure with context continuity
 | 
			
		||||
  async processQuery(userQuery: string, mode: string): Promise<AnalysisResult> {
 | 
			
		||||
    const startTime = Date.now();
 | 
			
		||||
    let completedTasks = 0;
 | 
			
		||||
    let failedTasks = 0;
 | 
			
		||||
    
 | 
			
		||||
    console.log(`[IMPROVED PIPELINE] Starting ${mode} query processing with context continuity`);
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      // Stage 1: Get intelligent candidates (embeddings + AI selection)
 | 
			
		||||
      const toolsData = await getCompressedToolsDataForAI();
 | 
			
		||||
      const filteredData = await this.getIntelligentCandidates(userQuery, toolsData, mode);
 | 
			
		||||
      
 | 
			
		||||
      const context: AnalysisContext = { userQuery, mode, filteredData, contextHistory: [] };
 | 
			
		||||
      // Initialize context with continuity
 | 
			
		||||
      const context: AnalysisContext = {
 | 
			
		||||
        userQuery,
 | 
			
		||||
        mode,
 | 
			
		||||
        filteredData,
 | 
			
		||||
        contextHistory: [] // ADDED: Context continuity
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      console.log(`[IMPROVED PIPELINE] Starting micro-tasks with ${filteredData.tools.length} tools visible`);
 | 
			
		||||
 | 
			
		||||
@ -571,8 +624,8 @@ WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen oder Markdo
 | 
			
		||||
          await this.delay(this.microTaskDelay);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        const shuffled = [...filteredData.tools].sort(() => Math.random() - 0.5); // FIX
 | 
			
		||||
        const topTools = shuffled.slice(0, 3);
 | 
			
		||||
        // Evaluate top 3 tools for specific problem
 | 
			
		||||
        const topTools = filteredData.tools.slice(0, 3);
 | 
			
		||||
        for (let i = 0; i < topTools.length; i++) {
 | 
			
		||||
          const evaluationResult = await this.evaluateSpecificTool(context, topTools[i], i + 1);
 | 
			
		||||
          if (evaluationResult.success) completedTasks++; else failedTasks++;
 | 
			
		||||
@ -589,21 +642,31 @@ WICHTIG: Antworten Sie NUR in fließendem deutschen Text ohne Listen oder Markdo
 | 
			
		||||
      const finalResult = await this.generateFinalRecommendations(context);
 | 
			
		||||
      if (finalResult.success) completedTasks++; else failedTasks++;
 | 
			
		||||
 | 
			
		||||
      const recommendation = this.buildRecommendation(context, mode, ''); // finalContent injected inside omitted logic
 | 
			
		||||
      // Build final recommendation (same as original)
 | 
			
		||||
      const recommendation = this.buildRecommendation(context, mode, finalResult.content);
 | 
			
		||||
 | 
			
		||||
      const processingStats = {
 | 
			
		||||
        embeddingsUsed: embeddingsService.isEnabled(),
 | 
			
		||||
        vectorIndexUsed: embeddingsService.isEnabled(), // VectorIndex is used when embeddings are enabled
 | 
			
		||||
        candidatesFromEmbeddings: filteredData.tools.length,
 | 
			
		||||
        finalSelectedItems: (context.selectedTools?.length || 0) + (context.backgroundKnowledge?.length || 0),
 | 
			
		||||
        finalSelectedItems: (context.selectedTools?.length || 0) + 
 | 
			
		||||
                           (context.backgroundKnowledge?.length || 0),
 | 
			
		||||
        processingTimeMs: Date.now() - startTime,
 | 
			
		||||
        microTasksCompleted: completedTasks,
 | 
			
		||||
        microTasksFailed: failedTasks,
 | 
			
		||||
        contextContinuityUsed: true
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      return { recommendation, processingStats };
 | 
			
		||||
      console.log(`[IMPROVED PIPELINE] Completed: ${completedTasks} tasks, Failed: ${failedTasks} tasks`);
 | 
			
		||||
      console.log(`[IMPROVED PIPELINE] VectorIndex used: ${embeddingsService.isEnabled()}, Candidates: ${filteredData.tools.length}`);
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        recommendation,
 | 
			
		||||
        processingStats
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      console.error('[PIPELINE] Processing failed:', error);
 | 
			
		||||
      console.error('[IMPROVED PIPELINE] Processing failed:', error);
 | 
			
		||||
      throw error;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user