diff --git a/src/components/AIQueryInterface.astro b/src/components/AIQueryInterface.astro index 1d782ae..417d094 100644 --- a/src/components/AIQueryInterface.astro +++ b/src/components/AIQueryInterface.astro @@ -46,13 +46,29 @@ const domainAgnosticSoftware = data['domain-agnostic-software'] || []; - + + +

@@ -131,6 +147,12 @@ function sanitizeHTML(html) { return div.innerHTML; } +function formatDuration(ms) { + if (ms < 1000) return '< 1s'; + if (ms < 60000) return `${Math.ceil(ms / 1000)}s`; + return `${Math.ceil(ms / 60000)}m`; +} + document.addEventListener('DOMContentLoaded', () => { const aiInterface = document.getElementById('ai-interface'); const aiInput = document.getElementById('ai-query-input'); @@ -245,6 +267,491 @@ document.addEventListener('DOMContentLoaded', () => { aiInput.addEventListener('input', updateCharacterCount); updateCharacterCount(); + function formatWorkflowSuggestion(text) { + const numberedListPattern = /(\d+\.\s)/g; + + if (numberedListPattern.test(text)) { + const items = text.split(/\d+\.\s/).filter(item => item.trim().length > 0); + + if (items.length > 1) { + const listItems = items.map(item => + `

  • ${item.trim()}
  • ` + ).join(''); + + return `
      ${listItems}
    `; + } + } + + const bulletPattern = /^[\s]*[-\*•]\s/gm; + if (bulletPattern.test(text)) { + const items = text.split(/^[\s]*[-\*•]\s/gm).filter(item => item.trim().length > 0); + + if (items.length > 1) { + const listItems = items.map(item => + `
  • ${item.trim()}
  • ` + ).join(''); + + return ``; + } + } + + if (text.includes('\n')) { + const lines = text.split('\n').filter(line => line.trim().length > 0); + if (lines.length > 1) { + const listItems = lines.map(line => + `
  • ${line.trim()}
  • ` + ).join(''); + + return ``; + } + } + + return `

    ${text}

    `; + } + + function renderBackgroundKnowledge(backgroundKnowledge) { + if (!backgroundKnowledge || backgroundKnowledge.length === 0) { + return ''; + } + + const conceptLinks = backgroundKnowledge.map(concept => ` +
    +
    + + Hintergrundwissen +
    +

    + ${concept.relevance} +

    +
    + `).join(''); + + return ` +
    +

    + + + + + Empfohlenes Hintergrundwissen +

    + ${conceptLinks} +
    + `; + } + + // Enhanced function to render contextual analysis sections + function renderContextualAnalysis(recommendation, mode) { + let html = ''; + + // Scenario/Problem Analysis Section + const analysisField = mode === 'workflow' ? recommendation.scenario_analysis : recommendation.problem_analysis; + if (analysisField) { + html += ` +
    +

    + + + + + ${mode === 'workflow' ? 'Szenario-Analyse' : 'Problem-Analyse'} +

    + ${formatWorkflowSuggestion(analysisField)} +
    + `; + } + + // Investigation Approach Section + if (recommendation.investigation_approach) { + html += ` +
    +

    + + + + + ${mode === 'workflow' ? 'Untersuchungsansatz' : 'Lösungsansatz'} +

    + ${formatWorkflowSuggestion(recommendation.investigation_approach)} +
    + `; + } + + // Critical Considerations Section + if (recommendation.critical_considerations) { + html += ` +
    +

    + + + + + + ${mode === 'workflow' ? 'Kritische Überlegungen' : 'Wichtige Voraussetzungen'} +

    + ${formatWorkflowSuggestion(recommendation.critical_considerations)} +
    + `; + } + + return html; + } + + function displayWorkflowResults(recommendation, originalQuery) { + const toolsByPhase = {}; + + const phaseOrder = phases.map(phase => phase.id); + const phaseNames = phases.reduce((acc, phase) => { + acc[phase.id] = phase.name; + return acc; + }, {}); + + phaseOrder.forEach(phase => { + toolsByPhase[phase] = []; + }); + + recommendation.recommended_tools?.forEach(recTool => { + if (toolsByPhase[recTool.phase]) { + const fullTool = tools.find(t => t.name === recTool.name); + if (fullTool) { + toolsByPhase[recTool.phase].push({ + ...fullTool, + recommendation: recTool + }); + } + } + }); + + const resultsHTML = ` +
    +
    +

    Empfohlener DFIR-Workflow

    +

    + Basierend auf Ihrer Anfrage: "${originalQuery.slice(0, 100)}${originalQuery.length > 100 ? '...' : ''}" +

    +
    + + ${renderContextualAnalysis(recommendation, 'workflow')} + + ${renderBackgroundKnowledge(recommendation.background_knowledge)} + + ${phaseOrder.map((phase, index) => { + const phaseTools = toolsByPhase[phase]; + if (phaseTools.length === 0) return ''; + + return ` +
    +
    +
    ${index + 1}
    +
    +

    ${phaseNames[phase]}

    +
    + ${phaseTools.map(tool => { + const hasValidProjectUrl = tool.projectUrl !== undefined && + tool.projectUrl !== null && + tool.projectUrl !== "" && + tool.projectUrl.trim() !== ""; + + const priorityColors = { + high: 'var(--color-error)', + medium: 'var(--color-warning)', + low: 'var(--color-accent)' + }; + + return ` +
    +
    +

    + ${tool.icon ? `${tool.icon}` : ''} + ${tool.name} +

    + + ${tool.recommendation.priority} + +
    + +
    + "${tool.recommendation.justification}" +
    + + +
    + `; + }).join('')} +
    +
    +
    + ${index < phaseOrder.length - 1 ? ` +
    + + + + +
    + ` : ''} +
    + `; + }).join('')} + + ${recommendation.workflow_suggestion ? ` +
    +

    + + + + + Workflow-Empfehlung +

    + ${formatWorkflowSuggestion(recommendation.workflow_suggestion)} +
    + ` : ''} + + ${recommendation.additional_notes ? ` +
    +

    + + + + + + Wichtige Hinweise +

    +
    + ${formatWorkflowSuggestion(recommendation.additional_notes).replace(/color: var\(--color-text\)/g, 'color: white')} +
    +
    + ` : ''} +
    + `; + + aiResults.innerHTML = ''; + const tempDiv = document.createElement('div'); + tempDiv.innerHTML = resultsHTML; + aiResults.appendChild(tempDiv); + } + + function displayToolResults(recommendation, originalQuery) { + function getSuitabilityText(score) { + const suitabilityTexts = { + high: 'GUT GEEIGNET', + medium: 'GEEIGNET', + low: 'VIELLEICHT GEEIGNET' + }; + return suitabilityTexts[score] || 'GEEIGNET'; + } + + function getToolPhases(tool) { + if (!tool.phases || tool.phases.length === 0) return ''; + + const phaseNames = phases.reduce((acc, phase) => { + acc[phase.id] = phase.name; + return acc; + }, {}); + + const domainAgnosticNames = domainAgnosticSoftware.reduce((acc, section) => { + acc[section.id] = section.name; + return acc; + }, {}); + + const allPhaseNames = { ...phaseNames, ...domainAgnosticNames }; + + return tool.phases.map(phaseId => allPhaseNames[phaseId]).filter(Boolean).join(', '); + } + + const resultsHTML = ` +
    +
    +

    + + + + Passende Empfehlungen +

    +

    + Basierend auf Ihrer Anfrage: "${originalQuery.slice(0, 100)}${originalQuery.length > 100 ? '...' : ''}" +

    +
    + + ${renderContextualAnalysis(recommendation, 'tool')} + + ${renderBackgroundKnowledge(recommendation.background_knowledge)} + +
    + ${recommendation.recommended_tools?.map((toolRec, index) => { + const fullTool = tools.find(t => t.name === toolRec.name); + if (!fullTool) return ''; + + const hasValidProjectUrl = fullTool.projectUrl !== undefined && + fullTool.projectUrl !== null && + fullTool.projectUrl !== "" && + fullTool.projectUrl.trim() !== ""; + const isMethod = fullTool.type === 'method'; + const suitabilityColors = { + high: 'var(--color-accent)', + medium: 'var(--color-warning)', + low: 'var(--color-text-secondary)' + }; + + const rankColors = { + 1: 'var(--color-accent)', + 2: 'var(--color-primary)', + 3: 'var(--color-warning)' + }; + + return ` +
    + +
    + ${toolRec.rank} +
    + +
    +

    ${fullTool.name}

    +
    + + ${getSuitabilityText(toolRec.suitability_score)} + + ${isMethod ? 'Methode' : ''} + ${!isMethod && hasValidProjectUrl ? 'CC24-Server' : ''} + ${!isMethod && fullTool.license !== 'Proprietary' ? 'Open Source' : ''} + ${fullTool.knowledgebase === true ? '📖' : ''} +
    +
    +
    + ${(() => { + const toolPhases = getToolPhases(fullTool); + return toolPhases ? ` +
    +
    + + + + + Anwendbare Phasen: ${toolPhases} +
    +
    + ` : ''; + })()} +
    +
    +

    + + + + + Warum diese Methode für Ihr Szenario? +

    + ${formatWorkflowSuggestion(toolRec.detailed_explanation)} + ${toolRec.implementation_approach ? ` +

    + + + + + Anwendungsansatz +

    + ${formatWorkflowSuggestion(toolRec.implementation_approach)} + ` : ''} +
    + + ${(toolRec.pros && toolRec.pros.length > 0) || (toolRec.cons && toolRec.cons.length > 0) ? ` +
    + ${toolRec.pros && toolRec.pros.length > 0 ? ` +
    +
    + + + + Vorteile +
    +
      + ${toolRec.pros.map(pro => `
    • ${pro}
    • `).join('')} +
    +
    + ` : ''} + ${toolRec.cons && toolRec.cons.length > 0 ? ` +
    +
    + + + + + Nachteile +
    +
      + ${toolRec.cons.map(con => `
    • ${con}
    • `).join('')} +
    +
    + ` : ''} +
    + ` : ''} + + + + ${toolRec.alternatives ? ` +
    +
    + + + + + + Alternative Ansätze +
    + ${formatWorkflowSuggestion(toolRec.alternatives)} +
    + ` : ''} +
    + `; + }).join('')} +
    + + ${recommendation.additional_considerations ? ` +
    +

    + + + + + + Zusätzliche Überlegungen +

    + ${formatWorkflowSuggestion(recommendation.additional_considerations)} +
    + ` : ''} +
    + `; + + aiResults.innerHTML = ''; + const tempDiv = document.createElement('div'); + tempDiv.innerHTML = resultsHTML; + aiResults.appendChild(tempDiv); + } + const handleSubmit = async () => { const query = aiInput.value.trim(); @@ -402,456 +909,6 @@ document.addEventListener('DOMContentLoaded', () => { } }; - function formatWorkflowSuggestion(text) { - const numberedListPattern = /(\d+\.\s)/g; - - if (numberedListPattern.test(text)) { - const items = text.split(/\d+\.\s/).filter(item => item.trim().length > 0); - - if (items.length > 1) { - const listItems = items.map(item => - `
  • ${item.trim()}
  • ` - ).join(''); - - return `
      ${listItems}
    `; - } - } - - const bulletPattern = /^[\s]*[-\*•]\s/gm; - if (bulletPattern.test(text)) { - const items = text.split(/^[\s]*[-\*•]\s/gm).filter(item => item.trim().length > 0); - - if (items.length > 1) { - const listItems = items.map(item => - `
  • ${item.trim()}
  • ` - ).join(''); - - return ``; - } - } - - if (text.includes('\n')) { - const lines = text.split('\n').filter(line => line.trim().length > 0); - if (lines.length > 1) { - const listItems = lines.map(line => - `
  • ${line.trim()}
  • ` - ).join(''); - - return ``; - } - } - - return `

    ${text}

    `; - } - - function renderBackgroundKnowledge(backgroundKnowledge) { - if (!backgroundKnowledge || backgroundKnowledge.length === 0) { - return ''; - } - - const conceptLinks = backgroundKnowledge.map(concept => ` -
    -
    - - Hintergrundwissen -
    -

    - ${concept.relevance} -

    -
    - `).join(''); - - return ` -
    -

    - - - - - Empfohlenes Hintergrundwissen -

    - ${conceptLinks} -
    - `; - } - - function displayWorkflowResults(recommendation, originalQuery) { - const toolsByPhase = {}; - - const phaseOrder = phases.map(phase => phase.id); - const phaseNames = phases.reduce((acc, phase) => { - acc[phase.id] = phase.name; - return acc; - }, {}); - - phaseOrder.forEach(phase => { - toolsByPhase[phase] = []; - }); - - recommendation.recommended_tools?.forEach(recTool => { - if (toolsByPhase[recTool.phase]) { - const fullTool = tools.find(t => t.name === recTool.name); - if (fullTool) { - toolsByPhase[recTool.phase].push({ - ...fullTool, - recommendation: recTool - }); - } - } - }); - - const resultsHTML = ` -
    -
    -

    Empfohlener DFIR-Workflow

    -

    - Basierend auf Ihrer Anfrage: "${originalQuery.slice(0, 100)}${originalQuery.length > 100 ? '...' : ''}" -

    -
    - - ${recommendation.scenario_analysis ? ` -
    -

    - - - - - Szenario-Analyse -

    - ${formatWorkflowSuggestion(recommendation.scenario_analysis)} -
    - ` : ''} - - ${renderBackgroundKnowledge(recommendation.background_knowledge)} - - ${phaseOrder.map((phase, index) => { - const phaseTools = toolsByPhase[phase]; - if (phaseTools.length === 0) return ''; - - return ` -
    -
    -
    ${index + 1}
    -
    -

    ${phaseNames[phase]}

    -
    - ${phaseTools.map(tool => { - const hasValidProjectUrl = tool.projectUrl !== undefined && - tool.projectUrl !== null && - tool.projectUrl !== "" && - tool.projectUrl.trim() !== ""; - - const priorityColors = { - high: 'var(--color-error)', - medium: 'var(--color-warning)', - low: 'var(--color-accent)' - }; - - return ` -
    -
    -

    - ${tool.icon ? `${tool.icon}` : ''} - ${tool.name} -

    - - ${tool.recommendation.priority} - -
    - -
    - "${tool.recommendation.justification}" -
    - - -
    - `; - }).join('')} -
    -
    -
    - ${index < phaseOrder.length - 1 ? ` -
    - - - - -
    - ` : ''} -
    - `; - }).join('')} - - ${recommendation.workflow_suggestion ? ` -
    -

    - - - - - Workflow-Empfehlung -

    - ${formatWorkflowSuggestion(recommendation.workflow_suggestion)} -
    - ` : ''} - - ${recommendation.additional_notes ? ` -
    -

    - - - - - - Wichtige Hinweise -

    -
    - ${formatWorkflowSuggestion(recommendation.additional_notes).replace(/color: var\(--color-text\)/g, 'color: white')} -
    -
    - ` : ''} -
    - `; - - aiResults.innerHTML = ''; - const tempDiv = document.createElement('div'); - tempDiv.innerHTML = resultsHTML; - aiResults.appendChild(tempDiv); - } - - function displayToolResults(recommendation, originalQuery) { - function getSuitabilityText(score) { - const suitabilityTexts = { - high: 'GUT GEEIGNET', - medium: 'GEEIGNET', - low: 'VIELLEICHT GEEIGNET' - }; - return suitabilityTexts[score] || 'GEEIGNET'; - } - - function getToolPhases(tool) { - if (!tool.phases || tool.phases.length === 0) return ''; - - const phaseNames = phases.reduce((acc, phase) => { - acc[phase.id] = phase.name; - return acc; - }, {}); - - const domainAgnosticNames = domainAgnosticSoftware.reduce((acc, section) => { - acc[section.id] = section.name; - return acc; - }, {}); - - const allPhaseNames = { ...phaseNames, ...domainAgnosticNames }; - - return tool.phases.map(phaseId => allPhaseNames[phaseId]).filter(Boolean).join(', '); - } - const resultsHTML = ` -
    -
    -

    - - - - Passende Empfehlungen -

    -

    - Basierend auf Ihrer Anfrage: "${originalQuery.slice(0, 100)}${originalQuery.length > 100 ? '...' : ''}" -

    -
    - - ${recommendation.problem_analysis ? ` -
    -

    - - - - - - Problem-Analyse -

    - ${formatWorkflowSuggestion(recommendation.problem_analysis)} -
    - ` : ''} - - ${renderBackgroundKnowledge(recommendation.background_knowledge)} - -
    - ${recommendation.recommended_tools?.map((toolRec, index) => { - const fullTool = tools.find(t => t.name === toolRec.name); - if (!fullTool) return ''; - - const hasValidProjectUrl = fullTool.projectUrl !== undefined && - fullTool.projectUrl !== null && - fullTool.projectUrl !== "" && - fullTool.projectUrl.trim() !== ""; - const isMethod = fullTool.type === 'method'; - const suitabilityColors = { - high: 'var(--color-accent)', - medium: 'var(--color-warning)', - low: 'var(--color-text-secondary)' - }; - - const rankColors = { - 1: 'var(--color-accent)', - 2: 'var(--color-primary)', - 3: 'var(--color-warning)' - }; - - return ` -
    - -
    - ${toolRec.rank} -
    - -
    -

    ${fullTool.name}

    -
    - - ${getSuitabilityText(toolRec.suitability_score)} - - ${isMethod ? 'Methode' : ''} - ${!isMethod && hasValidProjectUrl ? 'CC24-Server' : ''} - ${!isMethod && fullTool.license !== 'Proprietary' ? 'Open Source' : ''} - ${fullTool.knowledgebase === true ? '📖' : ''} -
    -
    -
    - ${(() => { - const toolPhases = getToolPhases(fullTool); - return toolPhases ? ` -
    -
    - - - - - Anwendbare Phasen: ${toolPhases} -
    -
    - ` : ''; - })()} -
    -
    -

    - - - - - Warum diese Methode? -

    - ${formatWorkflowSuggestion(toolRec.detailed_explanation)} - ${toolRec.implementation_approach ? ` -

    - - - - - Anwendungsansatz -

    - ${formatWorkflowSuggestion(toolRec.implementation_approach)} - ` : ''} -
    - - ${(toolRec.pros && toolRec.pros.length > 0) || (toolRec.cons && toolRec.cons.length > 0) ? ` -
    - ${toolRec.pros && toolRec.pros.length > 0 ? ` -
    -
    - - - - Vorteile -
    -
      - ${toolRec.pros.map(pro => `
    • ${pro}
    • `).join('')} -
    -
    - ` : ''} - ${toolRec.cons && toolRec.cons.length > 0 ? ` -
    -
    - - - - - Nachteile -
    -
      - ${toolRec.cons.map(con => `
    • ${con}
    • `).join('')} -
    -
    - ` : ''} -
    - ` : ''} - - - - ${toolRec.alternatives ? ` -
    -
    - - - - - - Alternative Ansätze -
    - ${formatWorkflowSuggestion(toolRec.alternatives)} -
    - ` : ''} -
    - `; - }).join('')} -
    - - ${recommendation.additional_considerations ? ` -
    -

    - - - - - - Zusätzliche Überlegungen -

    - ${formatWorkflowSuggestion(recommendation.additional_considerations)} -
    - ` : ''} -
    - `; - - aiResults.innerHTML = ''; - const tempDiv = document.createElement('div'); - tempDiv.innerHTML = resultsHTML; - aiResults.appendChild(tempDiv); - } - updateModeUI(); }); \ No newline at end of file diff --git a/src/pages/api/ai/enhance-input.ts b/src/pages/api/ai/enhance-input.ts new file mode 100644 index 0000000..ccfb2fe --- /dev/null +++ b/src/pages/api/ai/enhance-input.ts @@ -0,0 +1,182 @@ +// src/pages/api/ai/enhance-input.ts +import type { APIRoute } from 'astro'; +import { withAPIAuth } from '../../../utils/auth.js'; +import { apiError, apiServerError, createAuthErrorResponse } from '../../../utils/api.js'; +import { enqueueApiCall } from '../../../utils/rateLimitedQueue.js'; + +export const prerender = false; + +function getEnv(key: string): string { + const value = process.env[key]; + if (!value) { + throw new Error(`Missing environment variable: ${key}`); + } + return value; +} + +const AI_MODEL = getEnv('AI_MODEL'); +const rateLimitStore = new Map(); +const RATE_LIMIT_WINDOW = 60 * 1000; // 1 minute +const RATE_LIMIT_MAX = 5; // 5 enhancement requests per minute per user + +function sanitizeInput(input: string): string { + return input + .replace(/```[\s\S]*?```/g, '[CODE_BLOCK_REMOVED]') + .replace(/\<\/?[^>]+(>|$)/g, '') + .replace(/\b(system|assistant|user)\s*[:]/gi, '[ROLE_REMOVED]') + .replace(/\b(ignore|forget|disregard)\s+(previous|all|your)\s+(instructions?|context|rules?)/gi, '[INSTRUCTION_REMOVED]') + .trim() + .slice(0, 1000); // Shorter limit for enhancement +} + +function checkRateLimit(userId: string): boolean { + const now = Date.now(); + const userLimit = rateLimitStore.get(userId); + + if (!userLimit || now > userLimit.resetTime) { + rateLimitStore.set(userId, { count: 1, resetTime: now + RATE_LIMIT_WINDOW }); + return true; + } + + if (userLimit.count >= RATE_LIMIT_MAX) { + return false; + } + + userLimit.count++; + return true; +} + +function cleanupExpiredRateLimits() { + const now = Date.now(); + for (const [userId, limit] of rateLimitStore.entries()) { + if (now > limit.resetTime) { + rateLimitStore.delete(userId); + } + } +} + +// Clean up expired limits every 5 minutes +setInterval(cleanupExpiredRateLimits, 5 * 60 * 1000); + +function createEnhancementPrompt(input: string): string { + return `Analysiere diese forensische Szenario-Beschreibung und schlage 2-3 kurze, präzise Fragen vor, die dem Nutzer helfen würden, vollständigere Informationen zu liefern. + +Nutzer-Eingabe: "${input}" + +Konzentriere dich auf wichtige Details die für eine forensische Untersuchung relevant sind: +- Betroffene Systeme/Plattformen +- Zeitrahmen/Timeline +- Verfügbare Evidenz +- Verdächtige Aktivitäten +- Technische Details + +Antworte NUR mit einem JSON-Array von 2-3 kurzen Fragen (max. 60 Zeichen pro Frage): +["Frage 1?", "Frage 2?", "Frage 3?"] + +Keine zusätzlichen Erklärungen.`; +} + +export const POST: APIRoute = async ({ request }) => { + try { + const authResult = await withAPIAuth(request, 'ai'); + if (!authResult.authenticated) { + return createAuthErrorResponse(); + } + + const userId = authResult.userId; + + if (!checkRateLimit(userId)) { + return apiError.rateLimit('Enhancement rate limit exceeded'); + } + + const body = await request.json(); + const { input } = body; + + if (!input || typeof input !== 'string' || input.length < 20) { + return apiError.badRequest('Input too short for enhancement'); + } + + const sanitizedInput = sanitizeInput(input); + if (sanitizedInput.length < 20) { + return apiError.badRequest('Input too short after sanitization'); + } + + const systemPrompt = createEnhancementPrompt(sanitizedInput); + const taskId = `enhance_${userId}_${Date.now()}_${Math.random().toString(36).substr(2, 4)}`; + + const aiResponse = await enqueueApiCall(() => + fetch(process.env.AI_API_ENDPOINT + '/v1/chat/completions', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${process.env.AI_API_KEY}` + }, + body: JSON.stringify({ + model: AI_MODEL, + messages: [ + { + role: 'user', + content: systemPrompt + } + ], + max_tokens: 200, + temperature: 0.7 + }) + }), taskId); + + if (!aiResponse.ok) { + console.error('AI enhancement error:', await aiResponse.text()); + return apiServerError.unavailable('Enhancement service unavailable'); + } + + const aiData = await aiResponse.json(); + const aiContent = aiData.choices?.[0]?.message?.content; + + if (!aiContent) { + return apiServerError.unavailable('No enhancement response'); + } + + let questions; + try { + // Clean up the response and parse JSON + const cleanedContent = aiContent + .replace(/^```json\s*/i, '') + .replace(/\s*```\s*$/, '') + .trim(); + + questions = JSON.parse(cleanedContent); + + if (!Array.isArray(questions) || questions.length === 0) { + throw new Error('Invalid questions format'); + } + + // Validate and clean questions + questions = questions + .filter(q => typeof q === 'string' && q.length > 5 && q.length < 100) + .slice(0, 3); + + if (questions.length === 0) { + throw new Error('No valid questions found'); + } + + } catch (error) { + console.error('Failed to parse enhancement response:', aiContent); + return apiServerError.unavailable('Invalid enhancement response format'); + } + + console.log(`[AI Enhancement] User: ${userId}, Questions: ${questions.length}, Input length: ${sanitizedInput.length}`); + + return new Response(JSON.stringify({ + success: true, + questions, + taskId + }), { + status: 200, + headers: { 'Content-Type': 'application/json' } + }); + + } catch (error) { + console.error('Enhancement error:', error); + return apiServerError.internal('Enhancement processing failed'); + } +}; \ No newline at end of file diff --git a/src/pages/api/ai/query.ts b/src/pages/api/ai/query.ts index c011d84..55cae17 100644 --- a/src/pages/api/ai/query.ts +++ b/src/pages/api/ai/query.ts @@ -155,6 +155,11 @@ WICHTIGE REGELN: 8. WICHTIG: Erwähne relevante Hintergrundwissen-Konzepte wenn Tools verwendet werden, die related_concepts haben 9. Konzepte sind NICHT Tools - empfehle sie nicht als actionable Schritte, sondern als Wissensbasis +ENHANCED CONTEXTUAL ANALYSIS: +10. Analysiere das Szenario detailliert und identifiziere Schlüsselelemente, Bedrohungen und forensische Herausforderungen +11. Entwickle einen strategischen Untersuchungsansatz basierend auf dem spezifischen Szenario +12. Identifiziere zeitkritische oder besonders wichtige Faktoren für diesen Fall + SOFTWARE/METHODEN-AUSWAHL NACH PHASE: ${phaseDescriptions} @@ -163,16 +168,18 @@ ${domainAgnosticDescriptions} ANTWORT-FORMAT (strict JSON): { - "scenario_analysis": "Detaillierte Analyse des Szenarios auf Deutsch/English", + "scenario_analysis": "Detaillierte Analyse des Szenarios: Erkannte Schlüsselelemente, Art des Vorfalls, betroffene Systeme, potentielle Bedrohungen und forensische Herausforderungen", + "investigation_approach": "Strategischer Untersuchungsansatz für dieses spezifische Szenario: Prioritäten, Reihenfolge der Phasen, besondere Überlegungen", + "critical_considerations": "Zeitkritische Faktoren, wichtige Sicherheitsaspekte oder besondere Vorsichtsmaßnahmen für diesen Fall", "recommended_tools": [ { "name": "EXAKTER Name aus der Tools-Database", "priority": "high|medium|low", "phase": "${validPhases}", - "justification": "Warum diese Methode für diese Phase und Szenario geeignet ist" + "justification": "Warum diese Methode für diese Phase und dieses spezifische Szenario geeignet ist - mit Bezug zu den erkannten Schlüsselelementen" } ], - "workflow_suggestion": "Vorgeschlagener Untersuchungsablauf", + "workflow_suggestion": "Vorgeschlagener Untersuchungsablauf mit konkreten Schritten für dieses Szenario", "background_knowledge": [ { "concept_name": "EXAKTER Name aus der Konzepte-Database", @@ -230,15 +237,22 @@ WICHTIGE REGELN: 10. WICHTIG: Erwähne relevante Hintergrundwissen-Konzepte wenn Tools verwendet werden, die related_concepts haben 11. Konzepte sind NICHT Tools - empfehle sie nicht als actionable Schritte, sondern als Wissensbasis +ENHANCED CONTEXTUAL ANALYSIS: +12. Analysiere das Problem detailliert und identifiziere technische Anforderungen, Herausforderungen und Erfolgsfaktoren +13. Entwickle einen strategischen Lösungsansatz basierend auf dem spezifischen Problem +14. Identifiziere wichtige Voraussetzungen oder Warnungen für die Anwendung + ANTWORT-FORMAT (strict JSON): { - "problem_analysis": "Detaillierte Analyse des Problems/der Anforderung", + "problem_analysis": "Detaillierte Analyse des Problems: Erkannte technische Anforderungen, Herausforderungen, benötigte Fähigkeiten und Erfolgsfaktoren", + "investigation_approach": "Strategischer Lösungsansatz für dieses spezifische Problem: Herangehensweise, Prioritäten, optimale Anwendungsreihenfolge", + "critical_considerations": "Wichtige Voraussetzungen, potentielle Fallstricke oder Warnungen für die Anwendung der empfohlenen Lösungen", "recommended_tools": [ { "name": "EXAKTER Name aus der Tools-Database", "rank": 1, "suitability_score": "high|medium|low", - "detailed_explanation": "Detaillierte Erklärung, warum dieses Tool/diese Methode das Problem löst", + "detailed_explanation": "Detaillierte Erklärung, warum dieses Tool/diese Methode das spezifische Problem löst - mit Bezug zu den erkannten Anforderungen", "implementation_approach": "Konkrete Schritte/Ansatz zur Anwendung für dieses spezifische Problem", "pros": ["Spezifische Vorteile für diesen Anwendungsfall", "Weitere Vorteile"], "cons": ["Potentielle Nachteile oder Limitationen", "Weitere Einschränkungen"], @@ -348,6 +362,10 @@ export const POST: APIRoute = async ({ request }) => { if (mode === 'workflow') { validatedRecommendation = { ...recommendation, + // Ensure all new fields are included with fallbacks + scenario_analysis: recommendation.scenario_analysis || recommendation.problem_analysis || '', + investigation_approach: recommendation.investigation_approach || '', + critical_considerations: recommendation.critical_considerations || '', recommended_tools: recommendation.recommended_tools?.filter((tool: any) => { if (!validToolNames.has(tool.name)) { console.warn(`AI recommended unknown tool: ${tool.name}`); @@ -366,6 +384,10 @@ export const POST: APIRoute = async ({ request }) => { } else { validatedRecommendation = { ...recommendation, + // Ensure all new fields are included with fallbacks + problem_analysis: recommendation.problem_analysis || recommendation.scenario_analysis || '', + investigation_approach: recommendation.investigation_approach || '', + critical_considerations: recommendation.critical_considerations || '', recommended_tools: recommendation.recommended_tools?.filter((tool: any) => { if (!validToolNames.has(tool.name)) { console.warn(`AI recommended unknown tool: ${tool.name}`);