diff --git a/src/components/AIQueryInterface.astro b/src/components/AIQueryInterface.astro index 3053541..98912ef 100644 --- a/src/components/AIQueryInterface.astro +++ b/src/components/AIQueryInterface.astro @@ -1130,16 +1130,12 @@ class AIQueryInterface { const lowConfidenceSteps = auditTrail.filter(entry => (entry.confidence || 0) < 60).length; const mediumConfidenceSteps = auditTrail.length - highConfidenceSteps - lowConfidenceSteps; - // FIX 1: Count actual AI decision actions only const aiDecisionCount = auditTrail.filter(entry => entry.action === 'ai-decision').length; - // FIX 2: Count actual similarity search actions, not metadata flags const embeddingsUsageCount = auditTrail.filter(entry => entry.action === 'similarity-search').length; - // FIX 3: Maintain tool selection count (this was correct) const toolSelectionCount = auditTrail.filter(entry => entry.action === 'selection-decision').length; - // Additional diagnostic counts for debugging const microTaskCount = auditTrail.filter(entry => entry.action === 'ai-decision' && entry.metadata?.microTaskType ).length; @@ -1152,7 +1148,6 @@ class AIQueryInterface { entry.action === 'phase-enhancement' ).length; - // Enhanced insights with diagnostic information const keyInsights = []; const potentialIssues = []; @@ -1172,7 +1167,6 @@ class AIQueryInterface { keyInsights.push(`${microTaskCount} spezialisierte Micro-Task-Analysen durchgeführt`); } - // Detect mode-specific patterns for validation if (phaseToolSelectionCount > 0 || phaseEnhancementCount > 0) { keyInsights.push('Workflow-Modus: Phasenspezifische Analyse durchgeführt'); } else if (microTaskCount >= 3) { @@ -1216,10 +1210,9 @@ class AIQueryInterface { keyInsights.push('Mehrheit der Analyseschritte mit hoher Sicherheit'); } - // Validate expected counts based on mode detection const isWorkflowMode = phaseToolSelectionCount > 0 || phaseEnhancementCount > 0; - const expectedMinAI = isWorkflowMode ? 11 : 8; // Workflow: 5 common + 6 phase selections, Tool: 5 common + 3 evaluations - const expectedMinEmbeddings = 1; // Both modes should have initial search + const expectedMinAI = isWorkflowMode ? 11 : 8; + const expectedMinEmbeddings = 1; if (aiDecisionCount < expectedMinAI) { potentialIssues.push(`${expectedMinAI - aiDecisionCount} fehlende KI-Entscheidungen für ${isWorkflowMode ? 'Workflow' : 'Tool'}-Modus`); @@ -1250,7 +1243,6 @@ class AIQueryInterface { analysisQuality, keyInsights, potentialIssues, - // Debug information debugCounts: { microTaskCount, phaseToolSelectionCount, diff --git a/src/config/prompts.ts b/src/config/prompts.ts index c2d4b5d..a1d3deb 100644 --- a/src/config/prompts.ts +++ b/src/config/prompts.ts @@ -16,9 +16,41 @@ STRICTNESS: `.trim(); export const AI_PROMPTS = { - // --------------------------------------------------------------------------- - // Tool/Concept selection (AI pre-pick from embedding-curated set) - // --------------------------------------------------------------------------- + enhancementQuestions: (input: string) => { + return `Sie sind DFIR-Experte. Ein Nutzer beschreibt unten ein Szenario/Problem. + +ZIEL: +- Stellen Sie NUR dann 1–3 präzise Rückfragen, wenn entscheidende forensische Lücken die weitere Analyse/Toolauswahl PHASENREIHENFOLGE oder EVIDENCE-STRATEGIE wesentlich beeinflussen würden. +- Wenn ausreichend abgedeckt: Geben Sie eine leere Liste [] zurück. + +PRIORITÄT DER THEMEN (in dieser Reihenfolge prüfen): +1) Available Evidence & Artefakte (z.B. RAM-Dump, Disk-Image, Logs, PCAP, Registry, Cloud/Audit-Logs) +2) Scope/Systems (konkrete Plattformen/Assets/Identitäten/Netzsegmente) +3) Investigation Objectives (Ziele: IOC-Extraktion, Timeline, Impact, Attribution) +4) Timeline/Timeframe (kritische Zeitfenster, Erhalt flüchtiger Daten) +5) Legal & Compliance (Chain of Custody, Aufbewahrung, DSGVO/Branchenvorgaben) +6) Technical Constraints (Ressourcen, Zugriffsrechte, Tooling/EDR) + +FRAGEN-QUALITÄT: +- Forensisch spezifisch und entscheidungsrelevant (keine Allgemeinplätze). +- Eine Frage pro Thema, keine Dopplungen. +- Antwortbar vom Nutzer (keine Spekulation, keine “Beweise senden”-Aufforderungen). +- Maximal 18 Wörter, endet mit "?". + +VALIDIERUNG: +- Stellen Sie NUR Fragen zu Themen, die im Nutzertext NICHT hinreichend konkret beantwortet sind (keine Wiederholung bereits gegebener Details). +- Wenn alle priorisierten Themen ausreichend sind → []. + +ANTWORTFORMAT (NUR JSON, KEIN ZUSÄTZLICHER TEXT): +[ + "präzise Frage 1?", + "präzise Frage 2?", + "präzise Frage 3?" +] + +NUTZER-EINGABE: +${input}`.trim(); + }, toolSelection: (mode: string, userQuery: string, maxSelectedItems: number) => { const modeInstruction = mode === 'workflow' @@ -80,9 +112,6 @@ ${RELEVANCE_RUBRIC} ${STRICTNESS}`; }, - // --------------------------------------------------------------------------- - // Contextual analyses (keine JSON-Ausgabe nötig; kurzer Fließtext) - // --------------------------------------------------------------------------- scenarioAnalysis: (isWorkflow: boolean, userQuery: string) => { const analysisType = isWorkflow ? 'Szenario' : 'Problem'; const focus = isWorkflow @@ -124,9 +153,6 @@ Fokus: ${focus} Antwort: Fließtext, max 100 Wörter.`; }, - // --------------------------------------------------------------------------- - // Phase-specific selection (workflow mode substep) - // --------------------------------------------------------------------------- phaseToolSelection: (userQuery: string, phase: any, phaseTools: any[]) => { const methods = phaseTools.filter(t => t.type === 'method'); const tools = phaseTools.filter(t => t.type === 'software'); @@ -183,9 +209,6 @@ ANTWORT (NUR JSON): ]`; }, - // --------------------------------------------------------------------------- - // Per-item evaluation (used in tool mode & elsewhere) - // --------------------------------------------------------------------------- toolEvaluation: (userQuery: string, tool: any, rank: number) => { const itemType = tool.type === 'method' ? 'Methode' : 'Tool'; @@ -215,9 +238,6 @@ ANTWORT (NUR JSON): }`; }, - // --------------------------------------------------------------------------- - // Background knowledge (concepts) - // --------------------------------------------------------------------------- backgroundKnowledgeSelection: (userQuery: string, mode: string, selectedToolNames: string[], availableConcepts: any[]) => { return `Wähle 2–4 Konzepte, die das Verständnis/den Einsatz der ausgewählten Tools verbessern. @@ -242,9 +262,6 @@ ANTWORT (NUR JSON): ]`; }, - // --------------------------------------------------------------------------- - // Phase completion (underrepresented phase fix) - // --------------------------------------------------------------------------- phaseCompletionReasoning: ( originalQuery: string, phase: any, @@ -306,9 +323,6 @@ ANTWORT (NUR JSON): }`; }, - // --------------------------------------------------------------------------- - // Final synthesis (short prose, no JSON needed) - // --------------------------------------------------------------------------- finalRecommendations: (isWorkflow: boolean, userQuery: string, selectedToolNames: string[]) => { const focus = isWorkflow ? 'Knappe Workflow-Schritte & Best Practices; neutral formulieren' @@ -324,7 +338,7 @@ Antwort: Fließtext, max ${isWorkflow ? '100' : '80'} Wörter. Keine Liste.`; } } as const; -// Overloads +export function getPrompt(key: 'enhancementQuestions', input: string): string; export function getPrompt(key: 'toolSelection', mode: string, userQuery: string, maxSelectedItems: number): string; export function getPrompt(key: 'toolSelectionWithData', basePrompt: string, toolsToSend: any[], conceptsToSend: any[]): string; export function getPrompt(key: 'scenarioAnalysis', isWorkflow: boolean, userQuery: string): string; @@ -337,7 +351,6 @@ export function getPrompt(key: 'phaseCompletionReasoning', originalQuery: 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; -// Dispatcher export function getPrompt(promptKey: keyof typeof AI_PROMPTS, ...args: any[]): string { try { const f = AI_PROMPTS[promptKey]; @@ -348,4 +361,4 @@ export function getPrompt(promptKey: keyof typeof AI_PROMPTS, ...args: any[]): s console.error(`[PROMPTS] Error generating prompt ${promptKey}:`, err); return 'Error: Failed to generate prompt'; } -} \ No newline at end of file +} diff --git a/src/pages/about.astro b/src/pages/about.astro index 1ae305a..fa4f8b8 100644 --- a/src/pages/about.astro +++ b/src/pages/about.astro @@ -273,15 +273,13 @@ import BaseLayout from '../layouts/BaseLayout.astro';