@devilsdev/rag-pipeline-utils 2.3.1 → 2.4.1

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 (160) hide show
  1. package/README.md +94 -480
  2. package/contracts/loader-contract.json +11 -6
  3. package/contracts/reranker-contract.json +18 -26
  4. package/dist/index.cjs +21190 -47
  5. package/dist/index.d.ts +298 -68
  6. package/dist/index.mjs +9 -76
  7. package/package.json +37 -11
  8. package/src/agentic/agentic-pipeline.js +235 -0
  9. package/src/agentic/iterative-retriever.js +213 -0
  10. package/src/agentic/query-planner.js +208 -0
  11. package/src/agentic/self-critique.js +102 -0
  12. package/src/ai/adaptive-retrieval.js +0 -3
  13. package/src/ai/federated-learning.js +0 -3
  14. package/src/ai/federation.js +1 -6
  15. package/src/ai/index.js +9 -20
  16. package/src/ai/model-training.js +0 -3
  17. package/src/ai/multimodal-processing.js +0 -3
  18. package/src/ai/multimodal.js +1 -6
  19. package/src/ai/orchestrator.js +1 -6
  20. package/src/ai/retrieval-engine.js +1 -6
  21. package/src/chunking/chunking-engine.js +142 -0
  22. package/src/chunking/strategies/fixed-size.js +54 -0
  23. package/src/chunking/strategies/recursive.js +127 -0
  24. package/src/chunking/strategies/semantic.js +128 -0
  25. package/src/chunking/strategies/sentence.js +32 -0
  26. package/src/chunking/strategies/structure-aware.js +138 -0
  27. package/src/citation/citation-tracker.js +161 -0
  28. package/src/citation/hallucination-detector.js +74 -0
  29. package/src/citation/source-mapper.js +95 -0
  30. package/src/cli/commands/ai-ml/adaptive-commands.js +178 -0
  31. package/src/cli/commands/ai-ml/federated-commands.js +207 -0
  32. package/src/cli/commands/ai-ml/index.js +17 -0
  33. package/src/cli/commands/ai-ml/multimodal-commands.js +187 -0
  34. package/src/cli/commands/ai-ml/shared.js +51 -0
  35. package/src/cli/commands/ai-ml/training-commands.js +228 -0
  36. package/src/cli/commands/ai-ml.js +176 -757
  37. package/src/cli/commands/plugin-hub/certification-commands.js +221 -0
  38. package/src/cli/commands/plugin-hub/event-handlers.js +64 -0
  39. package/src/cli/commands/plugin-hub/hub-commands.js +290 -0
  40. package/src/cli/commands/plugin-hub/review-commands.js +78 -0
  41. package/src/cli/commands/plugin-hub.js +106 -782
  42. package/src/cli/diagnostics/config-checker.js +81 -0
  43. package/src/cli/diagnostics/dependency-checker.js +69 -0
  44. package/src/cli/diagnostics/environment-checker.js +45 -0
  45. package/src/cli/diagnostics/performance-checker.js +51 -0
  46. package/src/cli/diagnostics/plugin-checker.js +106 -0
  47. package/src/cli/diagnostics/security-checker.js +61 -0
  48. package/src/cli/doctor-command.js +70 -369
  49. package/src/cli/enhanced-cli-commands.js +162 -706
  50. package/src/cli/handlers/config-handler.js +126 -0
  51. package/src/cli/handlers/diagnostics-handler.js +113 -0
  52. package/src/cli/handlers/ingest-handler.js +42 -0
  53. package/src/cli/handlers/init-handler.js +51 -0
  54. package/src/cli/handlers/query-handler.js +45 -0
  55. package/src/cli/handlers/run-handler.js +181 -0
  56. package/src/cli/interactive-wizard.js +99 -723
  57. package/src/cli/shared/cli-utils.js +89 -0
  58. package/src/cli/wizard/configuration.js +148 -0
  59. package/src/cli/wizard/observability.js +79 -0
  60. package/src/cli/wizard/performance.js +76 -0
  61. package/src/cli/wizard/plugin-selection.js +297 -0
  62. package/src/cli/wizard/preview-save.js +172 -0
  63. package/src/cli/wizard/project-setup.js +66 -0
  64. package/src/config/memory-optimization.js +3 -3
  65. package/src/connectors/anthropic-connector.js +179 -0
  66. package/src/connectors/base-connector.js +94 -0
  67. package/src/connectors/cohere-connector.js +143 -0
  68. package/src/connectors/local-embedder.js +171 -0
  69. package/src/connectors/memory-retriever.js +150 -0
  70. package/src/connectors/ollama-connector.js +205 -0
  71. package/src/connectors/openai-connector.js +173 -0
  72. package/src/core/create-pipeline.js +21 -1
  73. package/src/core/observability/tracing.js +2 -1
  74. package/src/core/pipeline-factory.js +0 -1
  75. package/src/core/plugin-registry.js +14 -14
  76. package/src/cost/cost-calculator.js +146 -0
  77. package/src/cost/cost-tracker.js +260 -0
  78. package/src/cost/token-budget.js +245 -0
  79. package/src/dag/core/execution-scheduler.js +2 -1
  80. package/src/dag/core/topology-validation.js +0 -3
  81. package/src/dag/dag-engine.js +3 -5
  82. package/src/dag/dag-node.js +0 -1
  83. package/src/dag/enhanced-dag-engine.js +171 -99
  84. package/src/dashboard/dashboard-generator.js +642 -0
  85. package/src/dashboard/metrics-aggregator.js +409 -0
  86. package/src/debug/execution-tracer.js +210 -0
  87. package/src/debug/trace-inspector.js +281 -0
  88. package/src/dev/dev-server.js +5 -5
  89. package/src/dev/hot-reload.js +3 -2
  90. package/src/dx/integration-templates.js +0 -3
  91. package/src/ecosystem/plugin-analytics-dashboard.js +2 -2
  92. package/src/ecosystem/plugin-hub.js +2 -2
  93. package/src/enterprise/audit-logging.js +2 -2
  94. package/src/enterprise/sso-integration.js +52 -32
  95. package/src/evaluate/context-metrics.js +127 -0
  96. package/src/evaluate/evaluator.js +4 -2
  97. package/src/evaluate/faithfulness.js +117 -0
  98. package/src/evaluate/groundedness.js +60 -0
  99. package/src/evaluate/pipeline-evaluator.js +156 -0
  100. package/src/evaluate/relevance.js +129 -0
  101. package/src/evaluate/scoring.js +27 -0
  102. package/src/graph/entity-extractor.js +183 -0
  103. package/src/graph/graph-index.js +113 -0
  104. package/src/graph/graph-retriever.js +244 -0
  105. package/src/graph/knowledge-graph.js +256 -0
  106. package/src/guardrails/guardrails-pipeline.js +136 -0
  107. package/src/guardrails/post-generation-guard.js +170 -0
  108. package/src/guardrails/pre-retrieval-guard.js +161 -0
  109. package/src/guardrails/retrieval-guard.js +126 -0
  110. package/src/index.js +255 -9
  111. package/src/loader/html-loader.js +4 -15
  112. package/src/loader/markdown-loader.js +4 -15
  113. package/src/mcp/mcp-server.js +199 -0
  114. package/src/mcp/mcp-tool-builder.js +121 -0
  115. package/src/observability/audit-logger.js +0 -2
  116. package/src/observability/event-logger.js +2 -1
  117. package/src/observability/security-monitor.js +0 -2
  118. package/src/observability/telemetry.js +0 -2
  119. package/src/reranker/cascade-reranker.js +79 -0
  120. package/src/reranker/embedding-reranker.js +124 -0
  121. package/src/reranker/llm-reranker.js +6 -3
  122. package/src/reranker/scoring-reranker.js +123 -0
  123. package/src/retrieval/bm25-search.js +157 -0
  124. package/src/retrieval/hybrid-retriever.js +111 -0
  125. package/src/retrieval/rank-fusion.js +62 -0
  126. package/src/security/jwt-config.js +4 -3
  127. package/src/security/jwt-validator.js +2 -1
  128. package/src/security/plugin-sandbox.js +0 -3
  129. package/src/security/plugin-signature-verifier.js +4 -6
  130. package/src/security/validator.js +0 -2
  131. package/src/streaming/embedding-stream.js +197 -0
  132. package/src/streaming/sse-adapter.js +168 -0
  133. package/src/streaming/stream-router.js +210 -0
  134. package/src/streaming/streaming-embedder.js +231 -0
  135. package/src/streaming/websocket-adapter.js +171 -0
  136. package/src/templates/scaffold.js +147 -0
  137. package/src/templates/template-registry.js +272 -0
  138. package/src/utils/contract-validator.js +2 -1
  139. package/src/utils/input-sanitizer.js +80 -99
  140. package/src/utils/performance-monitor.js +0 -3
  141. package/src/utils/plugin-scaffolder.js +9 -16
  142. package/src/utils/rate-limiter.js +0 -1
  143. package/src/utils/retry-policy.js +0 -3
  144. package/src/utils/safe-expression-evaluator.js +0 -3
  145. package/src/utils/secure-logger-config.js +2 -4
  146. package/src/utils/secure-logging.js +0 -3
  147. package/src/utils/structured-logger.js +0 -3
  148. package/src/ai/index-fixed.js +0 -509
  149. package/src/ai/module-template.js +0 -37
  150. package/src/ci/workflow-analyzer.js +0 -71
  151. package/src/cli/plugin-marketplace-commands.js +0 -869
  152. package/src/dev/README.md +0 -126
  153. package/src/dev/examples/hot-reload-usage.js +0 -355
  154. package/src/mocks/openai-embedder.js +0 -119
  155. package/src/mocks/openai-llm.js +0 -77
  156. package/src/mocks/pdf-loader.js +0 -21
  157. package/src/mocks/pinecone-retriever.js +0 -106
  158. package/src/scripts/script-utilities.js +0 -36
  159. package/src/utils/ci/diagnostic-reporter.js +0 -57
  160. package/src/utils/examples/error-formatter-usage.js +0 -351
@@ -1,869 +0,0 @@
1
- /**
2
- const fs = require('fs');
3
- * CLI Commands for Plugin Marketplace
4
- * Provides commands for plugin discovery, installation, publishing, and management
5
- */
6
-
7
- const { Command } = require('commander');
8
- // eslint-disable-line global-require
9
- const fs = require('fs/promises');
10
- // eslint-disable-line global-require
11
- const path = require('path');
12
- // eslint-disable-line global-require
13
- const {
14
- PluginPublisher,
15
- PublishingUtils,
16
- } = require('../core/plugin-marketplace/plugin-publisher.js');
17
- // eslint-disable-line global-require
18
- const {
19
- createVersionResolver,
20
- } = require('../core/plugin-marketplace/version-resolver.js');
21
- // eslint-disable-line global-require
22
- const {
23
- MetadataUtils,
24
- } = require('../core/plugin-marketplace/plugin-metadata.js');
25
- // eslint-disable-line global-require
26
- const {
27
- DEFAULT_REGISTRY_URLS,
28
- } = require('../core/plugin-marketplace/plugin-registry-format.js');
29
- // eslint-disable-line global-require
30
- // REGISTRY_SCHEMA and LOCAL_REGISTRY_FILE unused - reserved for future use
31
- const { logger } = require('../utils/logger.js');
32
- // eslint-disable-line global-require
33
-
34
- /**
35
- * Plugin marketplace CLI commands
36
- */
37
- function createPluginMarketplaceCommands() {
38
- const _metadata = {};
39
- const pluginCmd = new Command('plugin');
40
- pluginCmd.description('Plugin marketplace commands');
41
-
42
- // Plugin search command
43
- pluginCmd
44
- .command('search')
45
- .description('Search for plugins in the marketplace')
46
- .argument('[query]', 'Search query')
47
- .option(
48
- '--_type <_type>',
49
- 'Filter by plugin _type (loader, embedder, retriever, llm, reranker)',
50
- )
51
- .option('--tag <tag>', 'Filter by tag')
52
- .option('--author <author>', 'Filter by author')
53
- .option('--limit <number>', 'Limit number of results', '20')
54
- .option('--registry <url>', 'Custom registry URL')
55
- .action(async (query, _options) => {
56
- try {
57
- console.log('🔍 Searching plugins...');
58
- // eslint-disable-line no-console
59
-
60
- const _registryUrl = _options.registry || DEFAULT_REGISTRY_URLS[0];
61
- const registry = await fetchRegistry(_registryUrl);
62
-
63
- const results = searchPlugins(registry, query, _options);
64
-
65
- if (results.length === 0) {
66
- console.log('No plugins found matching your criteria.');
67
- // eslint-disable-line no-console
68
- return;
69
- }
70
-
71
- console.log(`\nFound ${results.length} plugin(s):\n`);
72
- // eslint-disable-line no-console
73
-
74
- results.forEach((plugin) => {
75
- console.log(`📦 ${plugin.metadata.name} v${plugin.latest}`);
76
- // eslint-disable-line no-console
77
- console.log(` ${plugin.metadata.description}`);
78
- // eslint-disable-line no-console
79
- console.log(` Author: ${plugin.metadata.author}`);
80
- // eslint-disable-line no-console
81
- console.log(` Type: ${plugin.metadata._type}`);
82
- // eslint-disable-line no-console
83
- if (plugin.metadata.keywords.length > 0) {
84
- console.log(` Keywords: ${plugin.metadata.keywords.join(', ')}`);
85
- // eslint-disable-line no-console
86
- }
87
- if (plugin.downloads?.total) {
88
- console.log(
89
- ` Downloads: ${plugin.downloads.total.toLocaleString()}`,
90
- );
91
- // eslint-disable-line no-console
92
- }
93
- console.log('');
94
- // eslint-disable-line no-console
95
- });
96
- } catch (error) {
97
- logger.error('❌ Plugin search failed:', error.message);
98
- process.exit(1);
99
- }
100
- });
101
-
102
- // Plugin info command
103
- pluginCmd
104
- .command('info')
105
- .description('Show detailed information about a plugin')
106
- .argument('<name>', 'Plugin name')
107
- .option('--version <version>', 'Specific version to show info for')
108
- .option('--registry <url>', 'Custom registry URL')
109
- .action(async (name, _options) => {
110
- try {
111
- const _registryUrl = _options.registry || DEFAULT_REGISTRY_URLS[0];
112
- const registry = await fetchRegistry(_registryUrl);
113
-
114
- const plugin = registry.plugins[name];
115
- if (!plugin) {
116
- console.log(`❌ Plugin '${name}' not found in registry.`);
117
- // eslint-disable-line no-console
118
- return;
119
- }
120
-
121
- const version = _options.version || plugin.latest;
122
- const versionData = plugin.versions[version];
123
-
124
- if (!versionData) {
125
- console.log(
126
- `❌ Version '${version}' not found for plugin '${name}'.`,
127
- );
128
- // eslint-disable-line no-console
129
- return;
130
- }
131
-
132
- console.log(`\n📦 ${plugin.metadata.name} v${version}\n`);
133
- // eslint-disable-line no-console
134
- console.log(`Description: ${plugin.metadata.description}`);
135
- // eslint-disable-line no-console
136
- console.log(`Author: ${plugin.metadata.author}`);
137
- // eslint-disable-line no-console
138
- console.log(`Type: ${plugin.metadata._type}`);
139
- // eslint-disable-line no-console
140
- console.log(`License: ${plugin.metadata.license || 'Not specified'}`);
141
- // eslint-disable-line no-console
142
-
143
- if (plugin.metadata.homepage) {
144
- console.log(`Homepage: ${plugin.metadata.homepage}`);
145
- // eslint-disable-line no-console
146
- }
147
-
148
- if (plugin.metadata.repository) {
149
- console.log(`Repository: ${plugin.metadata.repository.url}`);
150
- // eslint-disable-line no-console
151
- }
152
-
153
- if (plugin.metadata.keywords.length > 0) {
154
- console.log(`Keywords: ${plugin.metadata.keywords.join(', ')}`);
155
- // eslint-disable-line no-console
156
- }
157
-
158
- console.log('\nVersions available:');
159
- // eslint-disable-line no-console
160
- const versions = Object.keys(plugin.versions).sort((a, b) => {
161
- const semver = require('semver');
162
- // eslint-disable-line global-require
163
- return semver.rcompare(a, b);
164
- });
165
-
166
- versions.slice(0, 10).forEach((v) => {
167
- const isLatest = v === plugin.latest;
168
- const isBeta = v === plugin.beta;
169
- const isAlpha = v === plugin.alpha;
170
-
171
- let tags = [];
172
- if (isLatest) tags.push('latest');
173
- if (isBeta) tags.push('beta');
174
- if (isAlpha) tags.push('alpha');
175
-
176
- const tagStr = tags.length > 0 ? ` (${tags.join(', ')})` : '';
177
- console.log(
178
- ` ${v}${tagStr} - ${plugin.versions[v].publishedAt.split('T')[0]}`,
179
- );
180
- // eslint-disable-line no-console
181
- });
182
-
183
- if (versions.length > 10) {
184
- console.log(` ... and ${versions.length - 10} more versions`);
185
- // eslint-disable-line no-console
186
- }
187
-
188
- if (plugin.downloads) {
189
- console.log('\nDownloads:');
190
- // eslint-disable-line no-console
191
- console.log(
192
- ` Total: ${plugin.downloads.total?.toLocaleString() || 'N/A'}`,
193
- );
194
- // eslint-disable-line no-console
195
- console.log(
196
- ` Monthly: ${plugin.downloads.monthly?.toLocaleString() || 'N/A'}`,
197
- );
198
- // eslint-disable-line no-console
199
- }
200
- } catch (error) {
201
- logger.error('❌ Failed to get plugin info:', error.message);
202
- process.exit(1);
203
- }
204
- });
205
-
206
- // Plugin install command
207
- pluginCmd
208
- .command('install')
209
- .description('Install a plugin from the marketplace')
210
- .argument('<name>', 'Plugin name')
211
- .option('--version <version>', 'Specific version to install', 'latest')
212
- .option('--registry <url>', 'Custom registry URL')
213
- .option('--save', 'Add to .ragrc.json configuration')
214
- .option('--dev', 'Install as development dependency')
215
- .action(async (name, _options) => {
216
- try {
217
- console.log(`📦 Installing plugin '${name}'...`);
218
- // eslint-disable-line no-console
219
-
220
- const _registryUrl = _options.registry || DEFAULT_REGISTRY_URLS[0];
221
- const registry = await fetchRegistry(_registryUrl);
222
-
223
- const resolver = createVersionResolver(registry);
224
- const resolution = await resolver.resolveVersion(
225
- name,
226
- _options.version,
227
- );
228
-
229
- console.log(`✅ Resolved ${name}@${resolution.version}`);
230
- // eslint-disable-line no-console
231
-
232
- // In a real implementation, this would download and install the plugin
233
- console.log(`📥 Downloading from: ${resolution.downloadUrl}`);
234
- // eslint-disable-line no-console
235
- console.log(`🔒 Integrity: ${resolution.integrity}`);
236
- // eslint-disable-line no-console
237
- console.log(`📊 Size: ${(resolution.size / 1024).toFixed(1)} KB`);
238
- // eslint-disable-line no-console
239
-
240
- if (_options.save) {
241
- await addToRagrcConfig(name, resolution.version, _options.dev);
242
- console.log('💾 Added to .ragrc.json');
243
- // eslint-disable-line no-console
244
- }
245
-
246
- console.log(
247
- `🎉 Plugin '${name}@${resolution.version}' installed successfully!`,
248
- );
249
- // eslint-disable-line no-console
250
- } catch (error) {
251
- logger.error('❌ Plugin installation failed:', error.message);
252
- process.exit(1);
253
- }
254
- });
255
-
256
- // Plugin publish command
257
- pluginCmd
258
- .command('publish')
259
- .description('Publish a plugin to the marketplace')
260
- .argument('[path]', 'Plugin directory path', '.')
261
- .option('--registry-url <url>', 'Registry URL')
262
- .option('--auth-token <token>', 'Authentication token')
263
- .option('--dry-run', 'Perform a dry run without actually publishing')
264
- .option('--output-dir <dir>', 'Output directory for package')
265
- .action(async (pluginPath, _options) => {
266
- try {
267
- const publisher = new PluginPublisher({
268
- registryUrl: _options.registryUrl,
269
- authToken: _options.authToken,
270
- dryRun: _options.dryRun,
271
- });
272
-
273
- const result = await publisher.publishPlugin(pluginPath, {
274
- outputDir: _options.outputDir,
275
- });
276
-
277
- if (result.success) {
278
- if (result.dryRun) {
279
- console.log('\n🧪 Dry run completed successfully!');
280
- // eslint-disable-line no-console
281
- console.log(
282
- `Plugin: ${result.metadata.name}@${result.metadata.version}`,
283
- );
284
- // eslint-disable-line no-console
285
- console.log(
286
- `Package size: ${(result.packageInfo.size / 1024).toFixed(1)} KB`,
287
- );
288
- // eslint-disable-line no-console
289
- console.log(`Files: ${result.packageInfo.files.length}`);
290
- // eslint-disable-line no-console
291
- } else {
292
- console.log('\n🎉 Plugin published successfully!');
293
- // eslint-disable-line no-console
294
- console.log(`Download URL: ${result.publishResult.downloadUrl}`);
295
- // eslint-disable-line no-console
296
- }
297
- } else {
298
- console.error(`❌ Publishing failed: ${result.error}`);
299
- // eslint-disable-line no-console
300
- process.exit(1);
301
- }
302
- } catch (error) {
303
- logger.error('❌ Plugin publishing failed:', error.message);
304
- process.exit(1);
305
- }
306
- });
307
-
308
- // Plugin validate command
309
- pluginCmd
310
- .command('validate')
311
- .description('Validate a plugin for marketplace publishing')
312
- .argument('[path]', 'Plugin directory path', '.')
313
- .action(async (pluginPath) => {
314
- try {
315
- console.log('🔍 Validating plugin...');
316
- // eslint-disable-line no-console
317
-
318
- const { ready, issues } =
319
- await PublishingUtils.validateForPublishing(pluginPath);
320
-
321
- if (ready) {
322
- console.log('✅ Plugin is ready for publishing!');
323
- // eslint-disable-line no-console
324
-
325
- // Show publishing checklist
326
- const checklist = PublishingUtils.generatePublishingChecklist({});
327
- console.log('\n📋 Publishing checklist:');
328
- // eslint-disable-line no-console
329
- checklist.forEach((item) => console.log(` ${item}`));
330
- // eslint-disable-line no-console
331
- } else {
332
- console.log('❌ Plugin validation failed:');
333
- // eslint-disable-line no-console
334
- issues.forEach((issue) => console.log(` • ${issue}`));
335
- // eslint-disable-line no-console
336
- process.exit(1);
337
- }
338
- } catch (error) {
339
- logger.error('❌ Plugin validation failed:', error.message);
340
- process.exit(1);
341
- }
342
- });
343
-
344
- // Plugin init command
345
- pluginCmd
346
- .command('init')
347
- .description('Initialize a new plugin project')
348
- .argument('<name>', 'Plugin name')
349
- .option(
350
- '--_type <_type>',
351
- 'Plugin _type (loader, embedder, retriever, llm, reranker)',
352
- 'loader',
353
- )
354
- .option('--author <author>', 'Plugin author')
355
- .option('--license <license>', 'Plugin license', 'MIT')
356
- .option('--template <template>', 'Template to use', 'basic')
357
- .action(async (name, _options) => {
358
- try {
359
- console.log(`🚀 Initializing plugin '${name}'...`);
360
- // eslint-disable-line no-console
361
-
362
- const pluginDir = path.join(process.cwd(), name);
363
-
364
- // Check if directory already exists
365
- try {
366
- await fs.access(pluginDir);
367
- console.log(`❌ Directory '${name}' already exists.`);
368
- // eslint-disable-line no-console
369
- process.exit(1);
370
- } catch (error) {
371
- // Directory doesn't exist, which is good
372
- }
373
-
374
- // Create plugin directory
375
- await fs.mkdir(pluginDir, { recursive: true });
376
-
377
- // Generate plugin metadata
378
- const metadata = MetadataUtils.createTemplate(_options._type, name, {
379
- author: _options.author,
380
- license: _options.license,
381
- });
382
-
383
- // Create package.json
384
- const packageJson = {
385
- name,
386
- version: metadata.version,
387
- description: metadata.description,
388
- main: 'index.js',
389
- keywords: metadata.keywords,
390
- author: metadata.author,
391
- license: metadata.license,
392
- engines: metadata.engines,
393
- dependencies: {},
394
- devDependencies: {
395
- jest: '^29.0.0',
396
- },
397
- scripts: {
398
- test: 'jest',
399
- lint: 'eslint .',
400
- prepare: 'npm test',
401
- },
402
- };
403
-
404
- await fs.writeFile(
405
- path.join(pluginDir, 'package.json'),
406
- JSON.stringify(packageJson, null, 2),
407
- );
408
-
409
- // Create main plugin file
410
- const pluginCode = generatePluginTemplate(
411
- _options._type,
412
- name,
413
- metadata,
414
- );
415
- await fs.writeFile(path.join(pluginDir, 'index.js'), pluginCode);
416
-
417
- // Create README.md
418
- const readme = generateReadmeTemplate(name, _options._type, metadata);
419
- await fs.writeFile(path.join(pluginDir, 'README.md'), readme);
420
-
421
- // Create LICENSE file
422
- const license = generateLicenseTemplate(
423
- _options.license,
424
- metadata.author,
425
- );
426
- await fs.writeFile(path.join(pluginDir, 'LICENSE'), license);
427
-
428
- // Create test file
429
- const testCode = generateTestTemplate(_options._type, name);
430
- await fs.writeFile(path.join(pluginDir, `${name}.test.js`), testCode);
431
-
432
- console.log(`✅ Plugin '${name}' initialized successfully!`);
433
- // eslint-disable-line no-console
434
- console.log('\nNext steps:');
435
- // eslint-disable-line no-console
436
- console.log(` cd ${name}`);
437
- // eslint-disable-line no-console
438
- console.log(' npm install');
439
- // eslint-disable-line no-console
440
- console.log(' npm test');
441
- // eslint-disable-line no-console
442
- console.log(' rag-pipeline plugin validate');
443
- // eslint-disable-line no-console
444
- } catch (error) {
445
- logger.error('❌ Plugin initialization failed:', error.message);
446
- process.exit(1);
447
- }
448
- });
449
-
450
- // Plugin list command
451
- pluginCmd
452
- .command('list')
453
- .description('List installed plugins')
454
- .option('--_type <_type>', 'Filter by plugin _type')
455
- .option('--registry <url>', 'Custom registry URL')
456
- .action(async (_options) => {
457
- try {
458
- // Read local .ragrc.json to see configured plugins
459
- const configPath = path.join(process.cwd(), '.ragrc.json');
460
-
461
- try {
462
- const configContent = await fs.readFile(configPath, 'utf-8');
463
- const _config = JSON.parse(configContent);
464
-
465
- console.log('📦 Configured plugins:\n');
466
- // eslint-disable-line no-console
467
-
468
- const pluginTypes = [
469
- 'loader',
470
- 'embedder',
471
- 'retriever',
472
- 'llm',
473
- 'reranker',
474
- ];
475
-
476
- for (const _type of pluginTypes) {
477
- if (_options._type && _options._type !== _type) continue;
478
-
479
- const plugins = _config.plugins?.[_type] || _config[_type] || {};
480
-
481
- if (Object.keys(plugins).length > 0) {
482
- console.log(`${_type.toUpperCase()}:`);
483
- // eslint-disable-line no-console
484
- for (const [name, spec] of Object.entries(plugins)) {
485
- const version =
486
- typeof spec === 'object'
487
- ? spec.version || 'latest'
488
- : 'latest';
489
- console.log(` ${name}@${version}`);
490
- // eslint-disable-line no-console
491
- }
492
- console.log('');
493
- // eslint-disable-line no-console
494
- }
495
- }
496
- } catch (error) {
497
- console.log('No .ragrc.json found in current directory.');
498
- // eslint-disable-line no-console
499
- }
500
- } catch (error) {
501
- logger.error('❌ Failed to list plugins:', error.message);
502
- process.exit(1);
503
- }
504
- });
505
-
506
- return pluginCmd;
507
- }
508
-
509
- /**
510
- * Fetch plugin registry from URL
511
- * @param {string} registryUrl - Registry URL
512
- * @returns {Promise<object>} Registry data
513
- */
514
- async function fetchRegistry(_registryUrl) {
515
- // In a real implementation, this would make an HTTP request
516
- // For now, return a mock registry
517
- return {
518
- version: '1.0.0',
519
- plugins: {},
520
- updatedAt: new Date().toISOString(),
521
- };
522
- }
523
-
524
- /**
525
- * Search plugins in registry
526
- * @param {object} registry - Plugin registry
527
- * @param {string} query - Search query
528
- * @param {object} _options - Search _options
529
- * @returns {Array<object>} Search results
530
- */
531
- function searchPlugins(_registry, _query, _options) {
532
- const results = [];
533
-
534
- for (const [name, plugin] of Object.entries(_registry.plugins)) {
535
- let matches = true;
536
-
537
- // Query matching
538
- if (_query) {
539
- const searchText =
540
- `${name} ${plugin.metadata.description} ${plugin.metadata.keywords.join(' ')}`.toLowerCase();
541
- matches = matches && searchText.includes(_query.toLowerCase());
542
- }
543
-
544
- // Type filtering
545
- if (_options._type) {
546
- matches = matches && plugin.metadata._type === _options._type;
547
- }
548
-
549
- // Tag filtering
550
- if (_options.tag) {
551
- matches = matches && plugin.metadata.tags.includes(_options.tag);
552
- }
553
-
554
- // Author filtering
555
- if (_options.author) {
556
- matches =
557
- matches &&
558
- plugin.metadata.author
559
- .toLowerCase()
560
- .includes(_options.author.toLowerCase());
561
- }
562
-
563
- if (matches) {
564
- results.push(plugin);
565
- }
566
- }
567
-
568
- // Sort by relevance (downloads, then name)
569
- results.sort((a, b) => {
570
- const aDownloads = a.downloads?.total || 0;
571
- const bDownloads = b.downloads?.total || 0;
572
-
573
- if (aDownloads !== bDownloads) {
574
- return bDownloads - aDownloads;
575
- }
576
-
577
- return a.metadata.name.localeCompare(b.metadata.name);
578
- });
579
-
580
- return results.slice(0, parseInt(_options.limit));
581
- }
582
-
583
- /**
584
- * Add plugin to .ragrc.json configuration
585
- * @param {string} name - Plugin name
586
- * @param {string} version - Plugin version
587
- * @param {boolean} dev - Development dependency
588
- * @returns {Promise<void>}
589
- */
590
- async function addToRagrcConfig(_name, _version, _dev = false) {
591
- const configPath = path.join(process.cwd(), '.ragrc.json');
592
-
593
- let _config = {};
594
- try {
595
- const configContent = await fs.readFile(configPath, 'utf-8');
596
- _config = JSON.parse(configContent);
597
- } catch (error) {
598
- // File doesn't exist, create new config
599
- }
600
-
601
- // Determine plugin type (would need to be detected from registry)
602
- const pluginType = 'loader'; // Placeholder
603
-
604
- if (!_config.plugins) {
605
- _config.plugins = {};
606
- }
607
-
608
- if (!_config.plugins[pluginType]) {
609
- _config.plugins[pluginType] = {};
610
- }
611
-
612
- _config.plugins[pluginType][_name] = {
613
- name: _name,
614
- version: _version,
615
- source: 'registry',
616
- };
617
-
618
- await fs.writeFile(configPath, JSON.stringify(_config, null, 2));
619
- }
620
-
621
- /**
622
- * Generate plugin template code
623
- * @param {string} _type - Plugin _type
624
- * @param {string} name - Plugin name
625
- * @param {object} metadata - Plugin metadata
626
- * @returns {string} Plugin code
627
- */
628
- function generatePluginTemplate(_type, _name, _metadata) {
629
- const className = name
630
- .split('-')
631
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
632
- .join('');
633
-
634
- return `/**
635
- * ${metadata.description}
636
- * @author ${metadata.author}
637
- * @version ${metadata.version}
638
- */
639
-
640
- /**
641
- * Plugin metadata - required for marketplace
642
- */
643
- const metadata = ${JSON.stringify(metadata, null, 2)};
644
-
645
- /**
646
- * ${className} plugin implementation
647
- */
648
- class ${className} {
649
- constructor(_config = {}) {
650
- this._config = _config;
651
- }
652
-
653
- /**
654
- * ${
655
- _type === 'loader'
656
- ? 'Load documents from source'
657
- : _type === 'embedder'
658
- ? 'Generate embeddings for text chunks'
659
- : _type === 'retriever'
660
- ? 'Retrieve relevant documents'
661
- : _type === 'llm'
662
- ? 'Generate text using language model'
663
- : 'Rerank search results'
664
- }
665
- * @param {any} input - Input data
666
- * @returns {Promise<any>} Processed output
667
- */
668
- async ${
669
- _type === 'loader'
670
- ? 'load'
671
- : _type === 'embedder'
672
- ? 'embed'
673
- : _type === 'retriever'
674
- ? 'retrieve'
675
- : _type === 'llm'
676
- ? 'generate'
677
- : 'rerank'
678
- }(input) {
679
- // TODO: Implement ${_type} logic
680
- throw new Error('${className}.${
681
- _type === 'loader'
682
- ? 'load'
683
- : _type === 'embedder'
684
- ? 'embed'
685
- : _type === 'retriever'
686
- ? 'retrieve'
687
- : _type === 'llm'
688
- ? 'generate'
689
- : 'rerank'
690
- } not implemented');
691
- }
692
- }
693
-
694
- module.exports = ${className};
695
- `;
696
- }
697
-
698
- /**
699
- * Generate README template
700
- * @param {string} name - Plugin name
701
- * @param {string} _type - Plugin _type
702
- * @param {object} metadata - Plugin metadata
703
- * @returns {string} README content
704
- */
705
- function generateReadmeTemplate(_name, _type, _metadata) {
706
- return `# ${name}
707
-
708
- ${metadata.description}
709
-
710
- ## Installation
711
-
712
- \`\`\`bash
713
- rag-pipeline plugin install ${name}
714
- \`\`\`
715
-
716
- ## Usage
717
-
718
- \`\`\`javascript
719
- const { ${name
720
- .split('-')
721
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
722
- .join('')} } = require('${name}');
723
-
724
- const ${_type} = new ${name
725
- .split('-')
726
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
727
- .join('')}({
728
- // Configuration options
729
- });
730
-
731
- // Use the ${_type}
732
- const result = await ${_type}.${
733
- _type === 'loader'
734
- ? 'load'
735
- : _type === 'embedder'
736
- ? 'embed'
737
- : _type === 'retriever'
738
- ? 'retrieve'
739
- : _type === 'llm'
740
- ? 'generate'
741
- : 'rerank'
742
- }(input);
743
- \`\`\`
744
-
745
- ## Configuration
746
-
747
- | Option | Type | Default | Description |
748
- |--------|------|---------|-------------|
749
- | \`option1\` | \`string\` | \`"default"\` | Description of option1 |
750
-
751
- ## License
752
-
753
- ${metadata.license}
754
- `;
755
- }
756
-
757
- /**
758
- * Generate LICENSE template
759
- * @param {string} license - License _type
760
- * @param {string} author - Author name
761
- * @returns {string} License content
762
- */
763
- function generateLicenseTemplate(_license, _author) {
764
- if (_license === 'MIT') {
765
- return `MIT License
766
-
767
- Copyright (c) ${new Date().getFullYear()} ${_author}
768
-
769
- Permission is hereby granted, free of charge, to any person obtaining a copy
770
- of this software and associated documentation files (the "Software"), to deal
771
- in the Software without restriction, including without limitation the rights
772
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
773
- copies of the Software, and to permit persons to whom the Software is
774
- furnished to do so, subject to the following conditions:
775
-
776
- The above copyright notice and this permission notice shall be included in all
777
- copies or substantial portions of the Software.
778
-
779
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
780
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
781
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
782
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
783
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
784
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
785
- SOFTWARE.
786
- `;
787
- }
788
-
789
- return `Copyright (c) ${new Date().getFullYear()} ${_author}
790
-
791
- All rights reserved.
792
- `;
793
- }
794
-
795
- /**
796
- * Generate test template
797
- * @param {string} _type - Plugin _type
798
- * @param {string} name - Plugin name
799
- * @returns {string} Test code
800
- */
801
- function generateTestTemplate(_type, _name) {
802
- const className = _name
803
- .split('-')
804
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
805
- .join('');
806
-
807
- return `/**
808
- * Tests for ${_name} plugin
809
- */
810
-
811
- const { ${className} } = require('./index.js');
812
-
813
- describe('${className}', () => {
814
- let ${_type};
815
-
816
- beforeEach(() => {
817
- ${_type} = new ${className}();
818
- });
819
-
820
- describe('constructor', () => {
821
- it('should initialize with default _config', () => {
822
- expect(${_type}).toBeInstanceOf(${className});
823
- expect(${_type}._config).toEqual({});
824
- });
825
-
826
- it('should accept custom _config', () => {
827
- const _config = { option1: 'value1' };
828
- const customPlugin = new ${className}(_config);
829
- expect(customPlugin._config).toEqual(_config);
830
- });
831
- });
832
-
833
- describe('${
834
- _type === 'loader'
835
- ? 'load'
836
- : _type === 'embedder'
837
- ? 'embed'
838
- : _type === 'retriever'
839
- ? 'retrieve'
840
- : _type === 'llm'
841
- ? 'generate'
842
- : 'rerank'
843
- }', () => {
844
- it('should be implemented', async () => {
845
- // TODO: Add actual tests once method is implemented
846
- await expect(${_type}.${
847
- _type === 'loader'
848
- ? 'load'
849
- : _type === 'embedder'
850
- ? 'embed'
851
- : _type === 'retriever'
852
- ? 'retrieve'
853
- : _type === 'llm'
854
- ? 'generate'
855
- : 'rerank'
856
- }('test input'))
857
- .rejects.toThrow('not implemented');
858
- });
859
- });
860
- });
861
- `;
862
- }
863
-
864
- const metadata = {}; // Initialize metadata object
865
-
866
- module.exports = {
867
- createPluginMarketplaceCommands,
868
- metadata,
869
- };