@devilsdev/rag-pipeline-utils 2.4.4 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.ragrc.schema.json +83 -192
- package/CHANGELOG.md +345 -0
- package/README.md +418 -117
- package/SECURITY.md +5 -5
- package/dist/experimental.cjs +2 -0
- package/dist/experimental.d.ts +1 -0
- package/dist/experimental.mjs +5 -0
- package/dist/index.cjs +4992 -1242
- package/dist/index.d.ts +80 -2
- package/dist/index.mjs +1 -1
- package/dist/types/agentic/agentic-pipeline.d.ts +103 -0
- package/dist/types/agentic/iterative-retriever.d.ts +85 -0
- package/dist/types/agentic/query-planner.d.ts +145 -0
- package/dist/types/agentic/self-critique.d.ts +45 -0
- package/dist/types/ai/adaptive-retrieval.d.ts +44 -0
- package/dist/types/ai/federation/federated-learning-coordinator.d.ts +62 -0
- package/dist/types/ai/multimodal-processing.d.ts +32 -0
- package/dist/types/ai/multimodal.d.ts +39 -0
- package/dist/types/ai/retrieval-engine.d.ts +37 -0
- package/dist/types/ai/training/model-training-orchestrator.d.ts +31 -0
- package/dist/types/chunking/chunking-engine.d.ts +70 -0
- package/dist/types/chunking/strategies/fixed-size.d.ts +17 -0
- package/dist/types/chunking/strategies/recursive.d.ts +20 -0
- package/dist/types/chunking/strategies/semantic.d.ts +19 -0
- package/dist/types/chunking/strategies/sentence.d.ts +13 -0
- package/dist/types/chunking/strategies/structure-aware.d.ts +19 -0
- package/dist/types/citation/citation-tracker.d.ts +64 -0
- package/dist/types/citation/hallucination-detector.d.ts +40 -0
- package/dist/types/citation/source-mapper.d.ts +37 -0
- package/dist/types/connectors/anthropic-connector.d.ts +92 -0
- package/dist/types/connectors/base-connector.d.ts +87 -0
- package/dist/types/connectors/cohere-connector.d.ts +89 -0
- package/dist/types/connectors/connector-utils.d.ts +110 -0
- package/dist/types/connectors/local-embedder.d.ts +86 -0
- package/dist/types/connectors/memory-retriever.d.ts +91 -0
- package/dist/types/connectors/ollama-connector.d.ts +110 -0
- package/dist/types/connectors/openai-connector.d.ts +114 -0
- package/dist/types/connectors/rag-prompt.d.ts +40 -0
- package/dist/types/cost/cost-calculator.d.ts +152 -0
- package/dist/types/cost/cost-tracker.d.ts +126 -0
- package/dist/types/cost/token-budget.d.ts +110 -0
- package/dist/types/dag/core/error-context.d.ts +239 -0
- package/dist/types/dag/core/execution-scheduler.d.ts +191 -0
- package/dist/types/dag/core/topology-validation.d.ts +226 -0
- package/dist/types/dag/dag-engine.d.ts +156 -0
- package/dist/types/dag/dag-node.d.ts +37 -0
- package/dist/types/dashboard/dashboard-generator.d.ts +127 -0
- package/dist/types/dashboard/metrics-aggregator.d.ts +218 -0
- package/dist/types/debug/execution-tracer.d.ts +57 -0
- package/dist/types/debug/trace-inspector.d.ts +31 -0
- package/dist/types/ecosystem/plugin-certification.d.ts +169 -0
- package/dist/types/enterprise/data-governance.d.ts +203 -0
- package/dist/types/enterprise/multi-tenancy.d.ts +137 -0
- package/dist/types/enterprise/sso-integration.d.ts +420 -0
- package/dist/types/evaluate/context-metrics.d.ts +55 -0
- package/dist/types/evaluate/faithfulness.d.ts +41 -0
- package/dist/types/evaluate/groundedness.d.ts +60 -0
- package/dist/types/evaluate/pipeline-evaluator.d.ts +88 -0
- package/dist/types/evaluate/relevance.d.ts +21 -0
- package/dist/types/evaluate/scoring.d.ts +123 -0
- package/dist/types/experimental.d.ts +15 -0
- package/dist/types/graph/entity-extractor.d.ts +84 -0
- package/dist/types/graph/graph-index.d.ts +49 -0
- package/dist/types/graph/graph-retriever.d.ts +81 -0
- package/dist/types/graph/knowledge-graph.d.ts +129 -0
- package/dist/types/guardrails/guardrails-pipeline.d.ts +63 -0
- package/dist/types/guardrails/injection-detector.d.ts +47 -0
- package/dist/types/guardrails/post-generation-guard.d.ts +61 -0
- package/dist/types/guardrails/pre-retrieval-guard.d.ts +64 -0
- package/dist/types/guardrails/retrieval-guard.d.ts +57 -0
- package/dist/types/mcp/mcp-server.d.ts +85 -0
- package/dist/types/mcp/mcp-tool-builder.d.ts +55 -0
- package/dist/types/reranker/cascade-reranker.d.ts +40 -0
- package/dist/types/reranker/embedding-reranker.d.ts +77 -0
- package/dist/types/reranker/scoring-reranker.d.ts +41 -0
- package/dist/types/retrieval/bm25-search.d.ts +43 -0
- package/dist/types/retrieval/file-vector-store.d.ts +87 -0
- package/dist/types/retrieval/hybrid-retriever.d.ts +35 -0
- package/dist/types/retrieval/rank-fusion.d.ts +10 -0
- package/dist/types/security/jwt-config.d.ts +80 -0
- package/dist/types/security/jwt-validator.d.ts +195 -0
- package/dist/types/security/plugin-sandbox.d.ts +158 -0
- package/dist/types/security/plugin-signature-verifier.d.ts +139 -0
- package/dist/types/security/validator.d.ts +5 -0
- package/dist/types/streaming/embedding-stream.d.ts +65 -0
- package/dist/types/streaming/sse-adapter.d.ts +59 -0
- package/dist/types/streaming/stream-router.d.ts +88 -0
- package/dist/types/streaming/streaming-embedder.d.ts +99 -0
- package/dist/types/streaming/websocket-adapter.d.ts +71 -0
- package/dist/types/templates/scaffold.d.ts +55 -0
- package/dist/types/templates/template-registry.d.ts +63 -0
- package/dist/types/utils/embed-query.d.ts +20 -0
- package/dist/types/utils/logger.d.ts +50 -0
- package/dist/types/utils/rate-limiter.d.ts +66 -0
- package/dist/types/utils/retry.d.ts +27 -0
- package/dist/types/utils/run-abort.d.ts +34 -0
- package/dist/types/utils/secure-logging.d.ts +51 -0
- package/dist/types/utils/structured-logger.d.ts +126 -0
- package/package.json +53 -29
- package/src/agentic/agentic-pipeline.js +75 -7
- package/src/agentic/iterative-retriever.js +47 -10
- package/src/agentic/query-planner.js +329 -78
- package/src/citation/citation-tracker.js +6 -4
- package/src/citation/hallucination-detector.js +2 -2
- package/src/citation/source-mapper.js +15 -28
- package/src/cli/commands/ai.js +101 -0
- package/src/cli/commands/plugin-hub/event-handlers.js +6 -0
- package/src/cli/commands/plugin-hub/hub-commands.js +0 -74
- package/src/cli/commands/plugin-hub/local-commands.js +143 -0
- package/src/cli/commands/plugin-hub.js +96 -36
- package/src/cli/diagnostics/config-checker.js +76 -63
- package/src/cli/diagnostics/environment-checker.js +62 -31
- package/src/cli/diagnostics/plugin-checker.js +36 -89
- package/src/cli/doctor-command.js +39 -5
- package/src/cli/enhanced-cli-commands.js +72 -217
- package/src/cli/handlers/ai-handler.js +364 -0
- package/src/cli/handlers/diagnostics-handler.js +78 -31
- package/src/cli/handlers/ingest-handler.js +28 -22
- package/src/cli/handlers/init-handler.js +148 -25
- package/src/cli/handlers/query-handler.js +41 -26
- package/src/cli/handlers/run-handler.js +16 -167
- package/src/cli/handlers/serve-handler.js +60 -0
- package/src/cli/services/bench-stats.js +54 -0
- package/src/cli/services/benchmark.js +161 -0
- package/src/cli/services/feedback.js +155 -0
- package/src/cli/services/rag-service.js +322 -0
- package/src/cli/shared/cli-utils.js +24 -7
- package/src/cli/shared/config-context.js +21 -0
- package/src/cli/wizard/config-builder.js +81 -0
- package/src/cli/wizard/init-wizard.js +617 -0
- package/src/config/component-factory.js +125 -0
- package/src/config/load-config.js +29 -10
- package/src/config/load-plugin-config.js +46 -2
- package/src/connectors/anthropic-connector.js +93 -55
- package/src/connectors/base-connector.js +74 -19
- package/src/connectors/cohere-connector.js +88 -32
- package/src/connectors/connector-utils.js +302 -0
- package/src/connectors/local-embedder.js +43 -5
- package/src/connectors/memory-retriever.js +108 -15
- package/src/connectors/ollama-connector.js +83 -49
- package/src/connectors/openai-connector.js +108 -44
- package/src/connectors/rag-prompt.js +88 -0
- package/src/core/create-pipeline.js +209 -60
- package/src/core/plugin-registry.js +87 -11
- package/src/cost/cost-calculator.js +205 -32
- package/src/dev/dev-server.js +166 -11
- package/src/dev/hot-reload.js +40 -1
- package/src/ecosystem/plugin-checks.js +181 -0
- package/src/ecosystem/plugin-hub.js +50 -125
- package/src/ecosystem/plugin-installer.js +298 -0
- package/src/ecosystem/plugin-probe.js +127 -0
- package/src/ecosystem/plugin-scanner.js +185 -0
- package/src/ecosystem/tar-extract.js +114 -0
- package/src/enterprise/audit-logging.js +158 -29
- package/src/enterprise/sso-integration.js +715 -228
- package/src/evaluate/context-metrics.js +28 -16
- package/src/evaluate/evaluator.js +3 -3
- package/src/evaluate/faithfulness.js +18 -14
- package/src/evaluate/groundedness.js +43 -12
- package/src/evaluate/pipeline-evaluator.js +35 -8
- package/src/evaluate/scoring.js +251 -3
- package/src/experimental.js +71 -0
- package/src/guardrails/guardrails-pipeline.js +69 -7
- package/src/guardrails/injection-detector.js +283 -0
- package/src/guardrails/post-generation-guard.js +19 -0
- package/src/guardrails/pre-retrieval-guard.js +36 -36
- package/src/guardrails/retrieval-guard.js +58 -8
- package/src/index.js +36 -1
- package/src/loader/document-reader.js +91 -0
- package/src/reranker/cascade-reranker.js +3 -0
- package/src/reranker/embedding-reranker.js +136 -21
- package/src/reranker/llm-reranker.js +79 -12
- package/src/reranker/scoring-reranker.js +3 -0
- package/src/retrieval/bm25-search.js +12 -6
- package/src/retrieval/file-vector-store.js +212 -0
- package/src/retrieval/hybrid-retriever.js +22 -19
- package/src/security/jwt-config.js +13 -2
- package/src/security/jwt-validator.js +134 -30
- package/src/security/plugin-sandbox.js +18 -1
- package/src/security/plugin-signature-verifier.js +245 -70
- package/src/utils/deprecate.js +69 -0
- package/src/utils/embed-query.js +33 -0
- package/src/utils/input-sanitizer.js +19 -4
- package/src/utils/logger.js +34 -4
- package/src/utils/run-abort.js +102 -0
- package/src/ai/federated-learning.js +0 -211
- package/src/ai/federation.js +0 -71
- package/src/ai/index.js +0 -22
- package/src/ai/model-trainer.js +0 -217
- package/src/ai/model-training.js +0 -202
- package/src/ai/multimodal/multi-modal-processor.js +0 -345
- package/src/ai/orchestrator.js +0 -65
- package/src/ai/retrieval/adaptive-retrieval-engine.js +0 -398
- package/src/cli/commands/ai-ml/adaptive-commands.js +0 -178
- package/src/cli/commands/ai-ml/federated-commands.js +0 -207
- package/src/cli/commands/ai-ml/index.js +0 -17
- package/src/cli/commands/ai-ml/multimodal-commands.js +0 -187
- package/src/cli/commands/ai-ml/shared.js +0 -51
- package/src/cli/commands/ai-ml/training-commands.js +0 -228
- package/src/cli/commands/ai-ml.js +0 -386
- package/src/cli/commands/docs.js +0 -228
- package/src/cli/commands/dx.js +0 -538
- package/src/cli/commands/wizard.js +0 -627
- package/src/cli/input-sanitization-middleware.js +0 -356
- package/src/cli/interactive-wizard.js +0 -373
- package/src/cli/templates/development.template.json +0 -64
- package/src/cli/templates/minimal.template.json +0 -33
- package/src/cli/templates/production.template.json +0 -104
- package/src/cli/templates/testing.template.json +0 -45
- package/src/cli/wizard/configuration.js +0 -148
- package/src/cli/wizard/observability.js +0 -79
- package/src/cli/wizard/performance.js +0 -76
- package/src/cli/wizard/plugin-selection.js +0 -297
- package/src/cli/wizard/preview-save.js +0 -172
- package/src/cli/wizard/project-setup.js +0 -66
- package/src/core/pipeline-factory.js +0 -59
- package/src/dag/enhanced-dag-engine.js +0 -894
- package/src/dx/index.js +0 -40
- package/src/dx/integration-templates.js +0 -662
- package/src/dx/performance-profiler.js +0 -968
- package/src/dx/realtime-debugger.js +0 -755
- package/src/dx/visual-pipeline-builder.js +0 -578
- package/src/ingest.js +0 -59
- package/src/pipeline/pipeline.js +0 -18
- package/src/query.js +0 -117
|
@@ -1,398 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adaptive Retrieval Engine - Extracted from monolithic AI module
|
|
3
|
-
* Handles personalized content retrieval and user profile management
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { EventEmitter } = require("events");
|
|
7
|
-
const crypto = require("crypto");
|
|
8
|
-
|
|
9
|
-
class AdaptiveRetrievalEngine extends EventEmitter {
|
|
10
|
-
constructor(options = {}) {
|
|
11
|
-
super();
|
|
12
|
-
this.config = {
|
|
13
|
-
learning: {
|
|
14
|
-
algorithm: options.algorithm || "contextual_bandit",
|
|
15
|
-
explorationRate: options.explorationRate || 0.1,
|
|
16
|
-
learningRate: options.learningRate || 0.01,
|
|
17
|
-
},
|
|
18
|
-
...options,
|
|
19
|
-
};
|
|
20
|
-
this.userProfiles = new Map();
|
|
21
|
-
this.queryHistory = new Map();
|
|
22
|
-
this.feedbackHistory = [];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async initializeUserProfile(userId, preferences = {}) {
|
|
26
|
-
const profile = {
|
|
27
|
-
userId,
|
|
28
|
-
interests: preferences.interests || [],
|
|
29
|
-
preferences: preferences,
|
|
30
|
-
expertise: preferences.expertise || "beginner",
|
|
31
|
-
createdAt: Date.now(),
|
|
32
|
-
interactions: 0,
|
|
33
|
-
personalizedRankings: new Map(),
|
|
34
|
-
learningHistory: [],
|
|
35
|
-
adaptationWeights: {
|
|
36
|
-
contentSimilarity: 0.4,
|
|
37
|
-
userPreference: 0.3,
|
|
38
|
-
contextualRelevance: 0.2,
|
|
39
|
-
temporalDecay: 0.1,
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
this.userProfiles.set(userId, profile);
|
|
44
|
-
this.emit("userProfileInitialized", { userId, profile });
|
|
45
|
-
return profile;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async getUserProfile(userId) {
|
|
49
|
-
const profile = this.userProfiles.get(userId);
|
|
50
|
-
if (!profile) {
|
|
51
|
-
throw new Error(`User profile not found for ${userId}`);
|
|
52
|
-
}
|
|
53
|
-
return profile;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async adaptiveRetrieve(userId, query, options = {}) {
|
|
57
|
-
const profile = this.userProfiles.get(userId);
|
|
58
|
-
if (!profile) {
|
|
59
|
-
throw new Error(
|
|
60
|
-
`User profile not found for ${userId}. Please initialize profile first.`,
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const maxResults = options.maxResults || 10;
|
|
65
|
-
|
|
66
|
-
// Simulate document retrieval with adaptive ranking
|
|
67
|
-
const baseDocuments = Array.from({ length: maxResults }, (_, i) => ({
|
|
68
|
-
id: `doc_${i + 1}`,
|
|
69
|
-
title: `Document ${i + 1} about ${query}`,
|
|
70
|
-
content: `Content related to ${query} with relevance score`,
|
|
71
|
-
baseScore: 0.9 - i * 0.1,
|
|
72
|
-
metadata: {
|
|
73
|
-
source: "knowledge_base",
|
|
74
|
-
timestamp: Date.now() - Math.random() * 86400000,
|
|
75
|
-
tags: profile.interests.slice(0, 2),
|
|
76
|
-
},
|
|
77
|
-
}));
|
|
78
|
-
|
|
79
|
-
// Apply adaptive ranking based on user profile
|
|
80
|
-
const adaptedDocuments = baseDocuments
|
|
81
|
-
.map((doc) => {
|
|
82
|
-
const adaptiveScore = this._calculateAdaptiveScore(doc, profile, query);
|
|
83
|
-
return {
|
|
84
|
-
...doc,
|
|
85
|
-
adaptiveScore,
|
|
86
|
-
finalScore: doc.baseScore * 0.6 + adaptiveScore * 0.4,
|
|
87
|
-
adaptationFactors: {
|
|
88
|
-
userInterests: profile.interests.some((interest) =>
|
|
89
|
-
doc.title.toLowerCase().includes(interest.toLowerCase()),
|
|
90
|
-
)
|
|
91
|
-
? 0.2
|
|
92
|
-
: 0,
|
|
93
|
-
expertise: profile.expertise === "advanced" ? 0.1 : 0,
|
|
94
|
-
historicalPreference: Math.random() * 0.1,
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
})
|
|
98
|
-
.sort((a, b) => b.finalScore - a.finalScore);
|
|
99
|
-
|
|
100
|
-
const result = {
|
|
101
|
-
documents: adaptedDocuments,
|
|
102
|
-
adaptationMetadata: {
|
|
103
|
-
userId,
|
|
104
|
-
query,
|
|
105
|
-
adaptationStrategy: this.config.learning.algorithm,
|
|
106
|
-
profileFactors: {
|
|
107
|
-
interests: profile.interests,
|
|
108
|
-
expertise: profile.expertise,
|
|
109
|
-
interactionCount: profile.interactions,
|
|
110
|
-
},
|
|
111
|
-
retrievalTimestamp: Date.now(),
|
|
112
|
-
},
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// Update interaction count
|
|
116
|
-
profile.interactions++;
|
|
117
|
-
|
|
118
|
-
this.emit("adaptiveRetrievalCompleted", {
|
|
119
|
-
userId,
|
|
120
|
-
query,
|
|
121
|
-
resultsCount: adaptedDocuments.length,
|
|
122
|
-
adaptationApplied: true,
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
return result;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async processFeedback(userId, feedback) {
|
|
129
|
-
const profile = this.userProfiles.get(userId);
|
|
130
|
-
if (!profile) {
|
|
131
|
-
throw new Error(`User profile not found for ${userId}`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// Store feedback in learning history
|
|
135
|
-
const feedbackEntry = {
|
|
136
|
-
id: crypto.randomUUID(),
|
|
137
|
-
timestamp: Date.now(),
|
|
138
|
-
query: feedback.query,
|
|
139
|
-
results: feedback.results,
|
|
140
|
-
ratings: feedback.ratings || [],
|
|
141
|
-
clickedResults: feedback.clickedResults || [],
|
|
142
|
-
dwellTime: feedback.dwellTime || [],
|
|
143
|
-
feedbackType: "explicit",
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
profile.learningHistory.push(feedbackEntry);
|
|
147
|
-
|
|
148
|
-
// Initialize preferences.queryPatterns if not exists
|
|
149
|
-
if (!profile.preferences.queryPatterns) {
|
|
150
|
-
profile.preferences.queryPatterns = [];
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Update query patterns based on feedback
|
|
154
|
-
if (feedback.query) {
|
|
155
|
-
const existingPattern = profile.preferences.queryPatterns.find(
|
|
156
|
-
(p) => p.query === feedback.query,
|
|
157
|
-
);
|
|
158
|
-
if (existingPattern) {
|
|
159
|
-
existingPattern.frequency++;
|
|
160
|
-
existingPattern.lastUsed = Date.now();
|
|
161
|
-
if (feedback.ratings && feedback.ratings.length > 0) {
|
|
162
|
-
const avgRating =
|
|
163
|
-
feedback.ratings.reduce((sum, rating) => sum + rating, 0) /
|
|
164
|
-
feedback.ratings.length;
|
|
165
|
-
existingPattern.avgRating =
|
|
166
|
-
(existingPattern.avgRating + avgRating) / 2;
|
|
167
|
-
}
|
|
168
|
-
} else {
|
|
169
|
-
const avgRating =
|
|
170
|
-
feedback.ratings && feedback.ratings.length > 0
|
|
171
|
-
? feedback.ratings.reduce((sum, rating) => sum + rating, 0) /
|
|
172
|
-
feedback.ratings.length
|
|
173
|
-
: 3;
|
|
174
|
-
profile.preferences.queryPatterns.push({
|
|
175
|
-
query: feedback.query,
|
|
176
|
-
frequency: 1,
|
|
177
|
-
avgRating,
|
|
178
|
-
lastUsed: Date.now(),
|
|
179
|
-
category: this._categorizeQuery(feedback.query),
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Update user preferences based on feedback
|
|
185
|
-
if (feedback.ratings && feedback.ratings.length > 0) {
|
|
186
|
-
const avgRating =
|
|
187
|
-
feedback.ratings.reduce((sum, rating) => sum + rating, 0) /
|
|
188
|
-
feedback.ratings.length;
|
|
189
|
-
|
|
190
|
-
// Extract topics from highly rated results
|
|
191
|
-
if (avgRating >= 4) {
|
|
192
|
-
feedback.results.forEach((result, index) => {
|
|
193
|
-
if (feedback.ratings[index] >= 4) {
|
|
194
|
-
// Extract keywords and add to interests if not already present
|
|
195
|
-
const keywords = result.title.toLowerCase().split(" ");
|
|
196
|
-
keywords.forEach((keyword) => {
|
|
197
|
-
if (keyword.length > 3 && !profile.interests.includes(keyword)) {
|
|
198
|
-
profile.interests.push(keyword);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Update adaptation weights based on feedback patterns
|
|
207
|
-
this._updateAdaptationWeights(profile, feedbackEntry);
|
|
208
|
-
|
|
209
|
-
this.emit("feedbackProcessed", {
|
|
210
|
-
userId,
|
|
211
|
-
feedbackId: feedbackEntry.id,
|
|
212
|
-
learningHistorySize: profile.learningHistory.length,
|
|
213
|
-
updatedInterests: profile.interests,
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
return {
|
|
217
|
-
processed: true,
|
|
218
|
-
feedbackId: feedbackEntry.id,
|
|
219
|
-
profileUpdated: true,
|
|
220
|
-
newInterestsCount: profile.interests.length,
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
async generatePersonalizedRankings(userId, results, context = {}) {
|
|
225
|
-
const profile = this.userProfiles.get(userId);
|
|
226
|
-
if (!profile) {
|
|
227
|
-
throw new Error(`User profile not found for ${userId}`);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Simulate personalized ranking based on user interests
|
|
231
|
-
const rankedResults = results
|
|
232
|
-
.map((result) => ({
|
|
233
|
-
...result,
|
|
234
|
-
personalizedScore: Math.random() * 0.5 + 0.5,
|
|
235
|
-
relevanceFactors: profile.interests.slice(0, 2),
|
|
236
|
-
}))
|
|
237
|
-
.sort((a, b) => b.personalizedScore - a.personalizedScore);
|
|
238
|
-
|
|
239
|
-
this.emit("personalizedRankingsGenerated", {
|
|
240
|
-
userId,
|
|
241
|
-
resultsCount: rankedResults.length,
|
|
242
|
-
});
|
|
243
|
-
return rankedResults;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
async personalizeRanking(userId, documents, context = {}) {
|
|
247
|
-
const profile = this.userProfiles.get(userId);
|
|
248
|
-
if (!profile) {
|
|
249
|
-
throw new Error(`User profile not found for ${userId}`);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
// Apply personalized ranking to documents
|
|
253
|
-
const personalizedResults = documents
|
|
254
|
-
.map((doc) => {
|
|
255
|
-
let personalizedScore = doc.score || 0.5;
|
|
256
|
-
const rankingFactors = {
|
|
257
|
-
contentRelevance: 0,
|
|
258
|
-
userInterests: 0,
|
|
259
|
-
historicalPreference: 0,
|
|
260
|
-
contextualMatch: 0,
|
|
261
|
-
};
|
|
262
|
-
|
|
263
|
-
// Boost score based on user interests
|
|
264
|
-
if (profile.interests && profile.interests.length > 0) {
|
|
265
|
-
const interestMatch = profile.interests.some((interest) =>
|
|
266
|
-
doc.content.toLowerCase().includes(interest.toLowerCase()),
|
|
267
|
-
);
|
|
268
|
-
if (interestMatch) {
|
|
269
|
-
rankingFactors.userInterests = 0.2;
|
|
270
|
-
personalizedScore += 0.2;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// Apply historical preferences
|
|
275
|
-
if (profile.learningHistory && profile.learningHistory.length > 0) {
|
|
276
|
-
rankingFactors.historicalPreference = Math.random() * 0.1;
|
|
277
|
-
personalizedScore += rankingFactors.historicalPreference;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// Contextual matching with query
|
|
281
|
-
if (context.query) {
|
|
282
|
-
const queryWords = context.query.toLowerCase().split(" ");
|
|
283
|
-
const contentWords = doc.content.toLowerCase().split(" ");
|
|
284
|
-
const overlap = queryWords.filter((word) =>
|
|
285
|
-
contentWords.includes(word),
|
|
286
|
-
).length;
|
|
287
|
-
rankingFactors.contextualMatch = (overlap / queryWords.length) * 0.15;
|
|
288
|
-
personalizedScore += rankingFactors.contextualMatch;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
rankingFactors.contentRelevance = doc.score || 0.5;
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
...doc,
|
|
295
|
-
personalizedScore: Math.min(personalizedScore, 1.0),
|
|
296
|
-
rankingFactors,
|
|
297
|
-
};
|
|
298
|
-
})
|
|
299
|
-
.sort((a, b) => b.personalizedScore - a.personalizedScore);
|
|
300
|
-
|
|
301
|
-
this.emit("personalizedRankingCompleted", {
|
|
302
|
-
userId,
|
|
303
|
-
documentsCount: documents.length,
|
|
304
|
-
query: context.query,
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
return personalizedResults;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
async optimizeRetrieval(query, context = {}) {
|
|
311
|
-
const optimizedQuery = `optimized: ${query}`;
|
|
312
|
-
const retrievalStrategy = "adaptive";
|
|
313
|
-
|
|
314
|
-
this.emit("retrievalOptimized", {
|
|
315
|
-
originalQuery: query,
|
|
316
|
-
optimizedQuery,
|
|
317
|
-
strategy: retrievalStrategy,
|
|
318
|
-
context,
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
return {
|
|
322
|
-
query: optimizedQuery,
|
|
323
|
-
strategy: retrievalStrategy,
|
|
324
|
-
confidence: Math.random() * 0.3 + 0.7,
|
|
325
|
-
};
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
_categorizeQuery(query) {
|
|
329
|
-
const lowerQuery = query.toLowerCase();
|
|
330
|
-
if (lowerQuery.includes("machine learning") || lowerQuery.includes("ml"))
|
|
331
|
-
return "machine_learning";
|
|
332
|
-
if (lowerQuery.includes("deep learning") || lowerQuery.includes("neural"))
|
|
333
|
-
return "deep_learning";
|
|
334
|
-
if (
|
|
335
|
-
lowerQuery.includes("ai") ||
|
|
336
|
-
lowerQuery.includes("artificial intelligence")
|
|
337
|
-
)
|
|
338
|
-
return "artificial_intelligence";
|
|
339
|
-
if (lowerQuery.includes("data") || lowerQuery.includes("analytics"))
|
|
340
|
-
return "data_science";
|
|
341
|
-
return "general";
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
_calculateAdaptiveScore(document, profile, query) {
|
|
345
|
-
let score = 0;
|
|
346
|
-
|
|
347
|
-
// Interest matching
|
|
348
|
-
const interestMatch = profile.interests.some(
|
|
349
|
-
(interest) =>
|
|
350
|
-
document.title.toLowerCase().includes(interest.toLowerCase()) ||
|
|
351
|
-
document.content.toLowerCase().includes(interest.toLowerCase()),
|
|
352
|
-
);
|
|
353
|
-
if (interestMatch) score += 0.3;
|
|
354
|
-
|
|
355
|
-
// Expertise level matching
|
|
356
|
-
if (
|
|
357
|
-
profile.expertise === "advanced" &&
|
|
358
|
-
document.metadata.tags.includes("advanced")
|
|
359
|
-
) {
|
|
360
|
-
score += 0.2;
|
|
361
|
-
} else if (
|
|
362
|
-
profile.expertise === "beginner" &&
|
|
363
|
-
document.metadata.tags.includes("basic")
|
|
364
|
-
) {
|
|
365
|
-
score += 0.2;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
// Historical preference (simplified)
|
|
369
|
-
score += Math.random() * 0.2;
|
|
370
|
-
|
|
371
|
-
return Math.min(score, 1.0);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
_updateAdaptationWeights(profile, feedbackEntry) {
|
|
375
|
-
// Simple learning rate adjustment based on feedback quality
|
|
376
|
-
const avgRating =
|
|
377
|
-
feedbackEntry.ratings.length > 0
|
|
378
|
-
? feedbackEntry.ratings.reduce((sum, r) => sum + r, 0) /
|
|
379
|
-
feedbackEntry.ratings.length
|
|
380
|
-
: 3;
|
|
381
|
-
|
|
382
|
-
if (avgRating >= 4) {
|
|
383
|
-
// Positive feedback - slightly increase user preference weight
|
|
384
|
-
profile.adaptationWeights.userPreference = Math.min(
|
|
385
|
-
0.5,
|
|
386
|
-
profile.adaptationWeights.userPreference + 0.01,
|
|
387
|
-
);
|
|
388
|
-
} else if (avgRating <= 2) {
|
|
389
|
-
// Negative feedback - increase content similarity weight
|
|
390
|
-
profile.adaptationWeights.contentSimilarity = Math.min(
|
|
391
|
-
0.6,
|
|
392
|
-
profile.adaptationWeights.contentSimilarity + 0.01,
|
|
393
|
-
);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
module.exports = { AdaptiveRetrievalEngine };
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Adaptive retrieval CLI commands
|
|
3
|
-
* Handles user profiles, adaptive search, and feedback processing
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const chalk = require("chalk");
|
|
7
|
-
const ora = require("ora");
|
|
8
|
-
const inquirer = require("inquirer");
|
|
9
|
-
const Table = require("cli-table3");
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Manage user profile (view or create)
|
|
13
|
-
* @param {AdaptiveRetrievalEngine} adaptiveRetrieval - The adaptive retrieval engine instance
|
|
14
|
-
* @param {string} userId - User ID
|
|
15
|
-
* @param {object} _options - Command options
|
|
16
|
-
*/
|
|
17
|
-
async function manageUserProfile(adaptiveRetrieval, userId, _options) {
|
|
18
|
-
const spinner = ora("Managing user profile...").start();
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
let profile;
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
profile = await adaptiveRetrieval.getUserProfile(userId);
|
|
25
|
-
spinner.succeed("User profile found");
|
|
26
|
-
} catch {
|
|
27
|
-
// Profile doesn't exist, create new one
|
|
28
|
-
const profileData = {};
|
|
29
|
-
|
|
30
|
-
if (_options.interests) {
|
|
31
|
-
profileData.interests = _options.interests
|
|
32
|
-
.split(",")
|
|
33
|
-
.map((i) => i.trim());
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (_options.expertise) {
|
|
37
|
-
profileData.expertise = _options.expertise;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
profile = await adaptiveRetrieval.initializeUserProfile(
|
|
41
|
-
userId,
|
|
42
|
-
profileData,
|
|
43
|
-
);
|
|
44
|
-
spinner.succeed("User profile created");
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const table = new Table({
|
|
48
|
-
head: ["Property", "Value"],
|
|
49
|
-
colWidths: [20, 50],
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
table.push(
|
|
53
|
-
["User ID", profile.userId],
|
|
54
|
-
["Interests", profile.preferences?.interests?.join(", ") || "None"],
|
|
55
|
-
["Expertise", profile.preferences?.expertise || "Not set"],
|
|
56
|
-
[
|
|
57
|
-
"Learning History",
|
|
58
|
-
`${profile.learningHistory?.length || 0} interactions`,
|
|
59
|
-
],
|
|
60
|
-
["Created", profile.createdAt || "Unknown"],
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
console.log(table.toString());
|
|
64
|
-
// eslint-disable-line no-console
|
|
65
|
-
} catch (error) {
|
|
66
|
-
spinner.fail(`Profile management failed: ${error.message}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Perform adaptive search
|
|
72
|
-
* @param {AdaptiveRetrievalEngine} adaptiveRetrieval - The adaptive retrieval engine instance
|
|
73
|
-
* @param {string} userId - User ID
|
|
74
|
-
* @param {string} query - Search query
|
|
75
|
-
* @param {object} _options - Command options
|
|
76
|
-
*/
|
|
77
|
-
async function adaptiveSearch(adaptiveRetrieval, userId, query, _options) {
|
|
78
|
-
const spinner = ora("Performing adaptive search...").start();
|
|
79
|
-
|
|
80
|
-
try {
|
|
81
|
-
const searchOptions = {
|
|
82
|
-
maxResults: parseInt(_options.maxResults),
|
|
83
|
-
explain: !!_options.explain,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const results = await adaptiveRetrieval.adaptiveRetrieve(
|
|
87
|
-
userId,
|
|
88
|
-
query,
|
|
89
|
-
searchOptions,
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
spinner.succeed(`Found ${results.documents.length} results`);
|
|
93
|
-
|
|
94
|
-
// Display results
|
|
95
|
-
console.log(chalk.blue(`\nSearch Results for: "${query}"`));
|
|
96
|
-
// eslint-disable-line no-console
|
|
97
|
-
console.log(chalk.gray("=".repeat(50)));
|
|
98
|
-
// eslint-disable-line no-console
|
|
99
|
-
|
|
100
|
-
results.documents.forEach((doc, index) => {
|
|
101
|
-
console.log(chalk.green(`\n${index + 1}. ${doc.title || doc.id}`));
|
|
102
|
-
// eslint-disable-line no-console
|
|
103
|
-
console.log(chalk.gray(` Score: ${doc.score?.toFixed(4) || "N/A"}`));
|
|
104
|
-
// eslint-disable-line no-console
|
|
105
|
-
console.log(
|
|
106
|
-
chalk.gray(
|
|
107
|
-
` Personalized Score: ${doc.personalizedScore?.toFixed(4) || "N/A"}`,
|
|
108
|
-
),
|
|
109
|
-
);
|
|
110
|
-
// eslint-disable-line no-console
|
|
111
|
-
console.log(` ${doc.content?.substring(0, 200)}...`);
|
|
112
|
-
// eslint-disable-line no-console
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
if (_options.explain && results.adaptationMetadata) {
|
|
116
|
-
console.log(chalk.blue("\nAdaptation Explanation:"));
|
|
117
|
-
// eslint-disable-line no-console
|
|
118
|
-
console.log(
|
|
119
|
-
chalk.gray(JSON.stringify(results.adaptationMetadata, null, 2)),
|
|
120
|
-
);
|
|
121
|
-
// eslint-disable-line no-console
|
|
122
|
-
}
|
|
123
|
-
} catch (error) {
|
|
124
|
-
spinner.fail(`Adaptive search failed: ${error.message}`);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Provide feedback for learning
|
|
130
|
-
* @param {AdaptiveRetrievalEngine} adaptiveRetrieval - The adaptive retrieval engine instance
|
|
131
|
-
* @param {string} userId - User ID
|
|
132
|
-
* @param {object} _options - Command options
|
|
133
|
-
*/
|
|
134
|
-
async function provideFeedback(adaptiveRetrieval, userId, _options) {
|
|
135
|
-
if (!_options.query) {
|
|
136
|
-
const answers = await inquirer.prompt([
|
|
137
|
-
{
|
|
138
|
-
_type: "input",
|
|
139
|
-
name: "query",
|
|
140
|
-
message: "Enter the original query:",
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
_type: "input",
|
|
144
|
-
name: "ratings",
|
|
145
|
-
message: "Enter ratings for results (comma-separated, 1-5):",
|
|
146
|
-
},
|
|
147
|
-
]);
|
|
148
|
-
_options.query = answers.query;
|
|
149
|
-
_options.ratings = answers.ratings;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const spinner = ora("Processing feedback...").start();
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
const ratings = _options.ratings.split(",").map((r) => parseInt(r.trim()));
|
|
156
|
-
|
|
157
|
-
const feedback = {
|
|
158
|
-
query: _options.query,
|
|
159
|
-
ratings,
|
|
160
|
-
clickedResults: [0], // Assume first result was clicked
|
|
161
|
-
dwellTime: [120], // Assume 2 minutes dwell time
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
await adaptiveRetrieval.processFeedback(userId, feedback);
|
|
165
|
-
|
|
166
|
-
spinner.succeed("Feedback processed successfully");
|
|
167
|
-
console.log(chalk.green("\n✓ User profile updated with feedback"));
|
|
168
|
-
// eslint-disable-line no-console
|
|
169
|
-
} catch (error) {
|
|
170
|
-
spinner.fail(`Feedback processing failed: ${error.message}`);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
module.exports = {
|
|
175
|
-
manageUserProfile,
|
|
176
|
-
adaptiveSearch,
|
|
177
|
-
provideFeedback,
|
|
178
|
-
};
|