@devilsdev/rag-pipeline-utils 1.0.1 ā 2.0.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/.codecov.yml +21 -0
- package/.github/workflows/ci.yml +18 -0
- package/.github/workflows/docs-deploy.yml +36 -0
- package/.github/workflows/publish-release-blog.yml +51 -0
- package/.husky/pre-commit +6 -0
- package/CHANGELOG.md +40 -0
- package/README.md +101 -72
- package/USE_CASES.md +134 -0
- package/__tests__/fixtures/.ragrc.json +8 -0
- package/__tests__/fixtures/invalid-ragrc.json +4 -0
- package/__tests__/fixtures/src/mocks/openai-embedder.js +16 -0
- package/__tests__/fixtures/src/mocks/openai-llm.js +9 -0
- package/__tests__/fixtures/src/mocks/pdf-loader.js +17 -0
- package/__tests__/fixtures/src/mocks/pinecone-retriever.js +26 -0
- package/__tests__/fixtures/valid-ragrc.json +16 -0
- package/__tests__/integration/cli/config-flow.test.js +84 -15
- package/__tests__/integration/config/load-config.test.js +45 -30
- package/__tests__/unit/config/validate-schema.test.js +121 -0
- package/__tests__/unit/reranker/llm-reranker.test.js +9 -33
- package/__tests__/unit/reranker/reranker.enriched.test.js +19 -0
- package/__tests__/unit/reranker/reranker.fallback.test.js +15 -0
- package/__tests__/unit/reranker/reranker.snapshot.test.js +9 -11
- package/__tests__/unit/reranker/reranker.structured-output.test.js +17 -0
- package/bin/cli.js +49 -155
- package/docs-site/blog/2021-08-26-welcome/index.md +0 -1
- package/docs-site/blog/2025-04-17-release-2.0.md +67 -0
- package/docs-site/blog/2025-04-18-release-2.0.0.md +21 -0
- package/docs-site/blog/authors.yml +5 -23
- package/docs-site/blog/tags.yml +9 -0
- package/docs-site/docs/USE_CASES.md +0 -0
- package/docs-site/docusaurus.config.js +13 -0
- package/docs-site/sidebars.js +21 -9
- package/package.json +25 -2
- package/plugin.config.json +14 -0
- package/scripts/banner-injector.js +89 -0
- package/scripts/ci-runner.js +51 -0
- package/scripts/repair-fixtures.js +30 -0
- package/scripts/setup.js +26 -2
- package/scripts/validate-changelog-version.js +48 -0
- package/scripts/verify-fixture-mocks.js +45 -0
- package/scripts/verify-fixtures.js +36 -0
- package/src/config/load-config.js +19 -21
- package/src/config/load-plugin-config.js +56 -0
- package/src/config/validate-plugin-schema.js +28 -0
- package/src/config/validate-schema.js +88 -30
- package/src/core/create-pipeline.js +40 -26
- package/src/core/plugin-contracts.js +21 -0
- package/src/core/plugin-registry.js +4 -17
- package/src/mocks/openai-embedder.js +30 -0
- package/src/mocks/openai-llm.js +18 -0
- package/src/mocks/pdf-loader.js +17 -0
- package/src/mocks/pinecone-retriever.js +25 -0
- package/src/reranker/llm-reranker.js +28 -43
- package/src/utils/ci/diagnostic-reporter.js +36 -0
- package/src/utils/validate-plugin-contract.js +36 -0
- package/.github/workflows/release.yml +0 -20
- package/docs-site/blog/2019-05-28-first-blog-post.md +0 -12
- package/docs-site/blog/2019-05-29-long-blog-post.md +0 -44
- package/docs-site/blog/2021-08-01-mdx-blog-post.mdx +0 -24
package/bin/cli.js
CHANGED
|
@@ -1,168 +1,62 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* Version:
|
|
5
|
-
*
|
|
6
|
-
* Description: CLI interface for rag-pipeline utilities with loaders, reranker, and evaluation
|
|
2
|
+
* Version: 1.1.0
|
|
3
|
+
* Description: Final CLI entrypoint with dynamic plugin loading and full config validation
|
|
7
4
|
* Author: Ali Kahwaji
|
|
8
5
|
*/
|
|
9
6
|
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
7
|
+
import { resolve } from 'path';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
12
9
|
import { loadRagConfig } from '../src/config/load-config.js';
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import { LLMReranker } from '../src/reranker/llm-reranker.js';
|
|
10
|
+
import { loadPluginsFromJson } from '../src/config/load-plugin-config.js';
|
|
11
|
+
import registry from '../src/core/plugin-registry.js';
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import { DirectoryLoader } from '../src/loader/directory-loader.js';
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = resolve(__filename, '..');
|
|
15
|
+
const CONFIG_PATH = resolve('.ragrc.json');
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
async load(filePath) {
|
|
25
|
-
return [{ chunk: () => [`Test loaded: ${filePath}`] }];
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
class OpenAIEmbedder {
|
|
29
|
-
async embed(chunks) {
|
|
30
|
-
return chunks.map((text, i) => ({ id: `v${i}`, values: [0.1, 0.2, 0.3], metadata: { text } }));
|
|
31
|
-
}
|
|
32
|
-
async embedQuery(prompt) {
|
|
33
|
-
return [0.1, 0.2, 0.3];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
class PineconeRetriever {
|
|
37
|
-
async store() {}
|
|
38
|
-
async retrieve() {
|
|
39
|
-
return [
|
|
40
|
-
{ id: 'a', text: 'Chunk about pine trees', metadata: {} },
|
|
41
|
-
{ id: 'b', text: 'Chunk about vectors', metadata: {} },
|
|
42
|
-
{ id: 'c', text: 'Chunk about databases', metadata: {} }
|
|
43
|
-
];
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
class OpenAILLM {
|
|
47
|
-
async generate(prompt, context) {
|
|
48
|
-
return `Generated answer using: ${context.map(d => d.text).join(', ')}`;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
const command = args[0];
|
|
51
19
|
|
|
52
|
-
|
|
53
|
-
registry.register('loader', 'pdf', new PDFLoader());
|
|
54
|
-
registry.register('loader', 'markdown', new MarkdownLoader());
|
|
55
|
-
registry.register('loader', 'html', new HTMLLoader());
|
|
56
|
-
registry.register('loader', 'csv', new CSVLoader());
|
|
57
|
-
registry.register('loader', 'directory', new DirectoryLoader());
|
|
58
|
-
registry.register('embedder', 'openai', new OpenAIEmbedder());
|
|
59
|
-
registry.register('retriever', 'pinecone', new PineconeRetriever());
|
|
60
|
-
registry.register('llm', 'openai-gpt-4', new OpenAILLM());
|
|
61
|
-
|
|
62
|
-
const program = new Command();
|
|
63
|
-
program
|
|
64
|
-
.name('rag-pipeline')
|
|
65
|
-
.description('CLI for RAG pipeline utilities')
|
|
66
|
-
.version('0.1.8');
|
|
67
|
-
|
|
68
|
-
function resolveConfig(cliOpts) {
|
|
20
|
+
async function runCLI() {
|
|
69
21
|
try {
|
|
70
|
-
const
|
|
71
|
-
|
|
22
|
+
const config = loadRagConfig(CONFIG_PATH);
|
|
23
|
+
await loadPluginsFromJson(CONFIG_PATH);
|
|
24
|
+
|
|
25
|
+
switch (command) {
|
|
26
|
+
case 'ingest': {
|
|
27
|
+
const input = args[1];
|
|
28
|
+
const loader = registry.get('loader', Object.keys(config.loader)[0]);
|
|
29
|
+
const embedder = registry.get('embedder', Object.keys(config.embedder)[0]);
|
|
30
|
+
const retriever = registry.get('retriever', Object.keys(config.retriever)[0]);
|
|
31
|
+
|
|
32
|
+
const docs = await loader.load(input);
|
|
33
|
+
const vectors = await embedder.embed(docs);
|
|
34
|
+
await retriever.store(vectors, config.namespace);
|
|
35
|
+
|
|
36
|
+
console.log('Ingestion complete');
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case 'query': {
|
|
40
|
+
const question = args.slice(1).join(' ');
|
|
41
|
+
const embedder = registry.get('embedder', Object.keys(config.embedder)[0]);
|
|
42
|
+
const retriever = registry.get('retriever', Object.keys(config.retriever)[0]);
|
|
43
|
+
const llm = registry.get('llm', Object.keys(config.llm)[0]);
|
|
44
|
+
|
|
45
|
+
const queryVec = await embedder.embedQuery(question);
|
|
46
|
+
const docs = await retriever.search(queryVec, config.namespace);
|
|
47
|
+
const answer = await llm.ask(question, docs);
|
|
48
|
+
|
|
49
|
+
console.log('Answer:', answer);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
default:
|
|
53
|
+
console.error('Unknown command:', command);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
72
56
|
} catch (err) {
|
|
73
|
-
|
|
74
|
-
|
|
57
|
+
console.error('Error during execution:', err.message);
|
|
58
|
+
process.exit(1);
|
|
75
59
|
}
|
|
76
60
|
}
|
|
77
61
|
|
|
78
|
-
|
|
79
|
-
.command('ingest')
|
|
80
|
-
.argument('<path>', 'Path to document(s)')
|
|
81
|
-
.option('--loader <type>', 'Document loader type')
|
|
82
|
-
.option('--embedder <type>', 'Embedder type')
|
|
83
|
-
.option('--retriever <type>', 'Vector store retriever type')
|
|
84
|
-
.action(async (docPath, opts) => {
|
|
85
|
-
try {
|
|
86
|
-
const config = resolveConfig(opts);
|
|
87
|
-
const pipeline = createRagPipeline(config);
|
|
88
|
-
await pipeline.ingest(docPath);
|
|
89
|
-
console.log('Ingestion complete'); // required by test assertion
|
|
90
|
-
} catch (err) {
|
|
91
|
-
logger.error({ error: err.message }, 'Ingestion failed');
|
|
92
|
-
console.error('Error during ingestion:', err.message);
|
|
93
|
-
process.exit(1);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
program
|
|
98
|
-
.command('query')
|
|
99
|
-
.argument('<prompt>', 'Prompt to submit')
|
|
100
|
-
.option('--embedder <type>', 'Embedder type')
|
|
101
|
-
.option('--retriever <type>', 'Retriever type')
|
|
102
|
-
.option('--llm <type>', 'LLM type')
|
|
103
|
-
.action(async (prompt, opts) => {
|
|
104
|
-
try {
|
|
105
|
-
const config = resolveConfig(opts);
|
|
106
|
-
const pipeline = createRagPipeline(config);
|
|
107
|
-
const answer = await pipeline.query(prompt);
|
|
108
|
-
console.log('\n Answer:\n', answer);
|
|
109
|
-
} catch (err) {
|
|
110
|
-
logger.error({ error: err.message }, 'Query failed');
|
|
111
|
-
process.exit(1);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
program
|
|
116
|
-
.command('evaluate')
|
|
117
|
-
.argument('<dataset>', 'Path to JSON file of evaluation cases')
|
|
118
|
-
.option('--embedder <type>', 'Embedder type')
|
|
119
|
-
.option('--retriever <type>', 'Retriever type')
|
|
120
|
-
.option('--llm <type>', 'LLM type')
|
|
121
|
-
.action(async (dataset, opts) => {
|
|
122
|
-
try {
|
|
123
|
-
const config = resolveConfig(opts);
|
|
124
|
-
const results = await evaluateRagDataset(dataset, config);
|
|
125
|
-
const passRate = results.filter(r => r.success).length / results.length;
|
|
126
|
-
const avgBLEU = results.reduce((sum, r) => sum + r.scores.bleu, 0) / results.length;
|
|
127
|
-
const avgROUGE = results.reduce((sum, r) => sum + r.scores.rouge, 0) / results.length;
|
|
128
|
-
|
|
129
|
-
results.forEach((r, i) => {
|
|
130
|
-
console.log(`\nCase ${i + 1}:\nPrompt: ${r.prompt}\nPass: ${r.success}\nBLEU: ${r.scores.bleu.toFixed(2)}\nROUGE: ${r.scores.rouge.toFixed(2)}`);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
console.log(`\n Summary:\nPassed: ${Math.round(passRate * 100)}%\nAvg BLEU: ${avgBLEU.toFixed(2)}\nAvg ROUGE: ${avgROUGE.toFixed(2)}`);
|
|
134
|
-
} catch (err) {
|
|
135
|
-
logger.error({ error: err.message }, 'Evaluation failed');
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
program
|
|
141
|
-
.command('rerank')
|
|
142
|
-
.argument('<prompt>', 'Prompt to rerank context for')
|
|
143
|
-
.option('--retriever <type>', 'Retriever type')
|
|
144
|
-
.option('--llm <type>', 'LLM type')
|
|
145
|
-
.action(async (prompt, opts) => {
|
|
146
|
-
try {
|
|
147
|
-
const config = resolveConfig(opts);
|
|
148
|
-
const retriever = registry.get('retriever', config.retriever);
|
|
149
|
-
const llm = registry.get('llm', config.llm);
|
|
150
|
-
const embedder = registry.get('embedder', config.embedder);
|
|
151
|
-
|
|
152
|
-
const queryVector = await embedder.embedQuery(prompt);
|
|
153
|
-
const docs = await retriever.retrieve(queryVector);
|
|
154
|
-
|
|
155
|
-
const reranker = new LLMReranker({ llm });
|
|
156
|
-
const reranked = await reranker.rerank(prompt, docs);
|
|
157
|
-
|
|
158
|
-
console.log('\n Reranked Results:');
|
|
159
|
-
reranked.forEach((doc, i) => {
|
|
160
|
-
console.log(`\n#${i + 1}: ${doc.text}`);
|
|
161
|
-
});
|
|
162
|
-
} catch (err) {
|
|
163
|
-
logger.error({ error: err.message }, 'Rerank failed');
|
|
164
|
-
process.exit(1);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
program.parse();
|
|
62
|
+
await runCLI();
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
slug: release-2-0
|
|
3
|
+
title: Release 2.0.0 ā Plugin Contracts, CI Automation, Docs
|
|
4
|
+
authors: [ali]
|
|
5
|
+
tags: [release, changelog]
|
|
6
|
+
description: RAG Pipeline Utils v2.0.0 introduces plugin contract validation, full CI coverage, fixture repairs, and professional Docusaurus docs.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
Weāre thrilled to announce the release of **RAG Pipeline Utils v2.0.0** ā a fully modular and developer-focused toolkit for constructing, validating, and managing RAG (Retrieval-Augmented Generation) pipelines.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## š Highlights in v2.0.0
|
|
14
|
+
|
|
15
|
+
### š Contract-Based Plugin Validation
|
|
16
|
+
|
|
17
|
+
- Enforces strict interfaces for all core plugin types:
|
|
18
|
+
- `loader.load()`
|
|
19
|
+
- `embedder.embed()` and `embedQuery()`
|
|
20
|
+
- `retriever.store()` and `search()`
|
|
21
|
+
- `llm.ask()`
|
|
22
|
+
- Includes auto-verification and CLI validation via `scripts/verify-fixture-mocks.js`
|
|
23
|
+
|
|
24
|
+
### š§Ŗ Enhanced CI & Git Hooks
|
|
25
|
+
|
|
26
|
+
- Full GitHub Actions integration:
|
|
27
|
+
- Lint, test, mock validation, release automation
|
|
28
|
+
- Local enforcement using **Husky** + **validate-changelog-version.js**
|
|
29
|
+
|
|
30
|
+
### š§° Fixture Repair & Auto-Mock Utilities
|
|
31
|
+
|
|
32
|
+
- Self-healing script: `scripts/repair-fixtures.js`
|
|
33
|
+
- Support for regenerating mocks that align with runtime requirements and CLI tests
|
|
34
|
+
|
|
35
|
+
### š Developer Documentation
|
|
36
|
+
|
|
37
|
+
- Professionally published Docusaurus site:
|
|
38
|
+
- š [Visit Docs](https://devilsdev.github.io/rag-pipeline-utils)
|
|
39
|
+
- š§ Usage, architecture, CLI, plugin extension, and release notes
|
|
40
|
+
- Blog support enabled for continuous release announcements
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## ⨠Why This Matters
|
|
45
|
+
|
|
46
|
+
This release marks a shift from traditional monolithic RAG stacks to a **fully composable, testable, and CI-validated** toolkit. It was built with long-term developer experience (DX) in mind, emphasizing:
|
|
47
|
+
|
|
48
|
+
- š¦ **Modularity**: Swap or add plugins without rewriting pipeline logic
|
|
49
|
+
- š§Ŗ **Test Confidence**: Never publish broken mocks or CI regressions again
|
|
50
|
+
- š§ **Scalability**: Suitable for both small prototypes and production pipelines
|
|
51
|
+
- š **Tooling First**: Includes everything from config loading to evaluation dashboards
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## š¦ Install Now
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install @devilsdev/rag-pipeline-utils
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
For upgrade guides, contract schemas, and real-world examples, check out the [official docs](https://devilsdev.github.io/rag-pipeline-utils/docs/Introduction).
|
|
64
|
+
|
|
65
|
+
š§ Built for engineers who want **control, clarity, and composability** in their LLM workflows.
|
|
66
|
+
|
|
67
|
+
ā *Ali Kahwaji & RAG Pipeline Utils Contributors*
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
slug: release-2-0-0
|
|
3
|
+
title: Release 2.0.0 ā Modular RAG Toolkit
|
|
4
|
+
authors: ali
|
|
5
|
+
tags: [release, changelog, RAG, developer-tools]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
š **Version 2.0.0** is now live on [npm](https://www.npmjs.com/package/@devilsdev/rag-pipeline-utils)!
|
|
9
|
+
|
|
10
|
+
This release introduces:
|
|
11
|
+
|
|
12
|
+
- ā
Plugin contracts for loaders, embedders, retrievers, LLMs
|
|
13
|
+
- š§Ŗ Fixture mock verification + CLI validation
|
|
14
|
+
- š§° Auto-repair tooling for broken test mocks
|
|
15
|
+
- š¦ Seamless integration with `.ragrc.json` config fallback
|
|
16
|
+
- š Docusaurus documentation & blog support
|
|
17
|
+
- š” Modern DX with versioned docs, coverage, CI hooks, changelogs
|
|
18
|
+
|
|
19
|
+
Explore docs ā [devilsdev.github.io/rag-pipeline-utils](https://devilsdev.github.io/rag-pipeline-utils)
|
|
20
|
+
|
|
21
|
+
š Run `npm install @devilsdev/rag-pipeline-utils` to get started.
|
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
name:
|
|
3
|
-
title:
|
|
4
|
-
url: https://github.com/
|
|
5
|
-
image_url:
|
|
6
|
-
page: true
|
|
7
|
-
socials:
|
|
8
|
-
x: yangshunz
|
|
9
|
-
github: yangshun
|
|
10
|
-
|
|
11
|
-
slorber:
|
|
12
|
-
name: SƩbastien Lorber
|
|
13
|
-
title: Docusaurus maintainer
|
|
14
|
-
url: https://sebastienlorber.com
|
|
15
|
-
image_url: https://github.com/slorber.png
|
|
16
|
-
page:
|
|
17
|
-
# customize the url of the author page at /blog/authors/<permalink>
|
|
18
|
-
permalink: '/all-sebastien-lorber-articles'
|
|
19
|
-
socials:
|
|
20
|
-
x: sebastienlorber
|
|
21
|
-
linkedin: sebastienlorber
|
|
22
|
-
github: slorber
|
|
23
|
-
newsletter: https://thisweekinreact.com
|
|
1
|
+
ali:
|
|
2
|
+
name: Ali Kahwaji
|
|
3
|
+
title: Creator of RAG Pipeline Utils
|
|
4
|
+
url: https://github.com/DevilsDev
|
|
5
|
+
image_url: /img/authors/ali.jpg
|
package/docs-site/blog/tags.yml
CHANGED
|
File without changes
|
|
@@ -18,6 +18,13 @@ export default {
|
|
|
18
18
|
// ā
Final favicon and social card for branding
|
|
19
19
|
favicon: 'img/favicon.ico',
|
|
20
20
|
themeConfig: {
|
|
21
|
+
|
|
22
|
+
// algolia: {
|
|
23
|
+
// appId: 'YOUR_APP_ID',
|
|
24
|
+
// apiKey: 'YOUR_PUBLIC_API_KEY',
|
|
25
|
+
// indexName: 'rag_pipeline_utils',
|
|
26
|
+
// contextualSearch: true,
|
|
27
|
+
// },
|
|
21
28
|
image: 'img/social-card.jpg',
|
|
22
29
|
navbar: {
|
|
23
30
|
title: 'RAG Utils',
|
|
@@ -48,6 +55,12 @@ export default {
|
|
|
48
55
|
sidebarPath: require.resolve('./sidebars.js'),
|
|
49
56
|
editUrl: 'https://github.com/DevilsDev/rag-pipeline-utils/edit/main/docs-site/'
|
|
50
57
|
},
|
|
58
|
+
|
|
59
|
+
blog: {
|
|
60
|
+
showReadingTime: true,
|
|
61
|
+
editUrl: 'https://github.com/DevilsDev/rag-pipeline-utils/edit/main/docs-site/blog/',
|
|
62
|
+
},
|
|
63
|
+
|
|
51
64
|
theme: {
|
|
52
65
|
customCss: require.resolve('./src/css/custom.css')
|
|
53
66
|
}
|
package/docs-site/sidebars.js
CHANGED
|
@@ -2,21 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Sidebar configuration for RAG Pipeline Utils documentation site
|
|
5
|
-
*
|
|
5
|
+
* Version: 2.0.0
|
|
6
6
|
* Author: Ali Kahwaji
|
|
7
|
+
* Updated: Structured for modular clarity and DX
|
|
7
8
|
* @type {import('@docusaurus/plugin-content-docs').SidebarsConfig}
|
|
8
9
|
*/
|
|
9
10
|
|
|
10
11
|
const sidebars = {
|
|
11
12
|
tutorialSidebar: [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
{
|
|
14
|
+
type: 'category',
|
|
15
|
+
label: 'Overview',
|
|
16
|
+
collapsed: false,
|
|
17
|
+
items: ['Introduction', 'Architecture', 'USE_CASES'],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
type: 'category',
|
|
21
|
+
label: 'Developer Guide',
|
|
22
|
+
collapsed: false,
|
|
23
|
+
items: ['Usage', 'CLI', 'Plugins'],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
type: 'category',
|
|
27
|
+
label: 'Advanced',
|
|
28
|
+
collapsed: true,
|
|
29
|
+
items: ['Evaluation', 'FAQ'],
|
|
30
|
+
},
|
|
31
|
+
],
|
|
20
32
|
};
|
|
21
33
|
|
|
22
34
|
export default sidebars;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devilsdev/rag-pipeline-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "A modular toolkit for building RAG (Retrieval-Augmented Generation) pipelines in Node.js",
|
|
5
5
|
"main": "src/core/create-pipeline.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,10 +8,27 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"scripts": {
|
|
11
|
+
"validate-fixtures": "node ./scripts/verify-fixtures.js",
|
|
12
|
+
"setup": "node ./scripts/setup.js",
|
|
11
13
|
"test": "node ./scripts/setup.js && cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage",
|
|
12
14
|
"test:watch": "jest --watch",
|
|
13
15
|
"lint": "eslint .",
|
|
14
|
-
"prepare": "husky install"
|
|
16
|
+
"prepare": "husky install",
|
|
17
|
+
"lint-staged": "lint-staged",
|
|
18
|
+
"postinstall": "husky install",
|
|
19
|
+
"verify:mocks": "node scripts/verify-fixture-mocks.js",
|
|
20
|
+
"build:docs": "npx docusaurus build docs-site",
|
|
21
|
+
"ci": "node scripts/ci-runner.js",
|
|
22
|
+
"docs:dev": "npx docusaurus start docs-site",
|
|
23
|
+
"docs:build": "npx docusaurus build docs-site",
|
|
24
|
+
"docs:deploy": "npx docusaurus deploy docs-site",
|
|
25
|
+
"docs:version": "npx docusaurus docs:version"
|
|
26
|
+
},
|
|
27
|
+
"lint-staged": {
|
|
28
|
+
"**/*.{js,ts}": [
|
|
29
|
+
"npm run lint",
|
|
30
|
+
"npm run validate-fixtures"
|
|
31
|
+
]
|
|
15
32
|
},
|
|
16
33
|
"repository": {
|
|
17
34
|
"type": "git",
|
|
@@ -36,6 +53,8 @@
|
|
|
36
53
|
"access": "public"
|
|
37
54
|
},
|
|
38
55
|
"devDependencies": {
|
|
56
|
+
"@docusaurus/core": "^3.7.0",
|
|
57
|
+
"@docusaurus/preset-classic": "^3.7.0",
|
|
39
58
|
"@semantic-release/changelog": "^6.0.3",
|
|
40
59
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
41
60
|
"@semantic-release/git": "^10.0.1",
|
|
@@ -43,17 +62,21 @@
|
|
|
43
62
|
"@semantic-release/npm": "^11.0.3",
|
|
44
63
|
"@semantic-release/release-notes-generator": "^14.0.3",
|
|
45
64
|
"@types/jest": "^29.5.14",
|
|
65
|
+
"codecov": "^3.8.2",
|
|
46
66
|
"cross-env": "^7.0.3",
|
|
67
|
+
"docusaurus": "^1.14.7",
|
|
47
68
|
"esbuild": "^0.25.2",
|
|
48
69
|
"eslint": "^8.57.1",
|
|
49
70
|
"husky": "^8.0.3",
|
|
50
71
|
"jest": "^29.7.0",
|
|
72
|
+
"lint-staged": "^15.5.1",
|
|
51
73
|
"prettier": "^3.5.3",
|
|
52
74
|
"rimraf": "^6.0.1",
|
|
53
75
|
"semantic-release": "^21.1.2",
|
|
54
76
|
"ts-jest": "^29.3.2"
|
|
55
77
|
},
|
|
56
78
|
"dependencies": {
|
|
79
|
+
"ajv": "^8.17.1",
|
|
57
80
|
"axios": "^1.8.4",
|
|
58
81
|
"chalk": "^5.4.1",
|
|
59
82
|
"commander": "^13.1.0",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"loader": {
|
|
3
|
+
"pdf": "./src/mocks/pdf-loader.js"
|
|
4
|
+
},
|
|
5
|
+
"embedder": {
|
|
6
|
+
"openai": "./src/mocks/openai-embedder.js"
|
|
7
|
+
},
|
|
8
|
+
"retriever": {
|
|
9
|
+
"pinecone": "./src/mocks/pinecone-retriever.js"
|
|
10
|
+
},
|
|
11
|
+
"llm": {
|
|
12
|
+
"openai-gpt-4": "./src/mocks/openai-llm.js"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File: scripts/banner-injector.js
|
|
3
|
+
* Description: Script to programmatically inject file-level banners into specified project files
|
|
4
|
+
* Author: Ali Kahwaji
|
|
5
|
+
* Version: 1.0.0
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import glob from 'glob';
|
|
11
|
+
|
|
12
|
+
const banners = {
|
|
13
|
+
'__tests__/unit/reranker/llm-reranker.test.js': `/**
|
|
14
|
+
* File: __tests__/unit/reranker/llm-reranker.test.js
|
|
15
|
+
* Description: Unit and integration tests with mocks for RAG pipeline
|
|
16
|
+
* Author: Ali Kahwaji
|
|
17
|
+
* Version: 1.0.4
|
|
18
|
+
*/\n\n`,
|
|
19
|
+
|
|
20
|
+
'__tests__/unit/reranker/reranker.snapshot.test.js': `/**
|
|
21
|
+
* File: __tests__/unit/reranker/reranker.snapshot.test.js
|
|
22
|
+
* Description: Snapshot tests for LLM reranker
|
|
23
|
+
* Author: Ali Kahwaji
|
|
24
|
+
* Version: 1.0.4
|
|
25
|
+
*/\n\n`,
|
|
26
|
+
|
|
27
|
+
'__tests__/unit/core/plugin-registry.test.js': `/**
|
|
28
|
+
* File: __tests__/unit/core/plugin-registry.test.js
|
|
29
|
+
* Description: Unit and integration tests with mocks for RAG pipeline
|
|
30
|
+
* Author: Ali Kahwaji
|
|
31
|
+
* Version: 1.0.4
|
|
32
|
+
*/\n\n`,
|
|
33
|
+
|
|
34
|
+
'__tests__/integration/config/load-config.test.js': `/**
|
|
35
|
+
* File: __tests__/integration/config/load-config.test.js
|
|
36
|
+
* Description: Unit and integration tests with mocks for RAG pipeline
|
|
37
|
+
* Author: Ali Kahwaji
|
|
38
|
+
* Version: 1.0.4
|
|
39
|
+
*/\n\n`,
|
|
40
|
+
|
|
41
|
+
'__tests__/integration/cli/config-flow.test.js': `/**
|
|
42
|
+
* File: __tests__/integration/cli/config-flow.test.js
|
|
43
|
+
* Description: Unit and integration tests with mocks for RAG pipeline
|
|
44
|
+
* Author: Ali Kahwaji
|
|
45
|
+
* Version: 1.0.4
|
|
46
|
+
*/\n\n`,
|
|
47
|
+
|
|
48
|
+
'src/mocks/pdf-loader.js': `/**
|
|
49
|
+
* File: src/mocks/pdf-loader.js
|
|
50
|
+
* Description: Unit and integration tests with mocks for RAG pipeline
|
|
51
|
+
* Author: Ali Kahwaji
|
|
52
|
+
* Version: 1.0.4
|
|
53
|
+
*/\n\n`,
|
|
54
|
+
|
|
55
|
+
'src/mocks/openai-embedder.js': `/**
|
|
56
|
+
* File: src/mocks/openai-embedder.js
|
|
57
|
+
* Description: Unit and integration tests with mocks for RAG pipeline
|
|
58
|
+
* Author: Ali Kahwaji
|
|
59
|
+
* Version: 1.0.4
|
|
60
|
+
*/\n\n`,
|
|
61
|
+
|
|
62
|
+
'src/mocks/pinecone-retriever.js': `/**
|
|
63
|
+
* File: src/mocks/pinecone-retriever.js
|
|
64
|
+
* Description: Unit and integration tests with mocks for RAG pipeline
|
|
65
|
+
* Author: Ali Kahwaji
|
|
66
|
+
* Version: 1.0.4
|
|
67
|
+
*/\n\n`
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
Object.entries(banners).forEach(([filePath, banner]) => {
|
|
71
|
+
const resolvedPath = path.resolve(filePath);
|
|
72
|
+
|
|
73
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
74
|
+
console.warn(`[SKIPPED] ${filePath} does not exist.`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const originalContent = fs.readFileSync(resolvedPath, 'utf-8');
|
|
79
|
+
|
|
80
|
+
// Skip if banner already present
|
|
81
|
+
if (originalContent.startsWith('/**')) {
|
|
82
|
+
console.log(`[SKIPPED] ${filePath} already contains a banner.`);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const newContent = banner + originalContent;
|
|
87
|
+
fs.writeFileSync(resolvedPath, newContent, 'utf-8');
|
|
88
|
+
console.log(`[INJECTED] Banner added to ${filePath}`);
|
|
89
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Version: 1.1.0
|
|
3
|
+
* Description: CI runner for linting, mock validation, testing and coverage
|
|
4
|
+
* Author: Ali Kahwaji
|
|
5
|
+
* File: scripts/ci-runner.js
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execSync } from 'child_process';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import { pathToFileURL } from 'url';
|
|
11
|
+
import fs from 'fs';
|
|
12
|
+
|
|
13
|
+
// Entry helpers
|
|
14
|
+
const ROOT = path.resolve();
|
|
15
|
+
const resolveScript = (relPath) => pathToFileURL(path.resolve(ROOT, relPath)).href;
|
|
16
|
+
|
|
17
|
+
const run = (label, command) => {
|
|
18
|
+
console.log(`\nš§ Running: ${label}`);
|
|
19
|
+
try {
|
|
20
|
+
execSync(command, { stdio: 'inherit', cwd: ROOT });
|
|
21
|
+
console.log(`ā
${label} passed`);
|
|
22
|
+
} catch (err) {
|
|
23
|
+
console.error(`ā ${label} failed`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const runDynamicModule = async (label, modulePath) => {
|
|
29
|
+
console.log(`\nš Validating: ${label}`);
|
|
30
|
+
try {
|
|
31
|
+
const mod = await import(resolveScript(modulePath));
|
|
32
|
+
if (typeof mod.default === 'function') await mod.default();
|
|
33
|
+
console.log(`ā
${label} passed`);
|
|
34
|
+
} catch (err) {
|
|
35
|
+
console.error(`ā ${label} failed:\n${err.message}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
(async () => {
|
|
41
|
+
// Step 1: Lint
|
|
42
|
+
run('Lint', 'npx eslint . --ext .js,.ts');
|
|
43
|
+
|
|
44
|
+
// Step 2: Verify mocks for required interface methods
|
|
45
|
+
await runDynamicModule('Fixture Mock Interface Validation', 'scripts/verify-fixture-mocks.js');
|
|
46
|
+
|
|
47
|
+
// Step 3: Test and coverage
|
|
48
|
+
run('Unit + Integration Tests w/ Coverage', 'cross-env NODE_OPTIONS=--experimental-vm-modules jest --coverage');
|
|
49
|
+
|
|
50
|
+
console.log('\nš CI runner completed successfully.\n');
|
|
51
|
+
})();
|