From d043bba17fc83d386e6c09fd6f2d7b3e4f125f31 Mon Sep 17 00:00:00 2001 From: overcuriousity Date: Mon, 11 Aug 2025 08:57:16 +0200 Subject: [PATCH] phase completion justification --- src/config/prompts.ts | 63 ++++++++++++++++++++++++-------- src/utils/aiPipeline.ts | 80 ++++++++++++++++++++++++++++++++++------- 2 files changed, 115 insertions(+), 28 deletions(-) diff --git a/src/config/prompts.ts b/src/config/prompts.ts index 14af010..8802cd1 100644 --- a/src/config/prompts.ts +++ b/src/config/prompts.ts @@ -1,4 +1,4 @@ -// src/config/prompts.ts - Centralized German prompts for AI pipeline +// src/config/prompts.ts - Enhanced with phase completion reasoning export const AI_PROMPTS = { @@ -111,7 +111,7 @@ Antwort: Fließtext ohne Listen, max 100 Wörter.`; const tools = phaseTools.filter(t => t.type === 'software'); if (phaseTools.length === 0) { - return `Keine Tools für Phase "${phase.name}" verfügbar. Antworte mit leerem Array: []`; + return `Keine Methoden/Tools für Phase "${phase.name}" verfügbar. Antworte mit leerem Array: []`; } return `Du bist ein DFIR-Experte. Wähle die 2-3 BESTEN Items für Phase "${phase.name}". @@ -125,7 +125,7 @@ METHODEN (${methods.length}): ${methods.map((method: any) => `- ${method.name} Typ: ${method.type} - Beschreibung: ${method.description.slice(0, 150)}... + Beschreibung: ${method.description} Domains: ${method.domains?.join(', ') || 'N/A'} Skill Level: ${method.skillLevel}` ).join('\n\n')} @@ -136,7 +136,7 @@ SOFTWARE TOOLS (${tools.length}): ${tools.map((tool: any) => `- ${tool.name} Typ: ${tool.type} - Beschreibung: ${tool.description.slice(0, 150)}... + Beschreibung: ${tool.description} Plattformen: ${tool.platforms?.join(', ') || 'N/A'} Skill Level: ${tool.skillLevel}` ).join('\n\n')} @@ -155,7 +155,7 @@ ANTWORT AUSSCHLIESSLICH IM JSON-FORMAT OHNE JEGLICHEN TEXT AUSSERHALB: { "toolName": "Exakter Name aus der Liste oben", "taskRelevance": 85, - "justification": "Spezifische Begründung warum optimal für ${phase.name}", + "justification": "Detaillierte Begründung (60-80 Wörter) warum optimal für ${phase.name} - erkläre Anwendung, Vorteile und spezifische Relevanz", "limitations": ["Mögliche Einschränkung für diese Phase"] } ]`; @@ -202,23 +202,55 @@ ANTWORT AUSSCHLIESSLICH IM JSON-FORMAT OHNE JEGLICHEN TEXT AUSSERHALB DER JSON-S ]`; }, + phaseCompletionReasoning: ( + originalQuery: string, + phase: any, + selectedToolName: string, + tool: any, + completionContext: string + ) => { + return `Du bist ein DFIR-Experte. Erkläre warum dieses Tool nachträglich zur Vervollständigung hinzugefügt wurde. + +KONTEXT DER NACHTRÄGLICHEN ERGÄNZUNG: +- Ursprüngliche KI-Auswahl war zu spezifisch/eng gefasst +- Phase "${phase.name}" war unterrepräsentiert in der initialen Auswahl +- Semantische Suche fand zusätzlich relevante Tools für diese Phase +- Tool wird nachträglich hinzugefügt um Vollständigkeit zu gewährleisten + +URSPRÜNGLICHE ANFRAGE: "${originalQuery}" +PHASE ZU VERVOLLSTÄNDIGEN: ${phase.name} - ${phase.description || ''} +HINZUGEFÜGTES TOOL: ${selectedToolName} (${tool.type}) +TOOL-BESCHREIBUNG: ${tool.description} + +BEGRÜNDUNGSKONTEXT: ${completionContext} + +Erstelle eine präzise Begründung (max. 40 Wörter), die erklärt: +1. WARUM dieses Tool nachträglich hinzugefügt wurde +2. WIE es die ${phase.name}-Phase ergänzt +3. DASS es die ursprünglich zu spezifische Auswahl erweitert + +Antwort: Prägnanter Fließtext, knappe Begründung für Nachergänzung. Vermeide Begriffe wie "Das Tool" und gib keinen einleitenden Text wie "Begründung (40 Wörter):" an.`; + }, + generatePhaseCompletionPrompt( originalQuery: string, phase: any, candidateTools: any[], candidateConcepts: any[] ): string { - return `Du bist ein DFIR-Experte. Die Phase "${phase.name}" ist in der aktuellen Analyse unterrepräsentiert. + return `Du bist ein DFIR-Experte. Die initiale KI-Auswahl war zu spezifisch - die Phase "${phase.name}" ist unterrepräsentiert. + +KONTEXT: Die Hauptauswahl hat zu wenige Tools für "${phase.name}" identifiziert. Wähle jetzt ergänzende Tools aus semantischer Nachsuche. ORIGINAL ANFRAGE: "${originalQuery}" -PHASE ZU VERVOLLSTÄNDIGEN: ${phase.name} - ${phase.description || ''} +UNTERREPRÄSENTIERTE PHASE: ${phase.name} - ${phase.description || ''} -Wähle 1-2 BESTE Tools aus den gefundenen Kandidaten, die diese Phase optimal ergänzen: +SEMANTISCH GEFUNDENE KANDIDATEN für Nachergänzung: VERFÜGBARE TOOLS (${candidateTools.length}): ${candidateTools.map((tool: any) => ` - ${tool.name} (${tool.type}) - Beschreibung: ${tool.description.slice(0, 120)}... + Beschreibung: ${tool.description} Skill Level: ${tool.skillLevel} `).join('')} @@ -226,20 +258,20 @@ ${candidateConcepts.length > 0 ? ` VERFÜGBARE KONZEPTE (${candidateConcepts.length}): ${candidateConcepts.map((concept: any) => ` - ${concept.name} - Beschreibung: ${concept.description.slice(0, 120)}... + Beschreibung: ${concept.description} `).join('')} ` : ''} -AUSWAHLREGELN: -1. Wähle Tools, die die ${phase.name}-Phase der ursprünglichen Anfrage optimal ergänzen -2. Priorisiere Tools, die zur Gesamtlösung beitragen -3. Maximal 2 Tools für diese Phase +AUSWAHLREGELN FÜR NACHERGÄNZUNG: +1. Wähle 1-2 BESTE Methoden/Tools die die ${phase.name}-Phase optimal ergänzen +2. Methoden/Tools müssen für die ursprüngliche Anfrage relevant sein +3. Ergänzen, nicht ersetzen - erweitere die zu spezifische Erstauswahl ANTWORT AUSSCHLIESSLICH IM JSON-FORMAT: { "selectedTools": ["ToolName1", "ToolName2"], "selectedConcepts": ["ConceptName1"], - "reasoning": "Kurze Begründung der Auswahl für ${phase.name}" + "completionReasoning": "Kurze Erklärung warum diese Nachergänzung für ${phase.name} notwendig war" }`; }, @@ -267,6 +299,7 @@ export function getPrompt(key: 'criticalConsiderations', isWorkflow: boolean, us export function getPrompt(key: 'phaseToolSelection', userQuery: string, phase: any, phaseTools: any[]): string; export function getPrompt(key: 'toolEvaluation', userQuery: string, tool: any, rank: number, taskRelevance: number): string; export function getPrompt(key: 'backgroundKnowledgeSelection', userQuery: string, mode: string, selectedToolNames: string[], availableConcepts: any[]): string; +export function getPrompt(key: 'phaseCompletionReasoning', originalQuery: string, phase: any, selectedToolName: string, tool: any, completionContext: string): string; export function getPrompt(key: 'finalRecommendations', isWorkflow: boolean, userQuery: string, selectedToolNames: string[]): string; export function getPrompt(key: 'generatePhaseCompletionPrompt', originalQuery: string, phase: any, candidateTools: any[], candidateConcepts: any[]): string; export function getPrompt(promptKey: keyof typeof AI_PROMPTS, ...args: any[]): string { diff --git a/src/utils/aiPipeline.ts b/src/utils/aiPipeline.ts index 2b35889..2bf712d 100644 --- a/src/utils/aiPipeline.ts +++ b/src/utils/aiPipeline.ts @@ -1046,7 +1046,7 @@ class ImprovedMicroTaskAIPipeline { const phaseStart = Date.now(); const phaseQuery = phaseQueryTemplates[phase.id] || `forensic ${phase.name.toLowerCase()} tools methods`; - console.log('[AI-PIPELINE] Starting phase completion micro-task for:', phase.id); + console.log('[AI-PIPELINE] Starting enhanced phase completion micro-task for:', phase.id); try { const phaseResults = await embeddingsService.findSimilar(phaseQuery, 20, 0.2); @@ -1083,42 +1083,96 @@ class ImprovedMicroTaskAIPipeline { return; } - const prompt = AI_PROMPTS.generatePhaseCompletionPrompt(originalQuery, phase, phaseTools, phaseConcepts); - const response = await this.callAI(prompt, 800); - const selection = this.safeParseJSON(response, { selectedTools: [], selectedConcepts: [] }); + // Step 1: AI selection of tools for completion + const selectionPrompt = AI_PROMPTS.generatePhaseCompletionPrompt(originalQuery, phase, phaseTools, phaseConcepts); + const selectionResult = await this.callMicroTaskAI(selectionPrompt, context, 800); + + if (!selectionResult.success) { + console.error('[AI-PIPELINE] Phase completion selection failed for:', phase.id); + return; + } + + const selection = this.safeParseJSON(selectionResult.content, { + selectedTools: [], + selectedConcepts: [], + completionReasoning: '' + }); const validTools = selection.selectedTools .map((name: string) => phaseTools.find((t: any) => t && t.name === name)) .filter((tool: any): tool is NonNullable => tool !== undefined && tool !== null) .slice(0, 2); - validTools.forEach((tool: any) => { - console.log('[AI-PIPELINE] Adding phase completion tool:', tool.name, 'for', phase.id); + if (validTools.length === 0) { + console.log('[AI-PIPELINE] No valid tools selected for phase completion:', phase.id); + return; + } + + // Step 2: Generate detailed reasoning for each selected tool + for (const tool of validTools) { + console.log('[AI-PIPELINE] Generating reasoning for phase completion tool:', tool.name); + + const reasoningPrompt = getPrompt( + 'phaseCompletionReasoning', + originalQuery, + phase, + tool.name, + tool, + selection.completionReasoning || 'Nachergänzung zur Vervollständigung der Phasenabdeckung' + ); + + const reasoningResult = await this.callMicroTaskAI(reasoningPrompt, context, 400); + + let detailedJustification: string; + if (reasoningResult.success) { + detailedJustification = reasoningResult.content.trim(); + } else { + detailedJustification = `Nachträglich hinzugefügt zur Vervollständigung der ${phase.name}-Phase. Die ursprüngliche KI-Auswahl war zu spezifisch und hat wichtige Tools für diese Phase übersehen.`; + } this.addToolToSelection( context, tool, phase.id, 'medium', - `Hinzugefügt zur Vervollständigung der ${phase.name}-Phase`, + detailedJustification, 75, - ['Via phasenspezifische semantische Suche hinzugefügt'] + ['Nachträgliche Ergänzung via semantische Phasensuche'] ); - }); + + console.log('[AI-PIPELINE] Added phase completion tool with reasoning:', tool.name); + } this.addAuditEntry( context, 'validation', 'phase-completion', - { phase: phase.id, phaseQuery, candidatesFound: phaseTools.length }, - { toolsAdded: validTools.length, addedTools: validTools.map((t: any) => t.name) }, + { + phase: phase.id, + phaseQuery, + candidatesFound: phaseTools.length, + selectionReasoning: selection.completionReasoning + }, + { + toolsAdded: validTools.length, + addedTools: validTools.map((t: any) => ({ + name: t.name, + type: t.type, + reasoning: 'Generated via micro-task' + })) + }, validTools.length > 0 ? 80 : 40, phaseStart, - { phaseCompletion: true, semanticSearch: true } + { + phaseCompletion: true, + semanticSearch: true, + microTaskReasoning: true, + contextualExplanation: true + } ); } catch (error) { - console.error('[AI-PIPELINE] Phase completion failed for:', phase.id, error); + console.error('[AI-PIPELINE] Enhanced phase completion failed for:', phase.id, error); this.addAuditEntry( context,