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_ID=your-client-id
|
||||||
OIDC_CLIENT_SECRET=your-client-secret
|
OIDC_CLIENT_SECRET=your-client-secret
|
||||||
|
|
||||||
# === AI Configuration ===
|
# ===================================================================
|
||||||
|
# AI CONFIGURATION - Complete Reference for Improved Pipeline
|
||||||
|
# ===================================================================
|
||||||
|
|
||||||
# Selector AI (for selection stage, choode a good model)
|
# === CORE AI ENDPOINTS & MODELS ===
|
||||||
AI_SELECTOR_ENDPOINT=https://llm.mikoshi.de
|
AI_API_ENDPOINT=https://llm.mikoshi.de
|
||||||
AI_SELECTOR_API_KEY=sk-DzREDACTEDHA
|
AI_API_KEY=sREDACTED3w
|
||||||
AI_SELECTOR_MODEL=mistral/mistral-medium-latest
|
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_ENDPOINT=https://llm.mikoshi.de
|
||||||
AI_ANALYZER_API_KEY=sk-DzREDACTEDnHA
|
AI_ANALYZER_API_KEY=skREDACTEDw3w
|
||||||
AI_ANALYZER_MODEL=mistral/mistral-small-latest
|
AI_ANALYZER_MODEL='mistral/mistral-small-latest'
|
||||||
|
|
||||||
# === Embeddings Configuration ===
|
# === EMBEDDINGS CONFIGURATION ===
|
||||||
# Enable/disable semantic embeddings pre-selection
|
|
||||||
AI_EMBEDDINGS_ENABLED=true
|
AI_EMBEDDINGS_ENABLED=true
|
||||||
|
|
||||||
# Embeddings API (Mistral recommended)
|
|
||||||
AI_EMBEDDINGS_ENDPOINT=https://api.mistral.ai/v1/embeddings
|
AI_EMBEDDINGS_ENDPOINT=https://api.mistral.ai/v1/embeddings
|
||||||
AI_EMBEDDINGS_API_KEY=ZSpREDACTED3wL
|
AI_EMBEDDINGS_API_KEY=ZREDACTED3wL
|
||||||
AI_EMBEDDINGS_MODEL=mistral-embed
|
AI_EMBEDDINGS_MODEL=mistral-embed
|
||||||
|
|
||||||
# Embeddings performance settings
|
|
||||||
AI_EMBEDDINGS_BATCH_SIZE=20
|
AI_EMBEDDINGS_BATCH_SIZE=20
|
||||||
AI_EMBEDDINGS_BATCH_DELAY_MS=1000
|
AI_EMBEDDINGS_BATCH_DELAY_MS=1000
|
||||||
AI_EMBEDDING_CANDIDATES=30
|
|
||||||
AI_SIMILARITY_THRESHOLD=0.3
|
|
||||||
|
|
||||||
# Delay between micro-tasks to respect rate limits (milliseconds)
|
# === PIPELINE: VectorIndex (HNSW) Configuration ===
|
||||||
AI_MICRO_TASK_DELAY_MS=500
|
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)
|
# === MICRO-TASK CONFIGURATION ===
|
||||||
AI_MICRO_TASK_RATE_LIMIT=30
|
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)
|
# === RATE LIMITING ===
|
||||||
AI_MAX_PARALLEL_TASKS=3
|
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)
|
# === QUEUE MANAGEMENT ===
|
||||||
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
|
|
||||||
AI_QUEUE_MAX_SIZE=50
|
AI_QUEUE_MAX_SIZE=50
|
||||||
AI_QUEUE_CLEANUP_INTERVAL_MS=300000
|
AI_QUEUE_CLEANUP_INTERVAL_MS=300000
|
||||||
|
|
||||||
# === Performance & Monitoring ===
|
# === PERFORMANCE & MONITORING ===
|
||||||
# Enable detailed micro-task logging
|
AI_MICRO_TASK_DEBUG=true
|
||||||
AI_MICRO_TASK_DEBUG=false
|
|
||||||
|
|
||||||
# Enable performance metrics collection
|
|
||||||
AI_PERFORMANCE_METRICS=true
|
AI_PERFORMANCE_METRICS=true
|
||||||
|
|
||||||
# Cache settings for AI responses
|
|
||||||
AI_RESPONSE_CACHE_TTL_MS=3600000
|
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 ===
|
# === Application Configuration ===
|
||||||
PUBLIC_BASE_URL=http://localhost:4321
|
PUBLIC_BASE_URL=http://localhost:4321
|
||||||
NODE_ENV=development
|
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 { getCompressedToolsDataForAI } from './dataService.js';
|
||||||
import { embeddingsService, type EmbeddingData } from './embeddings.js';
|
import { embeddingsService, type EmbeddingData } from './embeddings.js';
|
||||||
import { vectorIndex } from "./vectorIndex.js";
|
import { vectorIndex } from './vectorIndex.js';
|
||||||
|
|
||||||
interface AIConfig {
|
interface AIConfig {
|
||||||
endpoint: string;
|
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 {
|
interface AnalysisContext {
|
||||||
userQuery: string;
|
userQuery: string;
|
||||||
mode: string;
|
mode: string;
|
||||||
filteredData: any;
|
filteredData: any;
|
||||||
// Context continuity
|
// ADDED: Context continuity
|
||||||
contextHistory: string[];
|
contextHistory: string[];
|
||||||
|
|
||||||
// Results
|
// Results (same as original)
|
||||||
scenarioAnalysis?: string;
|
scenarioAnalysis?: string;
|
||||||
problemAnalysis?: string;
|
problemAnalysis?: string;
|
||||||
investigationApproach?: string;
|
investigationApproach?: string;
|
||||||
@ -48,9 +48,6 @@ interface AnalysisContext {
|
|||||||
backgroundKnowledge?: Array<{concept: any, relevance: string}>;
|
backgroundKnowledge?: Array<{concept: any, relevance: string}>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Improved DFIR micro‑task pipeline – 2025‑08‑01 revision (bug‑fixed)
|
|
||||||
*/
|
|
||||||
class ImprovedMicroTaskAIPipeline {
|
class ImprovedMicroTaskAIPipeline {
|
||||||
private config: AIConfig;
|
private config: AIConfig;
|
||||||
private maxSelectedItems: number;
|
private maxSelectedItems: number;
|
||||||
@ -65,46 +62,59 @@ class ImprovedMicroTaskAIPipeline {
|
|||||||
model: this.getEnv('AI_ANALYZER_MODEL')
|
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.maxSelectedItems = parseInt(process.env.AI_MAX_SELECTED_ITEMS || '60', 10);
|
||||||
this.embeddingCandidates = parseInt(process.env.AI_EMBEDDING_CANDIDATES || '40', 10);
|
this.embeddingCandidates = parseInt(process.env.AI_EMBEDDING_CANDIDATES || '60', 10); // HNSW is more efficient
|
||||||
this.similarityThreshold = parseFloat(process.env.AI_SIMILARITY_THRESHOLD || '0.5');
|
this.similarityThreshold = 0.3; // Not used by vectorIndex, kept for fallback compatibility
|
||||||
this.microTaskDelay = parseInt(process.env.AI_MICRO_TASK_DELAY_MS || '500', 10);
|
this.microTaskDelay = parseInt(process.env.AI_MICRO_TASK_DELAY_MS || '500', 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getEnv(key: string): string {
|
private getEnv(key: string): string {
|
||||||
const value = process.env[key];
|
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;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Embedding → LLM blended selector */
|
// IMPROVED: AI-driven selection (no hard-coded keywords)
|
||||||
private async getIntelligentCandidates(userQuery: string, toolsData: any, mode: string) {
|
private async getIntelligentCandidates(userQuery: string, toolsData: any, mode: string) {
|
||||||
const candidateTools = new Set<string>();
|
let candidateTools = new Set<string>();
|
||||||
const candidateConcepts = new Set<string>();
|
let candidateConcepts = new Set<string>();
|
||||||
|
|
||||||
|
// Method 1: Embeddings-based selection (primary)
|
||||||
if (embeddingsService.isEnabled()) {
|
if (embeddingsService.isEnabled()) {
|
||||||
const similarItems = await vectorIndex.findSimilar(userQuery, this.embeddingCandidates);
|
const similarItems = await embeddingsService.findSimilar(
|
||||||
|
userQuery,
|
||||||
|
this.embeddingCandidates,
|
||||||
|
this.similarityThreshold
|
||||||
|
);
|
||||||
|
|
||||||
similarItems.forEach(item => {
|
similarItems.forEach(item => {
|
||||||
if (item.type === 'tool') candidateTools.add(item.name);
|
if (item.type === 'tool') candidateTools.add(item.name);
|
||||||
if (item.type === 'concept') candidateConcepts.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`);
|
||||||
}
|
|
||||||
|
|
||||||
const reducedData = {
|
if (candidateTools.size >= 20) {
|
||||||
...toolsData,
|
return {
|
||||||
tools: candidateTools.size ? toolsData.tools.filter((t: any) => candidateTools.has(t.name)) : toolsData.tools,
|
tools: toolsData.tools.filter((tool: any) => candidateTools.has(tool.name)),
|
||||||
concepts: candidateConcepts.size ? toolsData.concepts.filter((c: any) => candidateConcepts.has(c.name)) : toolsData.concepts
|
concepts: toolsData.concepts.filter((concept: any) => candidateConcepts.has(concept.name)),
|
||||||
|
domains: toolsData.domains,
|
||||||
|
phases: toolsData.phases,
|
||||||
|
'domain-agnostic-software': toolsData['domain-agnostic-software']
|
||||||
};
|
};
|
||||||
|
}
|
||||||
return this.aiSelection(userQuery, reducedData, mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Language‑model based selector (no 50‑item cap) */
|
// Method 2: Fallback AI selection (like original selector)
|
||||||
private async aiSelection(userQuery: string, toolsData: any, mode: string) {
|
console.log(`[IMPROVED PIPELINE] Using AI selector fallback`);
|
||||||
|
return await this.fallbackAISelection(userQuery, toolsData, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback AI selection
|
||||||
|
private async fallbackAISelection(userQuery: string, toolsData: any, mode: string) {
|
||||||
const toolsList = toolsData.tools.map((tool: any) => ({
|
const toolsList = toolsData.tools.map((tool: any) => ({
|
||||||
name: tool.name,
|
name: tool.name,
|
||||||
type: tool.type,
|
type: tool.type,
|
||||||
@ -124,8 +134,7 @@ class ImprovedMicroTaskAIPipeline {
|
|||||||
tags: concept.tags?.slice(0, 5) || []
|
tags: concept.tags?.slice(0, 5) || []
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const modeInstruction =
|
const modeInstruction = mode === 'workflow'
|
||||||
mode === 'workflow'
|
|
||||||
? 'The user wants a COMPREHENSIVE WORKFLOW with multiple tools/methods across different phases.'
|
? '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.';
|
: 'The user wants SPECIFIC TOOLS/METHODS that directly solve their particular problem.';
|
||||||
|
|
||||||
@ -134,7 +143,7 @@ class ImprovedMicroTaskAIPipeline {
|
|||||||
${modeInstruction}
|
${modeInstruction}
|
||||||
|
|
||||||
AVAILABLE TOOLS:
|
AVAILABLE TOOLS:
|
||||||
${JSON.stringify(toolsList, null, 2)}
|
${JSON.stringify(toolsList.slice(0, 50), null, 2)}
|
||||||
|
|
||||||
AVAILABLE CONCEPTS:
|
AVAILABLE CONCEPTS:
|
||||||
${JSON.stringify(conceptsList, null, 2)}
|
${JSON.stringify(conceptsList, null, 2)}
|
||||||
@ -161,12 +170,13 @@ Respond with ONLY this JSON format:
|
|||||||
|
|
||||||
const totalSelected = result.selectedTools.length + result.selectedConcepts.length;
|
const totalSelected = result.selectedTools.length + result.selectedConcepts.length;
|
||||||
if (totalSelected > this.maxSelectedItems) {
|
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.selectedTools = result.selectedTools.slice(0, Math.floor(this.maxSelectedItems * 0.8));
|
||||||
result.selectedConcepts = result.selectedConcepts.slice(0, Math.ceil(this.maxSelectedItems * 0.2));
|
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 {
|
return {
|
||||||
tools: toolsData.tools.filter((tool: any) => result.selectedTools.includes(tool.name)),
|
tools: toolsData.tools.filter((tool: any) => result.selectedTools.includes(tool.name)),
|
||||||
@ -175,25 +185,43 @@ Respond with ONLY this JSON format:
|
|||||||
phases: toolsData.phases,
|
phases: toolsData.phases,
|
||||||
'domain-agnostic-software': toolsData['domain-agnostic-software']
|
'domain-agnostic-software': toolsData['domain-agnostic-software']
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
console.error('[PIPELINE] Failed to parse selector response');
|
console.error('[IMPROVED PIPELINE] Failed to parse selector response');
|
||||||
throw new Error('Invalid JSON response from selector AI');
|
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> {
|
// IMPROVED: Enhanced micro-task with context history
|
||||||
const start = Date.now();
|
private async callMicroTaskAI(prompt: string, context: AnalysisContext, maxTokens: number = 300): Promise<MicroTaskResult> {
|
||||||
const contextPrompt = context.contextHistory.length
|
const startTime = Date.now();
|
||||||
? `BISHERIGE ANALYSE:\n${context.contextHistory.join('\n\n')}\n\nAKTUELLE AUFGABE:\n${prompt}`
|
|
||||||
: prompt;
|
// 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 {
|
try {
|
||||||
const response = await this.callAI(contextPrompt, maxTokens);
|
const response = await this.callAI(contextPrompt, maxTokens);
|
||||||
return { taskType: 'micro-task', content: response.trim(), processingTimeMs: Date.now() - start, success: true };
|
|
||||||
} catch (e) {
|
return {
|
||||||
return { taskType: 'micro-task', content: '', processingTimeMs: Date.now() - start, success: false, error: (e as Error).message };
|
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:
|
Führen Sie eine systematische ${isWorkflow ? 'Szenario-Analyse' : 'Problem-Analyse'} durch und berücksichtigen Sie dabei:
|
||||||
|
|
||||||
${isWorkflow ?
|
${isWorkflow ?
|
||||||
`- Auf das Szenario bezogene Problemstellungen` :
|
`- Angriffsvektoren und Bedrohungsmodellierung nach MITRE ATT&CK
|
||||||
`- konkrete problembezogene Aufgabenstellung`
|
- 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.`;
|
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 isWorkflow = context.mode === 'workflow';
|
||||||
const analysis = isWorkflow ? context.scenarioAnalysis : context.problemAnalysis;
|
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}"
|
${isWorkflow ? 'SZENARIO' : 'PROBLEM'}: "${context.userQuery}"
|
||||||
|
|
||||||
Entwickeln Sie einen systematischen ${isWorkflow ? 'Untersuchungsansatz' : 'Lösungsansatz'} unter Berücksichtigung von:
|
Entwickeln Sie einen systematischen ${isWorkflow ? 'Untersuchungsansatz' : 'Lösungsansatz'} unter Berücksichtigung von:
|
||||||
|
|
||||||
${isWorkflow ?
|
${isWorkflow ?
|
||||||
`- Triage-Prioritäten nach forensischer Dringlichkeit (wenn zutreffend)
|
`- Triage-Prioritäten nach forensischer Dringlichkeit
|
||||||
- Phasenabfolge nach NIST SP 800-86-Methodik (Datensammlung - Auswertung - Analyse - Report)` :
|
- Phasenabfolge nach NIST-Methodik
|
||||||
`- pragmatischer, zielorientierter Lösungsansatz im benehmen mit Anforderungen an die Reproduzierbarkeit`
|
- 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.`;
|
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}"
|
${isWorkflow ? 'SZENARIO' : 'PROBLEM'}: "${context.userQuery}"
|
||||||
|
|
||||||
Berücksichtigen Sie folgende Aspekte:
|
Berücksichtigen Sie folgende forensische Aspekte:
|
||||||
|
|
||||||
${isWorkflow ?
|
${isWorkflow ?
|
||||||
`- Szenariobezogene typische Problemstellungen, die auftreten können` :
|
`- Time-sensitive evidence preservation
|
||||||
`- Problembezogene Schwierigkeiten, die das Ergebnis negativ beeinträchtigen könnten`
|
- 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.`;
|
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')}
|
${phaseTools.map((tool: any) => `- ${tool.name}: ${tool.description.slice(0, 100)}...`).join('\n')}
|
||||||
|
|
||||||
Wählen Sie Methoden/Tools nach forensischen Kriterien aus:
|
Wählen Sie Methoden/Tools nach forensischen Kriterien aus:
|
||||||
- Eignung für die spezifische Lösung des Problems
|
- Court admissibility und Chain of Custody Kompatibilität
|
||||||
- besondere Fähigkeiten der Methode/des Tools, das sie von anderen abgrenzt
|
- Integration in forensische Standard-Workflows
|
||||||
- Reproduzierbarkeit und Objektivität
|
- Reproduzierbarkeit und Dokumentationsqualität
|
||||||
|
- Objektivität
|
||||||
|
|
||||||
Antworten Sie AUSSCHLIESSLICH mit diesem JSON-Format (kein zusätzlicher Text):
|
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)
|
// MICRO-TASK 5: Tool Evaluation (Tool mode)
|
||||||
private async evaluateSpecificTool(context: AnalysisContext, tool: any, rank: number): Promise<MicroTaskResult> {
|
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}"
|
PROBLEM: "${context.userQuery}"
|
||||||
|
|
||||||
@ -437,13 +480,13 @@ EMPFOHLENE TOOLS: ${selectedToolNames.join(', ')}
|
|||||||
VERFÜGBARE KONZEPTE:
|
VERFÜGBARE KONZEPTE:
|
||||||
${availableConcepts.slice(0, 15).map((concept: any) => `- ${concept.name}: ${concept.description.slice(0, 80)}...`).join('\n')}
|
${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:
|
Antworten Sie AUSSCHLIESSLICH mit diesem JSON-Format:
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"conceptName": "Exakter Konzept-Name",
|
"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 isWorkflow = context.mode === 'workflow';
|
||||||
|
|
||||||
const prompt = isWorkflow ?
|
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}"
|
SZENARIO: "${context.userQuery}"
|
||||||
AUSGEWÄHLTE TOOLS: ${context.selectedTools?.map(st => st.tool.name).join(', ') || 'Keine Tools ausgewählt'}
|
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.` :
|
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}"
|
PROBLEM: "${context.userQuery}"
|
||||||
EMPFOHLENE TOOLS: ${context.selectedTools?.map(st => st.tool.name).join(', ') || 'Keine Methoden/Tools ausgewählt'}
|
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.`;
|
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;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MAIN PROCESSING: Restored original structure with context continuity
|
||||||
async processQuery(userQuery: string, mode: string): Promise<AnalysisResult> {
|
async processQuery(userQuery: string, mode: string): Promise<AnalysisResult> {
|
||||||
const startTime = Date.now();
|
const startTime = Date.now();
|
||||||
let completedTasks = 0;
|
let completedTasks = 0;
|
||||||
let failedTasks = 0;
|
let failedTasks = 0;
|
||||||
|
|
||||||
|
console.log(`[IMPROVED PIPELINE] Starting ${mode} query processing with context continuity`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Stage 1: Get intelligent candidates (embeddings + AI selection)
|
||||||
const toolsData = await getCompressedToolsDataForAI();
|
const toolsData = await getCompressedToolsDataForAI();
|
||||||
const filteredData = await this.getIntelligentCandidates(userQuery, toolsData, mode);
|
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`);
|
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);
|
await this.delay(this.microTaskDelay);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const shuffled = [...filteredData.tools].sort(() => Math.random() - 0.5); // FIX
|
// Evaluate top 3 tools for specific problem
|
||||||
const topTools = shuffled.slice(0, 3);
|
const topTools = filteredData.tools.slice(0, 3);
|
||||||
for (let i = 0; i < topTools.length; i++) {
|
for (let i = 0; i < topTools.length; i++) {
|
||||||
const evaluationResult = await this.evaluateSpecificTool(context, topTools[i], i + 1);
|
const evaluationResult = await this.evaluateSpecificTool(context, topTools[i], i + 1);
|
||||||
if (evaluationResult.success) completedTasks++; else failedTasks++;
|
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);
|
const finalResult = await this.generateFinalRecommendations(context);
|
||||||
if (finalResult.success) completedTasks++; else failedTasks++;
|
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 = {
|
const processingStats = {
|
||||||
embeddingsUsed: embeddingsService.isEnabled(),
|
embeddingsUsed: embeddingsService.isEnabled(),
|
||||||
|
vectorIndexUsed: embeddingsService.isEnabled(), // VectorIndex is used when embeddings are enabled
|
||||||
candidatesFromEmbeddings: filteredData.tools.length,
|
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,
|
processingTimeMs: Date.now() - startTime,
|
||||||
microTasksCompleted: completedTasks,
|
microTasksCompleted: completedTasks,
|
||||||
microTasksFailed: failedTasks,
|
microTasksFailed: failedTasks,
|
||||||
contextContinuityUsed: true
|
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) {
|
} catch (error) {
|
||||||
console.error('[PIPELINE] Processing failed:', error);
|
console.error('[IMPROVED PIPELINE] Processing failed:', error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user