@devilsdev/rag-pipeline-utils 2.1.12 → 2.2.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.
- package/.ragrc.schema.json +218 -0
- package/README.md +178 -550
- package/bin/cli.js +8 -14
- package/contracts/reranker-contract.json +69 -0
- package/dist/index.d.ts +237 -0
- package/dist/index.mjs +22 -7
- package/package.json +18 -13
- package/src/ai/adaptive-retrieval.js +191 -0
- package/src/ai/federated-learning.js +214 -0
- package/src/ai/federation/federated-learning-coordinator.js +345 -0
- package/src/ai/federation.js +76 -0
- package/src/ai/index-fixed.js +509 -0
- package/src/ai/index.js +33 -0
- package/src/ai/model-trainer.js +217 -0
- package/src/ai/model-training.js +205 -0
- package/src/ai/module-template.js +37 -0
- package/src/ai/multimodal/multi-modal-processor.js +345 -0
- package/src/ai/multimodal-processing.js +268 -0
- package/src/ai/multimodal.js +71 -0
- package/src/ai/orchestrator.js +70 -0
- package/src/ai/retrieval/adaptive-retrieval-engine.js +398 -0
- package/src/ai/retrieval-engine.js +69 -0
- package/src/ai/training/model-training-orchestrator.js +228 -0
- package/src/ci/workflow-analyzer.js +71 -0
- package/src/cli/commands/ai-ml.js +967 -0
- package/src/cli/commands/docs.js +228 -0
- package/src/cli/commands/dx.js +538 -0
- package/src/cli/commands/plugin-hub.js +875 -0
- package/src/cli/doctor-command.js +639 -0
- package/src/cli/enhanced-cli-commands.js +945 -0
- package/src/cli/interactive-wizard.js +997 -0
- package/src/cli/plugin-marketplace-commands.js +869 -0
- package/src/cli.js +17 -0
- package/src/config/enhanced-ragrc-schema.js +632 -0
- package/src/config/load-config.js +54 -0
- package/src/config/load-plugin-config.js +69 -0
- package/src/config/normalize-config.js +105 -0
- package/src/config/schema-validator.js +315 -0
- package/src/config/validate-plugin-schema.js +35 -0
- package/src/config/validate-schema.js +113 -0
- package/src/contracts/plugin-contracts.js +33 -0
- package/src/core/create-pipeline.js +99 -0
- package/src/core/dependency-injection.js +242 -0
- package/src/core/observability/event-logger.js +241 -0
- package/src/core/observability/instrumented-pipeline.js +609 -0
- package/src/core/observability/metrics.js +497 -0
- package/src/core/observability/tracing.js +781 -0
- package/src/core/performance/benchmark.js +516 -0
- package/src/core/performance/parallel-processor.js +240 -0
- package/src/core/performance/streaming-safeguards.js +620 -0
- package/src/core/pipeline-factory.js +60 -0
- package/src/core/plugin-contracts.js +89 -0
- package/src/core/plugin-marketplace/plugin-metadata.js +485 -0
- package/src/core/plugin-marketplace/plugin-publisher.js +574 -0
- package/src/core/plugin-marketplace/plugin-registry-format.js +419 -0
- package/src/core/plugin-marketplace/version-resolver.js +61 -0
- package/src/core/plugin-registry.js +294 -0
- package/src/dag/dag-engine.js +954 -0
- package/src/dag/dag-node.js +76 -0
- package/src/dag/enhanced-dag-engine.js +822 -0
- package/src/dx/index.js +40 -0
- package/src/dx/integration-templates.js +665 -0
- package/src/dx/performance-profiler.js +968 -0
- package/src/dx/realtime-debugger.js +755 -0
- package/src/dx/visual-pipeline-builder.js +578 -0
- package/src/ecosystem/plugin-analytics-dashboard.js +778 -0
- package/src/ecosystem/plugin-certification.js +580 -0
- package/src/ecosystem/plugin-hub.js +821 -0
- package/src/enterprise/audit-logging.js +967 -0
- package/src/enterprise/data-governance.js +408 -0
- package/src/enterprise/multi-tenancy.js +496 -0
- package/src/enterprise/sso-integration.js +1030 -0
- package/src/evaluate/evaluator.js +52 -0
- package/src/evaluate/scoring.js +91 -0
- package/src/index.js +67 -0
- package/src/ingest.js +59 -0
- package/src/loader/csv-loader.js +38 -0
- package/src/loader/directory-loader.js +48 -0
- package/src/loader/html-loader.js +62 -0
- package/src/loader/markdown-loader.js +67 -0
- package/src/mocks/openai-embedder.js +119 -0
- package/src/mocks/openai-llm.js +77 -0
- package/src/mocks/pdf-loader.js +21 -0
- package/src/mocks/pinecone-retriever.js +106 -0
- package/src/observability/audit-logger.js +758 -0
- package/src/observability/dashboard-config.json +675 -0
- package/src/observability/event-logger.js +310 -0
- package/src/observability/metrics.js +691 -0
- package/src/observability/security-monitor.js +830 -0
- package/src/observability/slo-monitor.js +319 -0
- package/src/observability/telemetry.js +686 -0
- package/src/pipeline/pipeline.js +18 -0
- package/src/plugins/sample-embedder.js +53 -0
- package/src/plugins/sample-llm.js +30 -0
- package/src/plugins/sample-loader.js +24 -0
- package/src/plugins/sample-retriever.js +84 -0
- package/src/query.js +117 -0
- package/src/reranker/llm-reranker.js +111 -0
- package/src/scripts/script-utilities.js +36 -0
- package/src/security/plugin-sandbox.js +586 -0
- package/src/security/plugin-signature-verifier.js +414 -0
- package/src/security/validator.js +36 -0
- package/src/utils/ci/diagnostic-reporter.js +57 -0
- package/src/utils/logger.js +211 -0
- package/src/utils/performance-monitor.js +561 -0
- package/src/utils/plugin-scaffolder.js +447 -0
- package/src/utils/rate-limiter.js +244 -0
- package/src/utils/retry-policy.js +443 -0
- package/src/utils/retry.js +107 -0
- package/src/utils/safe-expression-evaluator.js +579 -0
- package/src/utils/secure-logging.js +338 -0
- package/src/utils/structured-logger.js +388 -0
- package/src/utils/validate-plugin-contract.js +42 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version: 2.0.0
|
|
3
|
+
* Description: Shared plugin interface contracts for runtime + CI mock validation
|
|
4
|
+
* Author: Ali Kahwaji
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const pluginContracts = {
|
|
8
|
+
loader: {
|
|
9
|
+
requiredMethods: ['load'],
|
|
10
|
+
methodSignatures: {
|
|
11
|
+
load: {
|
|
12
|
+
params: ['_filePath'],
|
|
13
|
+
paramTypes: ['string'],
|
|
14
|
+
returnType: 'Promise<Array<{chunk: () => string[]}>>',
|
|
15
|
+
description: 'Load and parse a document from the given file path',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
embedder: {
|
|
20
|
+
requiredMethods: ['embed', 'embedQuery'],
|
|
21
|
+
methodSignatures: {
|
|
22
|
+
embed: {
|
|
23
|
+
params: ['chunks'],
|
|
24
|
+
paramTypes: ['string[]'],
|
|
25
|
+
returnType: 'Promise<number[][]>',
|
|
26
|
+
description: 'Generate embeddings for an array of text chunks',
|
|
27
|
+
},
|
|
28
|
+
embedQuery: {
|
|
29
|
+
params: ['query'],
|
|
30
|
+
paramTypes: ['string'],
|
|
31
|
+
returnType: 'Promise<number[]>',
|
|
32
|
+
description: 'Generate embedding for a single query string',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
retriever: {
|
|
37
|
+
requiredMethods: ['store', 'retrieve'],
|
|
38
|
+
methodSignatures: {
|
|
39
|
+
store: {
|
|
40
|
+
params: ['vectors'],
|
|
41
|
+
paramTypes: ['number[][]'],
|
|
42
|
+
returnType: 'Promise<void>',
|
|
43
|
+
description: 'Store vectors in the retrieval system',
|
|
44
|
+
},
|
|
45
|
+
retrieve: {
|
|
46
|
+
params: ['queryVector'],
|
|
47
|
+
paramTypes: ['number[]'],
|
|
48
|
+
returnType: 'Promise<string[]>',
|
|
49
|
+
description: 'Retrieve relevant context based on query vector',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
llm: {
|
|
54
|
+
requiredMethods: ['generate'],
|
|
55
|
+
optionalMethods: ['generateStream'],
|
|
56
|
+
methodSignatures: {
|
|
57
|
+
generate: {
|
|
58
|
+
params: ['prompt', 'context'],
|
|
59
|
+
paramTypes: ['string', 'string[]'],
|
|
60
|
+
returnType: 'Promise<string>',
|
|
61
|
+
description: 'Generate response based on prompt and retrieved context',
|
|
62
|
+
},
|
|
63
|
+
generateStream: {
|
|
64
|
+
params: ['prompt', 'context'],
|
|
65
|
+
paramTypes: ['string', 'string[]'],
|
|
66
|
+
returnType: 'AsyncIterable<string>',
|
|
67
|
+
description:
|
|
68
|
+
'Generate streaming response token-by-token based on prompt and retrieved context',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
reranker: {
|
|
73
|
+
requiredMethods: ['rerank'],
|
|
74
|
+
methodSignatures: {
|
|
75
|
+
rerank: {
|
|
76
|
+
params: ['query', 'documents'],
|
|
77
|
+
paramTypes: ['string', 'string[]'],
|
|
78
|
+
returnType: 'Promise<string[]>',
|
|
79
|
+
description: 'Rerank documents based on relevance to query',
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Default export
|
|
86
|
+
|
|
87
|
+
module.exports = {
|
|
88
|
+
pluginContracts,
|
|
89
|
+
};
|
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Metadata Export System
|
|
3
|
+
* Requires all plugins to export standardized metadata for marketplace compatibility
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
validatePluginMetadata,
|
|
8
|
+
PLUGIN_NAMING,
|
|
9
|
+
} = require('./plugin-registry-format.js');
|
|
10
|
+
// eslint-disable-line global-require
|
|
11
|
+
const { VersionUtils } = require('./version-resolver.js');
|
|
12
|
+
// eslint-disable-line global-require
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Plugin metadata extractor and validator
|
|
16
|
+
*/
|
|
17
|
+
class PluginMetadataExtractor {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.requiredFields = ['name', 'version', '_type', 'description', 'author'];
|
|
20
|
+
this.optionalFields = [
|
|
21
|
+
'homepage',
|
|
22
|
+
'repository',
|
|
23
|
+
'keywords',
|
|
24
|
+
'license',
|
|
25
|
+
'engines',
|
|
26
|
+
'dependencies',
|
|
27
|
+
'peerDependencies',
|
|
28
|
+
'_config',
|
|
29
|
+
'examples',
|
|
30
|
+
'tags',
|
|
31
|
+
];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Extract metadata from plugin module
|
|
36
|
+
* @param {object} pluginModule - Plugin module or class
|
|
37
|
+
* @param {string} pluginType - Plugin _type (loader, embedder, etc.)
|
|
38
|
+
* @returns {object} Extracted metadata
|
|
39
|
+
*/
|
|
40
|
+
extractMetadata(pluginModule, pluginType) {
|
|
41
|
+
// Try different metadata export patterns
|
|
42
|
+
let metadata = null;
|
|
43
|
+
|
|
44
|
+
// Pattern 1: Static metadata property
|
|
45
|
+
if (pluginModule.metadata) {
|
|
46
|
+
metadata = pluginModule.metadata;
|
|
47
|
+
}
|
|
48
|
+
// Pattern 2: getMetadata() method
|
|
49
|
+
else if (typeof pluginModule.getMetadata === 'function') {
|
|
50
|
+
metadata = pluginModule.getMetadata();
|
|
51
|
+
}
|
|
52
|
+
// Pattern 3: Class constructor with static metadata
|
|
53
|
+
else if (
|
|
54
|
+
typeof pluginModule === 'function' &&
|
|
55
|
+
pluginModule.prototype &&
|
|
56
|
+
pluginModule.constructor.metadata
|
|
57
|
+
) {
|
|
58
|
+
metadata = pluginModule.constructor.metadata;
|
|
59
|
+
}
|
|
60
|
+
// Pattern 4: Default export with metadata
|
|
61
|
+
else if (pluginModule.default && pluginModule.default.metadata) {
|
|
62
|
+
metadata = pluginModule.default.metadata;
|
|
63
|
+
}
|
|
64
|
+
// Pattern 5: Package.json style metadata
|
|
65
|
+
else if (pluginModule.package) {
|
|
66
|
+
metadata = this.convertPackageJsonMetadata(
|
|
67
|
+
pluginModule.package,
|
|
68
|
+
pluginType,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!metadata) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
'Plugin does not export required metadata. Please add a \'metadata\' property or \'getMetadata()\' method.',
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Ensure type is set correctly
|
|
79
|
+
if (!metadata._type) {
|
|
80
|
+
metadata._type = pluginType;
|
|
81
|
+
} else if (metadata._type !== pluginType) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`Plugin metadata _type '${metadata._type}' does not match expected _type '${pluginType}'`,
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return this.validateAndNormalizeMetadata(metadata);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Convert package.json style metadata to plugin metadata format
|
|
92
|
+
* @param {object} packageData - Package.json data
|
|
93
|
+
* @param {string} pluginType - Plugin _type
|
|
94
|
+
* @returns {object} Plugin metadata
|
|
95
|
+
*/
|
|
96
|
+
convertPackageJsonMetadata(packageData, pluginType) {
|
|
97
|
+
return {
|
|
98
|
+
name: packageData.name,
|
|
99
|
+
version: packageData.version,
|
|
100
|
+
_type: pluginType,
|
|
101
|
+
description: packageData.description,
|
|
102
|
+
author:
|
|
103
|
+
typeof packageData.author === 'string'
|
|
104
|
+
? packageData.author
|
|
105
|
+
: packageData.author?.name,
|
|
106
|
+
homepage: packageData.homepage,
|
|
107
|
+
repository: packageData.repository,
|
|
108
|
+
keywords: packageData.keywords,
|
|
109
|
+
license: packageData.license,
|
|
110
|
+
engines: packageData.engines,
|
|
111
|
+
dependencies: packageData.dependencies,
|
|
112
|
+
peerDependencies: packageData.peerDependencies,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Validate and normalize plugin metadata
|
|
118
|
+
* @param {object} metadata - Raw metadata
|
|
119
|
+
* @returns {object} Validated and normalized metadata
|
|
120
|
+
*/
|
|
121
|
+
validateAndNormalizeMetadata(metadata) {
|
|
122
|
+
// Validate required fields
|
|
123
|
+
for (const field of this.requiredFields) {
|
|
124
|
+
if (!metadata[field]) {
|
|
125
|
+
throw new Error(`Plugin metadata missing required field: ${field}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Validate plugin name
|
|
130
|
+
const nameValidation = PLUGIN_NAMING.validateName(metadata.name);
|
|
131
|
+
if (!nameValidation.valid) {
|
|
132
|
+
throw new Error(`Invalid plugin name: ${nameValidation.reason}`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Validate version format
|
|
136
|
+
if (!VersionUtils.parseVersion(metadata.version)) {
|
|
137
|
+
throw new Error(`Invalid version format: ${metadata.version}`);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Validate using schema
|
|
141
|
+
const schemaValidation = validatePluginMetadata(metadata);
|
|
142
|
+
if (!schemaValidation.valid) {
|
|
143
|
+
const errors = schemaValidation.errors
|
|
144
|
+
.map((err) => `${err.instancePath}: ${err.message}`)
|
|
145
|
+
.join(', ');
|
|
146
|
+
throw new Error(`Plugin metadata validation failed: ${errors}`);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Normalize and set defaults
|
|
150
|
+
const normalized = {
|
|
151
|
+
...metadata,
|
|
152
|
+
keywords: metadata.keywords || [],
|
|
153
|
+
tags: metadata.tags || [],
|
|
154
|
+
engines: metadata.engines || {},
|
|
155
|
+
dependencies: metadata.dependencies || {},
|
|
156
|
+
peerDependencies: metadata.peerDependencies || {},
|
|
157
|
+
_config: metadata._config || {},
|
|
158
|
+
examples: metadata.examples || [],
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// Add automatic tags based on plugin characteristics
|
|
162
|
+
normalized.tags = this.addAutomaticTags(normalized);
|
|
163
|
+
|
|
164
|
+
return normalized;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Add automatic tags based on plugin characteristics
|
|
169
|
+
* @param {object} metadata - Plugin metadata
|
|
170
|
+
* @returns {Array<string>} Updated tags
|
|
171
|
+
*/
|
|
172
|
+
addAutomaticTags(metadata) {
|
|
173
|
+
const tags = new Set(metadata.tags || []);
|
|
174
|
+
|
|
175
|
+
// Add type-based tag
|
|
176
|
+
tags.add(metadata._type);
|
|
177
|
+
|
|
178
|
+
// Add version stability tags
|
|
179
|
+
const version = VersionUtils.parseVersion(metadata.version);
|
|
180
|
+
if (version.isPrerelease) {
|
|
181
|
+
if (version.prerelease[0] === 'alpha') {
|
|
182
|
+
tags.add('alpha');
|
|
183
|
+
} else if (version.prerelease[0] === 'beta') {
|
|
184
|
+
tags.add('beta');
|
|
185
|
+
} else {
|
|
186
|
+
tags.add('prerelease');
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
tags.add('stable');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Add dependency-based tags
|
|
193
|
+
if (Object.keys(metadata.dependencies).length === 0) {
|
|
194
|
+
tags.add('zero-dependencies');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Add feature tags based on config schema
|
|
198
|
+
if (metadata._config && Object.keys(metadata._config).length > 0) {
|
|
199
|
+
tags.add('configurable');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Add example tags
|
|
203
|
+
if (metadata.examples && metadata.examples.length > 0) {
|
|
204
|
+
tags.add('documented');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return Array.from(tags);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Generate plugin manifest for publishing
|
|
212
|
+
* @param {object} metadata - Plugin metadata
|
|
213
|
+
* @param {object} _options - Generation _options
|
|
214
|
+
* @returns {object} Plugin manifest
|
|
215
|
+
*/
|
|
216
|
+
generateManifest(metadata, _options = {}) {
|
|
217
|
+
const manifest = {
|
|
218
|
+
...metadata,
|
|
219
|
+
publishedAt: new Date().toISOString(),
|
|
220
|
+
integrity: _options.integrity,
|
|
221
|
+
size: _options.size,
|
|
222
|
+
downloadUrl: _options.downloadUrl,
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// Add build information if available
|
|
226
|
+
if (_options.buildInfo) {
|
|
227
|
+
manifest.build = {
|
|
228
|
+
timestamp: _options.buildInfo.timestamp,
|
|
229
|
+
commit: _options.buildInfo.commit,
|
|
230
|
+
branch: _options.buildInfo.branch,
|
|
231
|
+
environment: _options.buildInfo.environment,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return manifest;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Plugin metadata decorator for easy metadata definition
|
|
241
|
+
* @param {object} metadata - Plugin metadata
|
|
242
|
+
* @returns {Function} Class decorator
|
|
243
|
+
*/
|
|
244
|
+
function pluginMetadata(metadata) {
|
|
245
|
+
return function (target) {
|
|
246
|
+
target.metadata = metadata;
|
|
247
|
+
return target;
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Plugin metadata validation middleware
|
|
253
|
+
* Validates plugin metadata during registration
|
|
254
|
+
*/
|
|
255
|
+
class PluginMetadataValidator {
|
|
256
|
+
constructor() {
|
|
257
|
+
this.extractor = new PluginMetadataExtractor();
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Validate plugin during registration
|
|
262
|
+
* @param {string} _type - Plugin _type
|
|
263
|
+
* @param {string} name - Plugin name
|
|
264
|
+
* @param {object} plugin - Plugin _instance
|
|
265
|
+
* @returns {object} Validation result with metadata
|
|
266
|
+
*/
|
|
267
|
+
validatePlugin(_type, name, plugin) {
|
|
268
|
+
try {
|
|
269
|
+
const metadata = this.extractor.extractMetadata(plugin, _type);
|
|
270
|
+
|
|
271
|
+
// Verify name matches registration name
|
|
272
|
+
if (metadata.name !== name) {
|
|
273
|
+
throw new Error(
|
|
274
|
+
`Plugin metadata name '${metadata.name}' does not match registration name '${name}'`,
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return {
|
|
279
|
+
valid: true,
|
|
280
|
+
metadata,
|
|
281
|
+
warnings: this.generateWarnings(metadata),
|
|
282
|
+
};
|
|
283
|
+
} catch (error) {
|
|
284
|
+
return {
|
|
285
|
+
valid: false,
|
|
286
|
+
error: error.message,
|
|
287
|
+
metadata: null,
|
|
288
|
+
warnings: [],
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Generate warnings for plugin metadata
|
|
295
|
+
* @param {object} metadata - Plugin metadata
|
|
296
|
+
* @returns {Array<string>} Warning messages
|
|
297
|
+
*/
|
|
298
|
+
generateWarnings(metadata) {
|
|
299
|
+
const warnings = [];
|
|
300
|
+
|
|
301
|
+
// Check for missing optional but recommended fields
|
|
302
|
+
if (!metadata.homepage) {
|
|
303
|
+
warnings.push(
|
|
304
|
+
'Consider adding a homepage URL for better discoverability',
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (!metadata.repository) {
|
|
309
|
+
warnings.push('Consider adding repository information for transparency');
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (!metadata.license) {
|
|
313
|
+
warnings.push('Consider specifying a license for legal clarity');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (!metadata.keywords || metadata.keywords.length === 0) {
|
|
317
|
+
warnings.push('Consider adding keywords to improve searchability');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (!metadata.examples || metadata.examples.length === 0) {
|
|
321
|
+
warnings.push('Consider adding usage examples for better documentation');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Check version format
|
|
325
|
+
const version = VersionUtils.parseVersion(metadata.version);
|
|
326
|
+
if (version.major === 0) {
|
|
327
|
+
warnings.push(
|
|
328
|
+
'Version 0.x.x indicates unstable API - consider releasing 1.0.0 when stable',
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Check description length
|
|
333
|
+
if (metadata.description.length < 20) {
|
|
334
|
+
warnings.push('Consider providing a more detailed description');
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
return warnings;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Plugin metadata utilities
|
|
343
|
+
*/
|
|
344
|
+
const MetadataUtils = {
|
|
345
|
+
/**
|
|
346
|
+
* Create metadata template for new plugins
|
|
347
|
+
* @param {string} _type - Plugin _type
|
|
348
|
+
* @param {string} name - Plugin name
|
|
349
|
+
* @param {object} _options - Template _options
|
|
350
|
+
* @returns {object} Metadata template
|
|
351
|
+
*/
|
|
352
|
+
createTemplate(_type, name, _options = {}) {
|
|
353
|
+
return {
|
|
354
|
+
name,
|
|
355
|
+
version: '1.0.0',
|
|
356
|
+
_type,
|
|
357
|
+
description: `A ${_type} plugin for RAG pipeline`,
|
|
358
|
+
author: _options.author || 'Unknown',
|
|
359
|
+
homepage: _options.homepage || '',
|
|
360
|
+
repository: _options.repository || {
|
|
361
|
+
_type: 'git',
|
|
362
|
+
url: '',
|
|
363
|
+
},
|
|
364
|
+
keywords: [_type, 'rag', 'plugin'],
|
|
365
|
+
license: _options.license || 'MIT',
|
|
366
|
+
engines: {
|
|
367
|
+
node: '>=18.0.0',
|
|
368
|
+
'rag-pipeline-utils': '>=2.0.0',
|
|
369
|
+
},
|
|
370
|
+
dependencies: {},
|
|
371
|
+
peerDependencies: {},
|
|
372
|
+
_config: {
|
|
373
|
+
_type: 'object',
|
|
374
|
+
properties: {},
|
|
375
|
+
additionalProperties: false,
|
|
376
|
+
},
|
|
377
|
+
examples: [
|
|
378
|
+
{
|
|
379
|
+
title: 'Basic Usage',
|
|
380
|
+
description: `Basic ${_type} plugin usage`,
|
|
381
|
+
_config: {},
|
|
382
|
+
},
|
|
383
|
+
],
|
|
384
|
+
tags: [],
|
|
385
|
+
};
|
|
386
|
+
},
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Merge metadata with defaults
|
|
390
|
+
* @param {object} metadata - User metadata
|
|
391
|
+
* @param {object} defaults - Default metadata
|
|
392
|
+
* @returns {object} Merged metadata
|
|
393
|
+
*/
|
|
394
|
+
mergeWithDefaults(metadata, defaults) {
|
|
395
|
+
return {
|
|
396
|
+
...defaults,
|
|
397
|
+
...metadata,
|
|
398
|
+
keywords: [...(defaults.keywords || []), ...(metadata.keywords || [])],
|
|
399
|
+
tags: [...(defaults.tags || []), ...(metadata.tags || [])],
|
|
400
|
+
engines: { ...defaults.engines, ...metadata.engines },
|
|
401
|
+
dependencies: { ...defaults.dependencies, ...metadata.dependencies },
|
|
402
|
+
peerDependencies: {
|
|
403
|
+
...defaults.peerDependencies,
|
|
404
|
+
...metadata.peerDependencies,
|
|
405
|
+
},
|
|
406
|
+
examples: [...(defaults.examples || []), ...(metadata.examples || [])],
|
|
407
|
+
};
|
|
408
|
+
},
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Compare metadata versions
|
|
412
|
+
* @param {object} metadata1 - First metadata
|
|
413
|
+
* @param {object} metadata2 - Second metadata
|
|
414
|
+
* @returns {number} Comparison result (-1, 0, 1)
|
|
415
|
+
*/
|
|
416
|
+
compareVersions(metadata1, metadata2) {
|
|
417
|
+
return VersionUtils.compareVersions(metadata1.version, metadata2.version);
|
|
418
|
+
},
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Check if metadata is compatible with requirements
|
|
422
|
+
* @param {object} metadata - Plugin metadata
|
|
423
|
+
* @param {object} requirements - Compatibility requirements
|
|
424
|
+
* @returns {{ compatible: boolean, issues: Array<string> }}
|
|
425
|
+
*/
|
|
426
|
+
checkCompatibility(metadata, requirements) {
|
|
427
|
+
const issues = [];
|
|
428
|
+
|
|
429
|
+
// Check engine requirements
|
|
430
|
+
if (requirements.engines) {
|
|
431
|
+
for (const [engine, requiredVersion] of Object.entries(
|
|
432
|
+
requirements.engines,
|
|
433
|
+
)) {
|
|
434
|
+
const pluginVersion = metadata.engines?.[engine];
|
|
435
|
+
if (
|
|
436
|
+
pluginVersion &&
|
|
437
|
+
!VersionUtils.satisfiesRequirement(requiredVersion, pluginVersion)
|
|
438
|
+
) {
|
|
439
|
+
issues.push(
|
|
440
|
+
`Engine '${engine}' requirement not satisfied: requires ${pluginVersion}, have ${requiredVersion}`,
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Check peer dependencies
|
|
447
|
+
if (requirements.peerDependencies && metadata.peerDependencies) {
|
|
448
|
+
for (const [dep, requiredVersion] of Object.entries(
|
|
449
|
+
requirements.peerDependencies,
|
|
450
|
+
)) {
|
|
451
|
+
const pluginVersion = metadata.peerDependencies[dep];
|
|
452
|
+
if (
|
|
453
|
+
pluginVersion &&
|
|
454
|
+
!VersionUtils.satisfiesRequirement(requiredVersion, pluginVersion)
|
|
455
|
+
) {
|
|
456
|
+
issues.push(
|
|
457
|
+
`Peer dependency '${dep}' version mismatch: requires ${pluginVersion}, have ${requiredVersion}`,
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
return {
|
|
464
|
+
compatible: issues.length === 0,
|
|
465
|
+
issues,
|
|
466
|
+
};
|
|
467
|
+
},
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
// Global metadata extractor instance
|
|
471
|
+
const metadataExtractor = new PluginMetadataExtractor();
|
|
472
|
+
|
|
473
|
+
// Global metadata validator instance
|
|
474
|
+
const metadataValidator = new PluginMetadataValidator();
|
|
475
|
+
|
|
476
|
+
// Default export
|
|
477
|
+
|
|
478
|
+
module.exports = {
|
|
479
|
+
PluginMetadataExtractor,
|
|
480
|
+
PluginMetadataValidator,
|
|
481
|
+
pluginMetadata,
|
|
482
|
+
MetadataUtils,
|
|
483
|
+
metadataExtractor,
|
|
484
|
+
metadataValidator,
|
|
485
|
+
};
|