@devilsdev/rag-pipeline-utils 2.4.5 → 2.6.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.
Files changed (258) hide show
  1. package/.ragrc.schema.json +83 -192
  2. package/CHANGELOG.md +431 -0
  3. package/README.md +418 -117
  4. package/SECURITY.md +5 -5
  5. package/dist/experimental.cjs +2 -0
  6. package/dist/experimental.d.ts +1 -0
  7. package/dist/experimental.mjs +5 -0
  8. package/dist/index.cjs +6442 -1355
  9. package/dist/index.d.ts +129 -2
  10. package/dist/index.mjs +1 -1
  11. package/dist/testing.cjs +2 -0
  12. package/dist/testing.d.ts +1 -0
  13. package/dist/testing.mjs +5 -0
  14. package/dist/types/adapters/ai-sdk.d.ts +53 -0
  15. package/dist/types/agentic/agentic-pipeline.d.ts +103 -0
  16. package/dist/types/agentic/iterative-retriever.d.ts +85 -0
  17. package/dist/types/agentic/query-planner.d.ts +145 -0
  18. package/dist/types/agentic/self-critique.d.ts +45 -0
  19. package/dist/types/ai/adaptive-retrieval.d.ts +44 -0
  20. package/dist/types/ai/federation/federated-learning-coordinator.d.ts +62 -0
  21. package/dist/types/ai/multimodal-processing.d.ts +32 -0
  22. package/dist/types/ai/multimodal.d.ts +39 -0
  23. package/dist/types/ai/retrieval-engine.d.ts +37 -0
  24. package/dist/types/ai/training/model-training-orchestrator.d.ts +31 -0
  25. package/dist/types/cache/component-keys.d.ts +7 -0
  26. package/dist/types/cache/memory-cache.d.ts +54 -0
  27. package/dist/types/cache/pipeline-cache.d.ts +66 -0
  28. package/dist/types/cache/redis-cache.d.ts +46 -0
  29. package/dist/types/chunking/chunking-engine.d.ts +70 -0
  30. package/dist/types/chunking/strategies/fixed-size.d.ts +17 -0
  31. package/dist/types/chunking/strategies/recursive.d.ts +20 -0
  32. package/dist/types/chunking/strategies/semantic.d.ts +19 -0
  33. package/dist/types/chunking/strategies/sentence.d.ts +13 -0
  34. package/dist/types/chunking/strategies/structure-aware.d.ts +19 -0
  35. package/dist/types/citation/citation-tracker.d.ts +64 -0
  36. package/dist/types/citation/hallucination-detector.d.ts +40 -0
  37. package/dist/types/citation/source-mapper.d.ts +37 -0
  38. package/dist/types/connectors/anthropic-connector.d.ts +97 -0
  39. package/dist/types/connectors/base-connector.d.ts +87 -0
  40. package/dist/types/connectors/cohere-connector.d.ts +94 -0
  41. package/dist/types/connectors/connector-utils.d.ts +110 -0
  42. package/dist/types/connectors/local-embedder.d.ts +95 -0
  43. package/dist/types/connectors/memory-retriever.d.ts +99 -0
  44. package/dist/types/connectors/ollama-connector.d.ts +115 -0
  45. package/dist/types/connectors/openai-connector.d.ts +129 -0
  46. package/dist/types/connectors/rag-prompt.d.ts +40 -0
  47. package/dist/types/core/create-pipeline.d.ts +8 -0
  48. package/dist/types/core/plugin-registry.d.ts +136 -0
  49. package/dist/types/core/stage-contracts.d.ts +36 -0
  50. package/dist/types/core/validate-plugin.d.ts +45 -0
  51. package/dist/types/cost/cost-calculator.d.ts +152 -0
  52. package/dist/types/cost/cost-tracker.d.ts +126 -0
  53. package/dist/types/cost/token-budget.d.ts +110 -0
  54. package/dist/types/dag/core/error-context.d.ts +239 -0
  55. package/dist/types/dag/core/execution-scheduler.d.ts +191 -0
  56. package/dist/types/dag/core/topology-validation.d.ts +226 -0
  57. package/dist/types/dag/dag-engine.d.ts +156 -0
  58. package/dist/types/dag/dag-node.d.ts +37 -0
  59. package/dist/types/dashboard/dashboard-generator.d.ts +127 -0
  60. package/dist/types/dashboard/metrics-aggregator.d.ts +218 -0
  61. package/dist/types/debug/execution-tracer.d.ts +57 -0
  62. package/dist/types/debug/trace-inspector.d.ts +31 -0
  63. package/dist/types/ecosystem/plugin-certification.d.ts +169 -0
  64. package/dist/types/enterprise/data-governance.d.ts +203 -0
  65. package/dist/types/enterprise/multi-tenancy.d.ts +137 -0
  66. package/dist/types/enterprise/sso-integration.d.ts +420 -0
  67. package/dist/types/evaluate/context-metrics.d.ts +55 -0
  68. package/dist/types/evaluate/faithfulness.d.ts +41 -0
  69. package/dist/types/evaluate/groundedness.d.ts +60 -0
  70. package/dist/types/evaluate/pipeline-evaluator.d.ts +88 -0
  71. package/dist/types/evaluate/relevance.d.ts +21 -0
  72. package/dist/types/evaluate/scoring.d.ts +123 -0
  73. package/dist/types/evaluate/semantic-similarity.d.ts +14 -0
  74. package/dist/types/experimental.d.ts +15 -0
  75. package/dist/types/graph/entity-extractor.d.ts +84 -0
  76. package/dist/types/graph/graph-index.d.ts +49 -0
  77. package/dist/types/graph/graph-retriever.d.ts +81 -0
  78. package/dist/types/graph/knowledge-graph.d.ts +129 -0
  79. package/dist/types/grounding/check-answer.d.ts +101 -0
  80. package/dist/types/guardrails/guardrails-pipeline.d.ts +63 -0
  81. package/dist/types/guardrails/injection-detector.d.ts +47 -0
  82. package/dist/types/guardrails/post-generation-guard.d.ts +61 -0
  83. package/dist/types/guardrails/pre-retrieval-guard.d.ts +64 -0
  84. package/dist/types/guardrails/retrieval-guard.d.ts +57 -0
  85. package/dist/types/mcp/mcp-server.d.ts +85 -0
  86. package/dist/types/mcp/mcp-tool-builder.d.ts +55 -0
  87. package/dist/types/reranker/cascade-reranker.d.ts +40 -0
  88. package/dist/types/reranker/embedding-reranker.d.ts +77 -0
  89. package/dist/types/reranker/scoring-reranker.d.ts +41 -0
  90. package/dist/types/retrieval/bm25-search.d.ts +43 -0
  91. package/dist/types/retrieval/file-vector-store.d.ts +99 -0
  92. package/dist/types/retrieval/hybrid-retriever.d.ts +35 -0
  93. package/dist/types/retrieval/rank-fusion.d.ts +10 -0
  94. package/dist/types/security/jwt-config.d.ts +80 -0
  95. package/dist/types/security/jwt-validator.d.ts +195 -0
  96. package/dist/types/security/plugin-sandbox.d.ts +158 -0
  97. package/dist/types/security/plugin-signature-verifier.d.ts +139 -0
  98. package/dist/types/security/validator.d.ts +5 -0
  99. package/dist/types/streaming/embedding-stream.d.ts +65 -0
  100. package/dist/types/streaming/sse-adapter.d.ts +59 -0
  101. package/dist/types/streaming/stream-router.d.ts +88 -0
  102. package/dist/types/streaming/streaming-embedder.d.ts +99 -0
  103. package/dist/types/streaming/websocket-adapter.d.ts +71 -0
  104. package/dist/types/templates/scaffold.d.ts +55 -0
  105. package/dist/types/templates/template-registry.d.ts +63 -0
  106. package/dist/types/testing.d.ts +168 -0
  107. package/dist/types/utils/embed-query.d.ts +20 -0
  108. package/dist/types/utils/logger.d.ts +50 -0
  109. package/dist/types/utils/rate-limiter.d.ts +66 -0
  110. package/dist/types/utils/retry.d.ts +27 -0
  111. package/dist/types/utils/run-abort.d.ts +34 -0
  112. package/dist/types/utils/secure-logging.d.ts +51 -0
  113. package/dist/types/utils/structured-logger.d.ts +126 -0
  114. package/package.json +72 -33
  115. package/src/adapters/ai-sdk.js +215 -0
  116. package/src/agentic/agentic-pipeline.js +75 -7
  117. package/src/agentic/iterative-retriever.js +47 -10
  118. package/src/agentic/query-planner.js +329 -78
  119. package/src/cache/component-keys.js +38 -0
  120. package/src/cache/memory-cache.js +87 -0
  121. package/src/cache/pipeline-cache.js +260 -0
  122. package/src/cache/redis-cache.js +83 -0
  123. package/src/citation/citation-tracker.js +6 -4
  124. package/src/citation/hallucination-detector.js +2 -2
  125. package/src/citation/source-mapper.js +15 -28
  126. package/src/cli/commands/ai.js +106 -0
  127. package/src/cli/commands/plugin-hub/event-handlers.js +6 -0
  128. package/src/cli/commands/plugin-hub/hub-commands.js +0 -74
  129. package/src/cli/commands/plugin-hub/local-commands.js +143 -0
  130. package/src/cli/commands/plugin-hub.js +114 -49
  131. package/src/cli/diagnostics/config-checker.js +76 -63
  132. package/src/cli/diagnostics/environment-checker.js +62 -31
  133. package/src/cli/diagnostics/plugin-checker.js +36 -89
  134. package/src/cli/doctor-command.js +39 -5
  135. package/src/cli/enhanced-cli-commands.js +104 -233
  136. package/src/cli/handlers/ai-handler.js +364 -0
  137. package/src/cli/handlers/diagnostics-handler.js +78 -31
  138. package/src/cli/handlers/ingest-handler.js +28 -22
  139. package/src/cli/handlers/init-handler.js +148 -25
  140. package/src/cli/handlers/query-handler.js +203 -25
  141. package/src/cli/handlers/run-handler.js +16 -167
  142. package/src/cli/handlers/serve-handler.js +60 -0
  143. package/src/cli/services/bench-stats.js +54 -0
  144. package/src/cli/services/benchmark.js +161 -0
  145. package/src/cli/services/feedback.js +155 -0
  146. package/src/cli/services/instrument.js +83 -0
  147. package/src/cli/services/rag-service.js +361 -0
  148. package/src/cli/shared/cli-utils.js +24 -7
  149. package/src/cli/shared/config-context.js +21 -0
  150. package/src/cli/wizard/config-builder.js +81 -0
  151. package/src/cli/wizard/init-wizard.js +602 -0
  152. package/src/config/component-factory.js +125 -0
  153. package/src/config/enhanced-ragrc-schema.js +0 -2
  154. package/src/config/load-config.js +29 -10
  155. package/src/config/load-plugin-config.js +46 -2
  156. package/src/config/validate-schema.js +4 -1
  157. package/src/connectors/anthropic-connector.js +115 -57
  158. package/src/connectors/base-connector.js +74 -19
  159. package/src/connectors/cohere-connector.js +108 -34
  160. package/src/connectors/connector-utils.js +302 -0
  161. package/src/connectors/local-embedder.js +63 -5
  162. package/src/connectors/memory-retriever.js +125 -14
  163. package/src/connectors/ollama-connector.js +112 -51
  164. package/src/connectors/openai-connector.js +153 -44
  165. package/src/connectors/rag-prompt.js +88 -0
  166. package/src/core/create-pipeline.js +307 -61
  167. package/src/core/performance/parallel-processor.js +62 -1
  168. package/src/core/plugin-registry.js +125 -26
  169. package/src/core/stage-contracts.js +36 -0
  170. package/src/core/validate-plugin.js +85 -0
  171. package/src/cost/cost-calculator.js +205 -32
  172. package/src/debug/execution-tracer.js +14 -4
  173. package/src/dev/dev-server.js +173 -11
  174. package/src/dev/hot-reload.js +44 -4
  175. package/src/ecosystem/plugin-checks.js +181 -0
  176. package/src/ecosystem/plugin-hub.js +50 -125
  177. package/src/ecosystem/plugin-installer.js +298 -0
  178. package/src/ecosystem/plugin-probe.js +127 -0
  179. package/src/ecosystem/plugin-scanner.js +185 -0
  180. package/src/ecosystem/tar-extract.js +114 -0
  181. package/src/enterprise/audit-logging.js +158 -29
  182. package/src/enterprise/sso-integration.js +716 -228
  183. package/src/evaluate/context-metrics.js +28 -16
  184. package/src/evaluate/evaluator.js +3 -3
  185. package/src/evaluate/faithfulness.js +18 -14
  186. package/src/evaluate/groundedness.js +43 -12
  187. package/src/evaluate/pipeline-evaluator.js +35 -8
  188. package/src/evaluate/scoring.js +251 -3
  189. package/src/evaluate/semantic-similarity.js +79 -0
  190. package/src/experimental.js +71 -0
  191. package/src/grounding/check-answer.js +173 -0
  192. package/src/guardrails/guardrails-pipeline.js +69 -7
  193. package/src/guardrails/injection-detector.js +283 -0
  194. package/src/guardrails/post-generation-guard.js +19 -0
  195. package/src/guardrails/pre-retrieval-guard.js +36 -36
  196. package/src/guardrails/retrieval-guard.js +58 -8
  197. package/src/index.js +58 -1
  198. package/src/loader/csv-loader.js +3 -2
  199. package/src/loader/document-reader.js +91 -0
  200. package/src/loader/html-loader.js +3 -1
  201. package/src/loader/markdown-loader.js +3 -2
  202. package/src/reranker/cascade-reranker.js +3 -0
  203. package/src/reranker/embedding-reranker.js +136 -21
  204. package/src/reranker/llm-reranker.js +79 -12
  205. package/src/reranker/scoring-reranker.js +3 -0
  206. package/src/retrieval/bm25-search.js +12 -6
  207. package/src/retrieval/file-vector-store.js +241 -0
  208. package/src/retrieval/hybrid-retriever.js +22 -19
  209. package/src/security/jwt-config.js +13 -2
  210. package/src/security/jwt-validator.js +139 -34
  211. package/src/security/plugin-sandbox.js +18 -1
  212. package/src/security/plugin-signature-verifier.js +245 -70
  213. package/src/testing.js +254 -0
  214. package/src/utils/deprecate.js +69 -0
  215. package/src/utils/embed-query.js +33 -0
  216. package/src/utils/input-sanitizer.js +19 -4
  217. package/src/utils/logger.js +34 -4
  218. package/src/utils/run-abort.js +102 -0
  219. package/src/ai/federated-learning.js +0 -211
  220. package/src/ai/federation.js +0 -71
  221. package/src/ai/index.js +0 -22
  222. package/src/ai/model-trainer.js +0 -217
  223. package/src/ai/model-training.js +0 -202
  224. package/src/ai/multimodal/multi-modal-processor.js +0 -345
  225. package/src/ai/orchestrator.js +0 -65
  226. package/src/ai/retrieval/adaptive-retrieval-engine.js +0 -398
  227. package/src/cli/commands/ai-ml/adaptive-commands.js +0 -178
  228. package/src/cli/commands/ai-ml/federated-commands.js +0 -207
  229. package/src/cli/commands/ai-ml/index.js +0 -17
  230. package/src/cli/commands/ai-ml/multimodal-commands.js +0 -187
  231. package/src/cli/commands/ai-ml/shared.js +0 -51
  232. package/src/cli/commands/ai-ml/training-commands.js +0 -228
  233. package/src/cli/commands/ai-ml.js +0 -386
  234. package/src/cli/commands/docs.js +0 -228
  235. package/src/cli/commands/dx.js +0 -538
  236. package/src/cli/commands/wizard.js +0 -627
  237. package/src/cli/input-sanitization-middleware.js +0 -356
  238. package/src/cli/interactive-wizard.js +0 -373
  239. package/src/cli/templates/development.template.json +0 -64
  240. package/src/cli/templates/minimal.template.json +0 -33
  241. package/src/cli/templates/production.template.json +0 -104
  242. package/src/cli/templates/testing.template.json +0 -45
  243. package/src/cli/wizard/configuration.js +0 -148
  244. package/src/cli/wizard/observability.js +0 -79
  245. package/src/cli/wizard/performance.js +0 -76
  246. package/src/cli/wizard/plugin-selection.js +0 -297
  247. package/src/cli/wizard/preview-save.js +0 -172
  248. package/src/cli/wizard/project-setup.js +0 -66
  249. package/src/core/pipeline-factory.js +0 -59
  250. package/src/dag/enhanced-dag-engine.js +0 -894
  251. package/src/dx/index.js +0 -40
  252. package/src/dx/integration-templates.js +0 -662
  253. package/src/dx/performance-profiler.js +0 -968
  254. package/src/dx/realtime-debugger.js +0 -755
  255. package/src/dx/visual-pipeline-builder.js +0 -578
  256. package/src/ingest.js +0 -59
  257. package/src/pipeline/pipeline.js +0 -18
  258. package/src/query.js +0 -117
@@ -1,755 +0,0 @@
1
- /**
2
- * Real-time Debugger
3
- *
4
- * Live pipeline inspection and debugging capabilities.
5
- * Provides real-time monitoring, breakpoints, and step-through debugging.
6
- */
7
-
8
- const EventEmitter = require("events");
9
- // eslint-disable-line global-require
10
- const WebSocket = require("ws");
11
- // eslint-disable-line global-require
12
-
13
- class RealtimeDebugger extends EventEmitter {
14
- constructor(_options = {}) {
15
- super();
16
-
17
- this._options = {
18
- port: _options.port || 3002,
19
- enableBreakpoints: _options.enableBreakpoints !== false,
20
- enableStepThrough: _options.enableStepThrough !== false,
21
- enableVariableInspection: _options.enableVariableInspection !== false,
22
- maxHistorySize: _options.maxHistorySize || 1000,
23
- ..._options,
24
- };
25
-
26
- this.sessions = new Map();
27
- this.breakpoints = new Map();
28
- this.executionHistory = [];
29
- this.currentExecution = null;
30
- this.isDebugging = false;
31
- this.wsServer = null;
32
-
33
- this.initializeDebugger();
34
- }
35
-
36
- /**
37
- * Initialize debugger components
38
- */
39
- initializeDebugger() {
40
- this.debuggerState = {
41
- status: "idle",
42
- currentStep: null,
43
- variables: new Map(),
44
- callStack: [],
45
- performance: {
46
- startTime: null,
47
- stepTimes: [],
48
- totalTime: 0,
49
- },
50
- };
51
- }
52
-
53
- /**
54
- * Start debugging session
55
- */
56
- startSession(sessionId, pipelineConfig) {
57
- if (this.sessions.has(sessionId)) {
58
- throw new Error(`Debug session ${sessionId} already exists`);
59
- }
60
-
61
- const session = {
62
- id: sessionId,
63
- pipelineConfig,
64
- status: "active",
65
- startTime: Date.now(),
66
- steps: [],
67
- variables: new Map(),
68
- breakpoints: new Set(),
69
- currentStep: null,
70
- isPaused: false,
71
- };
72
-
73
- this.sessions.set(sessionId, session);
74
- this.emit("sessionStarted", { sessionId, session });
75
-
76
- return session;
77
- }
78
-
79
- /**
80
- * Add breakpoint
81
- */
82
- addBreakpoint(sessionId, componentId, condition = null) {
83
- const session = this.sessions.get(sessionId);
84
- if (!session) {
85
- throw new Error(`Debug session ${sessionId} not found`);
86
- }
87
-
88
- const breakpointId = `bp_${Date.now()}`;
89
- const breakpoint = {
90
- id: breakpointId,
91
- sessionId,
92
- componentId,
93
- condition,
94
- enabled: true,
95
- hitCount: 0,
96
- created: new Date().toISOString(),
97
- };
98
-
99
- this.breakpoints.set(breakpointId, breakpoint);
100
- session.breakpoints.add(breakpointId);
101
-
102
- this.emit("breakpointAdded", { sessionId, breakpointId, breakpoint });
103
- this.broadcastToClients("breakpointAdded", { sessionId, breakpoint });
104
-
105
- return breakpointId;
106
- }
107
-
108
- /**
109
- * Remove breakpoint
110
- */
111
- removeBreakpoint(breakpointId) {
112
- const breakpoint = this.breakpoints.get(breakpointId);
113
- if (!breakpoint) {
114
- throw new Error(`Breakpoint ${breakpointId} not found`);
115
- }
116
-
117
- const session = this.sessions.get(breakpoint.sessionId);
118
- if (session) {
119
- session.breakpoints.delete(breakpointId);
120
- }
121
-
122
- this.breakpoints.delete(breakpointId);
123
-
124
- this.emit("breakpointRemoved", { breakpointId, breakpoint });
125
- this.broadcastToClients("breakpointRemoved", { breakpointId });
126
- }
127
-
128
- /**
129
- * Execute pipeline step with debugging
130
- */
131
- async executeStep(sessionId, componentId, input, context = {}) {
132
- const session = this._validateSession(sessionId);
133
- const step = this._initializeStep(componentId, input, context);
134
-
135
- session.steps.push(step);
136
- session.currentStep = step.id;
137
-
138
- this._notifyStepStarted(sessionId, step);
139
- await this._handleBreakpoints(sessionId, step, componentId, input, context);
140
-
141
- try {
142
- const output = await this._executeStepLogic(
143
- componentId,
144
- input,
145
- context,
146
- step,
147
- );
148
- this._completeStep(step, output);
149
- this._notifyStepCompleted(sessionId, step);
150
- return output;
151
- } catch (error) {
152
- this._handleStepError(step, error);
153
- this._notifyStepError(sessionId, step, error);
154
- throw error;
155
- }
156
- }
157
-
158
- _validateSession(sessionId) {
159
- const session = this.sessions.get(sessionId);
160
- if (!session) {
161
- throw new Error(`Debug session ${sessionId} not found`);
162
- }
163
- return session;
164
- }
165
-
166
- _initializeStep(componentId, input, context) {
167
- const stepId = `step_${Date.now()}`;
168
- return {
169
- id: stepId,
170
- componentId,
171
- input: this.cloneData(input),
172
- context: this.cloneData(context),
173
- startTime: Date.now(),
174
- endTime: null,
175
- output: null,
176
- error: null,
177
- variables: new Map(),
178
- performance: {
179
- duration: 0,
180
- memoryUsage: process.memoryUsage(),
181
- cpuUsage: process.cpuUsage(),
182
- },
183
- };
184
- }
185
-
186
- _notifyStepStarted(sessionId, step) {
187
- this.emit("stepStarted", { sessionId, stepId: step.id, step });
188
- this.broadcastToClients("stepStarted", {
189
- sessionId,
190
- step: this.serializeStep(step),
191
- });
192
- }
193
-
194
- async _handleBreakpoints(sessionId, step, componentId, input, context) {
195
- const shouldBreak = await this.checkBreakpoints(
196
- sessionId,
197
- componentId,
198
- input,
199
- context,
200
- );
201
-
202
- if (shouldBreak) {
203
- const session = this.sessions.get(sessionId);
204
- session.isPaused = true;
205
-
206
- this.emit("breakpointHit", { sessionId, stepId: step.id, componentId });
207
- this.broadcastToClients("breakpointHit", {
208
- sessionId,
209
- stepId: step.id,
210
- componentId,
211
- });
212
-
213
- await this.waitForContinue(sessionId);
214
- }
215
- }
216
-
217
- async _executeStepLogic(componentId, input, context, step) {
218
- return await this.executeComponent(componentId, input, context, step);
219
- }
220
-
221
- _completeStep(step, output) {
222
- step.output = this.cloneData(output);
223
- step.endTime = Date.now();
224
- step.performance.duration = Math.max(step.endTime - step.startTime, 1); // Ensure non-zero duration
225
- step.performance.cpuUsageEnd = process.cpuUsage(step.performance.cpuUsage);
226
- step.performance.memoryUsageEnd = process.memoryUsage();
227
- }
228
-
229
- _notifyStepCompleted(sessionId, step) {
230
- this.emit("stepCompleted", { sessionId, stepId: step.id, step });
231
- this.broadcastToClients("stepCompleted", {
232
- sessionId,
233
- step: this.serializeStep(step),
234
- });
235
- }
236
-
237
- _handleStepError(step, error) {
238
- step.error = {
239
- message: error.message,
240
- stack: error.stack,
241
- name: error.name,
242
- };
243
- step.endTime = Date.now();
244
- step.performance.duration = step.endTime - step.startTime;
245
- }
246
-
247
- _notifyStepError(sessionId, step, error) {
248
- this.emit("stepError", { sessionId, stepId: step.id, step, error });
249
- this.broadcastToClients("stepError", {
250
- sessionId,
251
- step: this.serializeStep(step),
252
- error: step.error,
253
- });
254
- }
255
-
256
- /**
257
- * Execute component with debugging instrumentation
258
- */
259
- async executeComponent(componentId, input, context, step) {
260
- // This would integrate with the actual pipeline components
261
- // For now, we'll simulate component execution
262
-
263
- const startMemory = process.memoryUsage();
264
- const startCpu = process.cpuUsage();
265
-
266
- // Simulate component processing
267
- await new Promise((resolve) =>
268
- setTimeout(resolve, Math.random() * 100 + 50),
269
- );
270
-
271
- // Capture variables and state
272
- step.variables.set("input_size", JSON.stringify(input).length);
273
- step.variables.set("context_keys", Object.keys(context));
274
- step.variables.set("component_id", componentId);
275
- step.variables.set("execution_time", Date.now() - step.startTime);
276
-
277
- // Simulate output based on component type
278
- let output;
279
- switch (componentId.split("_")[0]) {
280
- case "loader":
281
- output = {
282
- documents: [{ id: "1", content: "Sample document", metadata: {} }],
283
- };
284
- break;
285
- case "embedder":
286
- output = { embeddings: [[0.1, 0.2, 0.3, 0.4, 0.5]] };
287
- break;
288
- case "retriever":
289
- output = {
290
- results: [{ score: 0.95, document: { content: "Relevant content" } }],
291
- };
292
- break;
293
- case "llm":
294
- output = { response: "Generated response based on retrieved context" };
295
- break;
296
- default:
297
- output = { processed: true, timestamp: Date.now() };
298
- }
299
-
300
- // Capture performance metrics
301
- const endMemory = process.memoryUsage();
302
- const endCpu = process.cpuUsage(startCpu);
303
-
304
- step.variables.set(
305
- "memory_delta",
306
- endMemory.heapUsed - startMemory.heapUsed,
307
- );
308
- step.variables.set("cpu_user_time", endCpu.user);
309
- step.variables.set("cpu_system_time", endCpu.system);
310
-
311
- return output;
312
- }
313
-
314
- /**
315
- * Check if breakpoints should trigger
316
- */
317
- async checkBreakpoints(sessionId, componentId, input, context) {
318
- const session = this.sessions.get(sessionId);
319
- if (!session || !this._options.enableBreakpoints) {
320
- return false;
321
- }
322
-
323
- for (const breakpointId of session.breakpoints) {
324
- const breakpoint = this.breakpoints.get(breakpointId);
325
- if (!breakpoint || !breakpoint.enabled) {
326
- continue;
327
- }
328
-
329
- if (breakpoint.componentId === componentId) {
330
- // Check condition if specified
331
- if (breakpoint.condition) {
332
- try {
333
- const conditionResult = await this.evaluateCondition(
334
- breakpoint.condition,
335
- input,
336
- context,
337
- );
338
- if (!conditionResult) {
339
- continue;
340
- }
341
- } catch (error) {
342
- this.emit("conditionError", { breakpointId, error: error.message });
343
- continue;
344
- }
345
- }
346
-
347
- breakpoint.hitCount++;
348
- return true;
349
- }
350
- }
351
-
352
- return false;
353
- }
354
-
355
- /**
356
- * Evaluate breakpoint condition safely
357
- */
358
- async evaluateCondition(condition, input, context) {
359
- try {
360
- const {
361
- evaluateExpression,
362
- } = require("../utils/safe-expression-evaluator.js");
363
-
364
- // Create safe context with limited access
365
- const safeContext = {
366
- input: this._createSafeObject(input),
367
- context: this._createSafeObject(context),
368
- };
369
-
370
- return evaluateExpression(condition, safeContext, {
371
- enabled: process.env.NODE_ENV !== "production",
372
- maxExpression: 100,
373
- maxDepth: 3,
374
- });
375
- } catch (error) {
376
- throw new Error(`Invalid condition: ${error.message}`);
377
- }
378
- }
379
-
380
- /**
381
- * Create safe object for evaluation context
382
- * @param {any} obj - Object to make safe
383
- * @returns {object} Safe object with limited properties
384
- */
385
- _createSafeObject(obj) {
386
- if (obj === null || obj === undefined) {
387
- return {};
388
- }
389
-
390
- if (typeof obj !== "object") {
391
- return { value: obj };
392
- }
393
-
394
- if (Array.isArray(obj)) {
395
- return {
396
- length: obj.length,
397
- first: obj[0],
398
- last: obj[obj.length - 1],
399
- };
400
- }
401
-
402
- // Create safe copy of object properties
403
- const safeObj = {};
404
- for (const [key, value] of Object.entries(obj)) {
405
- if (typeof key === "string" && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) {
406
- if (
407
- typeof value === "string" ||
408
- typeof value === "number" ||
409
- typeof value === "boolean"
410
- ) {
411
- safeObj[key] = value;
412
- } else if (Array.isArray(value)) {
413
- safeObj[key] = { length: value.length };
414
- } else if (value && typeof value === "object") {
415
- // Only include safe nested properties (1 level deep)
416
- safeObj[key] = {};
417
- for (const [nestedKey, nestedValue] of Object.entries(value)) {
418
- if (
419
- typeof nestedKey === "string" &&
420
- /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(nestedKey)
421
- ) {
422
- if (
423
- typeof nestedValue === "string" ||
424
- typeof nestedValue === "number" ||
425
- typeof nestedValue === "boolean"
426
- ) {
427
- safeObj[key][nestedKey] = nestedValue;
428
- }
429
- }
430
- }
431
- }
432
- }
433
- }
434
-
435
- return safeObj;
436
- }
437
-
438
- /**
439
- * Wait for user to continue execution
440
- */
441
- async waitForContinue(sessionId) {
442
- return new Promise((resolve) => {
443
- const continueHandler = (data) => {
444
- if (data.sessionId === sessionId && data.action === "continue") {
445
- this.off("debugAction", continueHandler);
446
- resolve();
447
- }
448
- };
449
-
450
- this.on("debugAction", continueHandler);
451
- });
452
- }
453
-
454
- /**
455
- * Continue execution from breakpoint
456
- */
457
- continueExecution(sessionId) {
458
- const session = this.sessions.get(sessionId);
459
- if (!session) {
460
- throw new Error(`Debug session ${sessionId} not found`);
461
- }
462
-
463
- session.isPaused = false;
464
- this.emit("debugAction", { sessionId, action: "continue" });
465
- this.broadcastToClients("executionContinued", { sessionId });
466
- }
467
-
468
- /**
469
- * Step through execution (single step)
470
- */
471
- stepThrough(sessionId) {
472
- const session = this.sessions.get(sessionId);
473
- if (!session) {
474
- throw new Error(`Debug session ${sessionId} not found`);
475
- }
476
-
477
- this.emit("debugAction", { sessionId, action: "step" });
478
- this.broadcastToClients("stepThrough", { sessionId });
479
- }
480
-
481
- /**
482
- * Get variable values at current step
483
- */
484
- getVariables(sessionId, stepId = null) {
485
- const session = this.sessions.get(sessionId);
486
- if (!session) {
487
- throw new Error(`Debug session ${sessionId} not found`);
488
- }
489
-
490
- if (stepId) {
491
- const step = session.steps.find((s) => s.id === stepId);
492
- if (!step) {
493
- throw new Error(`Step ${stepId} not found`);
494
- }
495
- return Object.fromEntries(step.variables);
496
- }
497
-
498
- // Return variables from current step
499
- const currentStep = session.steps[session.steps.length - 1];
500
- return currentStep ? Object.fromEntries(currentStep.variables) : {};
501
- }
502
-
503
- /**
504
- * Get call stack
505
- */
506
- getCallStack(sessionId) {
507
- const session = this.sessions.get(sessionId);
508
- if (!session) {
509
- throw new Error(`Debug session ${sessionId} not found`);
510
- }
511
-
512
- return session.steps.map((step) => ({
513
- stepId: step.id,
514
- componentId: step.componentId,
515
- startTime: step.startTime,
516
- duration: step.performance.duration,
517
- status: step.error ? "error" : "completed",
518
- }));
519
- }
520
-
521
- /**
522
- * Get execution timeline
523
- */
524
- getExecutionTimeline(sessionId) {
525
- const session = this.sessions.get(sessionId);
526
- if (!session) {
527
- throw new Error(`Debug session ${sessionId} not found`);
528
- }
529
-
530
- return {
531
- sessionId,
532
- startTime: session.startTime,
533
- totalSteps: session.steps.length,
534
- totalDuration: session.steps.reduce(
535
- (sum, step) => sum + (step.performance.duration || 0),
536
- 0,
537
- ),
538
- steps: session.steps.map((step) => ({
539
- id: step.id,
540
- componentId: step.componentId,
541
- startTime: step.startTime,
542
- duration: step.performance.duration,
543
- status: step.error ? "error" : "completed",
544
- hasBreakpoint: Array.from(session.breakpoints).some((bpId) => {
545
- const bp = this.breakpoints.get(bpId);
546
- return bp && bp.componentId === step.componentId;
547
- }),
548
- })),
549
- };
550
- }
551
-
552
- /**
553
- * Start WebSocket server for real-time communication
554
- */
555
- startWebSocketServer() {
556
- if (this.wsServer) {
557
- throw new Error("WebSocket server is already running");
558
- }
559
-
560
- this.wsServer = new WebSocket.Server({ port: this._options.port });
561
-
562
- this.wsServer.on("connection", (ws) => {
563
- const clientId = `client_${Date.now()}`;
564
-
565
- ws.on("message", (message) => {
566
- try {
567
- const data = JSON.parse(message);
568
- this.handleClientMessage(clientId, data, ws);
569
- } catch (error) {
570
- ws.send(JSON.stringify({ error: "Invalid message format" }));
571
- }
572
- });
573
-
574
- ws.on("close", () => {
575
- this.emit("clientDisconnected", { clientId });
576
- });
577
-
578
- this.emit("clientConnected", { clientId });
579
- ws.send(JSON.stringify({ _type: "connected", clientId }));
580
- });
581
-
582
- this.emit("webSocketServerStarted", { port: this._options.port });
583
- }
584
-
585
- /**
586
- * Handle client messages
587
- */
588
- handleClientMessage(clientId, data, ws) {
589
- switch (data._type) {
590
- case "addBreakpoint":
591
- try {
592
- const breakpointId = this.addBreakpoint(
593
- data.sessionId,
594
- data.componentId,
595
- data.condition,
596
- );
597
- ws.send(JSON.stringify({ _type: "breakpointAdded", breakpointId }));
598
- } catch (error) {
599
- ws.send(JSON.stringify({ _type: "error", message: error.message }));
600
- }
601
- break;
602
-
603
- case "removeBreakpoint":
604
- try {
605
- this.removeBreakpoint(data.breakpointId);
606
- ws.send(
607
- JSON.stringify({
608
- _type: "breakpointRemoved",
609
- breakpointId: data.breakpointId,
610
- }),
611
- );
612
- } catch (error) {
613
- ws.send(JSON.stringify({ _type: "error", message: error.message }));
614
- }
615
- break;
616
-
617
- case "continue":
618
- try {
619
- this.continueExecution(data.sessionId);
620
- ws.send(
621
- JSON.stringify({ _type: "continued", sessionId: data.sessionId }),
622
- );
623
- } catch (error) {
624
- ws.send(JSON.stringify({ _type: "error", message: error.message }));
625
- }
626
- break;
627
-
628
- case "step":
629
- try {
630
- this.stepThrough(data.sessionId);
631
- ws.send(
632
- JSON.stringify({ _type: "stepped", sessionId: data.sessionId }),
633
- );
634
- } catch (error) {
635
- ws.send(JSON.stringify({ _type: "error", message: error.message }));
636
- }
637
- break;
638
-
639
- case "getVariables":
640
- try {
641
- const variables = this.getVariables(data.sessionId, data.stepId);
642
- ws.send(
643
- JSON.stringify({
644
- _type: "variables",
645
- sessionId: data.sessionId,
646
- variables,
647
- }),
648
- );
649
- } catch (error) {
650
- ws.send(JSON.stringify({ _type: "error", message: error.message }));
651
- }
652
- break;
653
-
654
- default:
655
- ws.send(
656
- JSON.stringify({ _type: "error", message: "Unknown message _type" }),
657
- );
658
- }
659
- }
660
-
661
- /**
662
- * Broadcast message to all connected clients
663
- */
664
- broadcastToClients(_type, data) {
665
- if (!this.wsServer) {
666
- return;
667
- }
668
-
669
- const message = JSON.stringify({ _type, ...data });
670
- this.wsServer.clients.forEach((client) => {
671
- if (client.readyState === WebSocket.OPEN) {
672
- client.send(message);
673
- }
674
- });
675
- }
676
-
677
- /**
678
- * Serialize step for transmission
679
- */
680
- serializeStep(step) {
681
- return {
682
- id: step.id,
683
- componentId: step.componentId,
684
- startTime: step.startTime,
685
- endTime: step.endTime,
686
- duration: step.performance.duration,
687
- variables: Object.fromEntries(step.variables),
688
- error: step.error,
689
- hasOutput: !!step.output,
690
- };
691
- }
692
-
693
- /**
694
- * Clone data for debugging (avoid mutations)
695
- */
696
- cloneData(data) {
697
- try {
698
- return JSON.parse(JSON.stringify(data));
699
- } catch (error) {
700
- return { _cloneError: "Unable to clone data", _original: String(data) };
701
- }
702
- }
703
-
704
- /**
705
- * End debugging session
706
- */
707
- endSession(sessionId) {
708
- const session = this.sessions.get(sessionId);
709
- if (!session) {
710
- throw new Error(`Debug session ${sessionId} not found`);
711
- }
712
-
713
- // Remove session breakpoints
714
- session.breakpoints.forEach((breakpointId) => {
715
- this.breakpoints.delete(breakpointId);
716
- });
717
-
718
- this.sessions.delete(sessionId);
719
-
720
- this.emit("sessionEnded", { sessionId, session });
721
- this.broadcastToClients("sessionEnded", { sessionId });
722
- }
723
-
724
- /**
725
- * Get all active sessions
726
- */
727
- getActiveSessions() {
728
- return Array.from(this.sessions.values());
729
- }
730
-
731
- /**
732
- * Get debugger status
733
- */
734
- getStatus() {
735
- return {
736
- activeSessions: this.sessions.size,
737
- totalBreakpoints: this.breakpoints.size,
738
- isWebSocketServerRunning: !!this.wsServer,
739
- _options: this._options,
740
- };
741
- }
742
-
743
- /**
744
- * Stop WebSocket server
745
- */
746
- stopWebSocketServer() {
747
- if (this.wsServer) {
748
- this.wsServer.close();
749
- this.wsServer = null;
750
- this.emit("webSocketServerStopped");
751
- }
752
- }
753
- }
754
-
755
- module.exports = RealtimeDebugger;