@aiconnect/easy-rag 0.3.1 → 1.0.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 (66) hide show
  1. package/README.md +100 -28
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +105 -3
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/config/types.d.ts +3 -0
  6. package/dist/config/types.d.ts.map +1 -1
  7. package/dist/eval/index.d.ts +10 -0
  8. package/dist/eval/index.d.ts.map +1 -0
  9. package/dist/eval/index.js +37 -0
  10. package/dist/eval/index.js.map +1 -0
  11. package/dist/eval/metrics.d.ts +12 -0
  12. package/dist/eval/metrics.d.ts.map +1 -0
  13. package/dist/eval/metrics.js +43 -0
  14. package/dist/eval/metrics.js.map +1 -0
  15. package/dist/eval/reporter.d.ts +7 -0
  16. package/dist/eval/reporter.d.ts.map +1 -0
  17. package/dist/eval/reporter.js +105 -0
  18. package/dist/eval/reporter.js.map +1 -0
  19. package/dist/eval/runner.d.ts +8 -0
  20. package/dist/eval/runner.d.ts.map +1 -0
  21. package/dist/eval/runner.js +43 -0
  22. package/dist/eval/runner.js.map +1 -0
  23. package/dist/eval/test-cases.d.ts +3 -0
  24. package/dist/eval/test-cases.d.ts.map +1 -0
  25. package/dist/eval/test-cases.js +98 -0
  26. package/dist/eval/test-cases.js.map +1 -0
  27. package/dist/eval/types.d.ts +49 -0
  28. package/dist/eval/types.d.ts.map +1 -0
  29. package/dist/eval/types.js +2 -0
  30. package/dist/eval/types.js.map +1 -0
  31. package/dist/index.js +10 -45
  32. package/dist/index.js.map +1 -1
  33. package/dist/indexer/orchestrator.d.ts.map +1 -1
  34. package/dist/indexer/orchestrator.js +24 -6
  35. package/dist/indexer/orchestrator.js.map +1 -1
  36. package/dist/query/hybrid.d.ts +17 -0
  37. package/dist/query/hybrid.d.ts.map +1 -0
  38. package/dist/query/hybrid.js +116 -0
  39. package/dist/query/hybrid.js.map +1 -0
  40. package/dist/query/index.d.ts.map +1 -1
  41. package/dist/query/index.js +81 -16
  42. package/dist/query/index.js.map +1 -1
  43. package/dist/query/search.d.ts +7 -4
  44. package/dist/query/search.d.ts.map +1 -1
  45. package/dist/query/search.js +45 -40
  46. package/dist/query/search.js.map +1 -1
  47. package/dist/query/types.d.ts +8 -0
  48. package/dist/query/types.d.ts.map +1 -1
  49. package/dist/vector-store/index.d.ts +3 -2
  50. package/dist/vector-store/index.d.ts.map +1 -1
  51. package/dist/vector-store/index.js +2 -2
  52. package/dist/vector-store/index.js.map +1 -1
  53. package/dist/vector-store/tokenizer.d.ts +3 -0
  54. package/dist/vector-store/tokenizer.d.ts.map +1 -0
  55. package/dist/vector-store/tokenizer.js +91 -0
  56. package/dist/vector-store/tokenizer.js.map +1 -0
  57. package/dist/vector-store/utils.d.ts +4 -1
  58. package/dist/vector-store/utils.d.ts.map +1 -1
  59. package/dist/vector-store/utils.js +17 -6
  60. package/dist/vector-store/utils.js.map +1 -1
  61. package/dist/vector-store/zvec.d.ts +15 -0
  62. package/dist/vector-store/zvec.d.ts.map +1 -0
  63. package/dist/vector-store/zvec.js +136 -0
  64. package/dist/vector-store/zvec.js.map +1 -0
  65. package/package.json +5 -4
  66. package/skills/easy-rag/SKILL.md +40 -9
@@ -1,2 +1,5 @@
1
- export declare function ensureChromaDataDirectory(): Promise<string>;
1
+ export declare const COLLECTIONS_DIR: string;
2
+ export declare function ensureCollectionsDirectory(): string;
3
+ export declare function getCollectionPath(name: string): string;
4
+ export declare function sanitizeCollectionName(name: string): string;
2
5
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/vector-store/utils.ts"],"names":[],"mappings":"AAMA,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,MAAM,CAAC,CAYjE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/vector-store/utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,eAAe,QAAsD,CAAC;AAEnF,wBAAgB,0BAA0B,IAAI,MAAM,CAYnD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI3D"}
@@ -1,17 +1,28 @@
1
1
  import os from 'os';
2
2
  import path from 'path';
3
- import fs from 'fs/promises';
4
- const CHROMA_DATA_DIR = path.join(os.homedir(), '.easy-rag', 'chromadb');
5
- export async function ensureChromaDataDirectory() {
3
+ import fs from 'fs';
4
+ export const COLLECTIONS_DIR = path.join(os.homedir(), '.easy-rag', 'collections');
5
+ export function ensureCollectionsDirectory() {
6
6
  try {
7
- await fs.mkdir(CHROMA_DATA_DIR, { recursive: true });
8
- return CHROMA_DATA_DIR;
7
+ fs.mkdirSync(COLLECTIONS_DIR, { recursive: true });
8
+ return COLLECTIONS_DIR;
9
9
  }
10
10
  catch (error) {
11
11
  if (error instanceof Error && 'code' in error && error.code === 'EACCES') {
12
- throw new Error(`Cannot write to ${CHROMA_DATA_DIR}. Please check directory permissions.`);
12
+ throw new Error(`Cannot write to ${COLLECTIONS_DIR}. Please check directory permissions.`);
13
13
  }
14
14
  throw error;
15
15
  }
16
16
  }
17
+ export function getCollectionPath(name) {
18
+ const sanitized = name
19
+ .replace(/[^a-zA-Z0-9_-]/g, '_')
20
+ .toLowerCase();
21
+ return path.join(COLLECTIONS_DIR, sanitized);
22
+ }
23
+ export function sanitizeCollectionName(name) {
24
+ return name
25
+ .replace(/[^a-zA-Z0-9_-]/g, '_')
26
+ .toLowerCase();
27
+ }
17
28
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/vector-store/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,aAAa,CAAC;AAE7B,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;AAEzE,MAAM,CAAC,KAAK,UAAU,yBAAyB;IAC7C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,OAAO,eAAe,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACzE,MAAM,IAAI,KAAK,CACb,mBAAmB,eAAe,uCAAuC,CAC1E,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/vector-store/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;AAEnF,MAAM,UAAU,0BAA0B;IACxC,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,OAAO,eAAe,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpG,MAAM,IAAI,KAAK,CACb,mBAAmB,eAAe,uCAAuC,CAC1E,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,SAAS,GAAG,IAAI;SACnB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;SAC/B,WAAW,EAAE,CAAC;IACjB,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,IAAI;SACR,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC;SAC/B,WAAW,EAAE,CAAC;AACnB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import zvec from '@zvec/zvec';
2
+ import type { VectorChunk, CollectionInfo } from './types.js';
3
+ declare const ZVecCreateAndOpen: typeof zvec.ZVecCreateAndOpen;
4
+ type ZVecCollection = ReturnType<typeof ZVecCreateAndOpen>;
5
+ export declare function getDimensionForModel(model: string): number;
6
+ export declare function getOrCreateCollection(baseName: string, embeddingModel?: string): ZVecCollection;
7
+ export declare function openCollection(name: string): ZVecCollection;
8
+ export interface SparseChunk extends VectorChunk {
9
+ sparseEmbedding: Record<number, number>;
10
+ }
11
+ export declare function storeEmbeddings(collection: ZVecCollection, chunks: SparseChunk[]): void;
12
+ export declare function listCollections(): CollectionInfo[];
13
+ export declare function deleteCollection(collectionName: string): void;
14
+ export {};
15
+ //# sourceMappingURL=zvec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zvec.d.ts","sourceRoot":"","sources":["../../src/vector-store/zvec.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,YAAY,CAAC;AAC9B,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG9D,QAAA,MAEE,iBAAiB,+BAKX,CAAC;AAET,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAQ3D,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAiCD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,cAAc,GAAE,MAAiC,GAChD,cAAc,CAgBhB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAM3D;AAED,MAAM,WAAW,WAAY,SAAQ,WAAW;IAC9C,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,cAAc,EAC1B,MAAM,EAAE,WAAW,EAAE,GACpB,IAAI,CAqCN;AAED,wBAAgB,eAAe,IAAI,cAAc,EAAE,CAyBlD;AAED,wBAAgB,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAc7D"}
@@ -0,0 +1,136 @@
1
+ import fs from 'fs';
2
+ import zvec from '@zvec/zvec';
3
+ import { ensureCollectionsDirectory, getCollectionPath, sanitizeCollectionName } from './utils.js';
4
+ const { ZVecCollectionSchema, ZVecCreateAndOpen, ZVecOpen, ZVecDataType, ZVecMetricType, ZVecIndexType, } = zvec;
5
+ const EMBEDDING_DIMENSIONS = {
6
+ 'text-embedding-3-large': 3072,
7
+ 'text-embedding-3-small': 1536,
8
+ 'text-embedding-ada-002': 1536,
9
+ };
10
+ export function getDimensionForModel(model) {
11
+ return EMBEDDING_DIMENSIONS[model] ?? 3072;
12
+ }
13
+ function buildSchema(name, dimension) {
14
+ return new ZVecCollectionSchema({
15
+ name,
16
+ fields: [
17
+ { name: 'content', dataType: ZVecDataType.STRING },
18
+ { name: 'sourcePath', dataType: ZVecDataType.STRING },
19
+ { name: 'contentType', dataType: ZVecDataType.STRING },
20
+ { name: 'chunkIndex', dataType: ZVecDataType.INT64 },
21
+ { name: 'sectionTitle', dataType: ZVecDataType.STRING, nullable: true },
22
+ { name: 'startPosition', dataType: ZVecDataType.INT64, nullable: true },
23
+ { name: 'endPosition', dataType: ZVecDataType.INT64, nullable: true },
24
+ { name: 'rowNumber', dataType: ZVecDataType.INT64, nullable: true },
25
+ ],
26
+ vectors: [
27
+ {
28
+ name: 'embedding',
29
+ dataType: ZVecDataType.VECTOR_FP32,
30
+ dimension,
31
+ indexParams: {
32
+ indexType: ZVecIndexType.HNSW,
33
+ metricType: ZVecMetricType.COSINE,
34
+ },
35
+ },
36
+ {
37
+ name: 'sparse_embedding',
38
+ dataType: ZVecDataType.SPARSE_VECTOR_FP32,
39
+ },
40
+ ],
41
+ });
42
+ }
43
+ export function getOrCreateCollection(baseName, embeddingModel = 'text-embedding-3-large') {
44
+ ensureCollectionsDirectory();
45
+ const sanitized = sanitizeCollectionName(baseName);
46
+ const collectionPath = getCollectionPath(baseName);
47
+ const dimension = getDimensionForModel(embeddingModel);
48
+ if (fs.existsSync(collectionPath)) {
49
+ const collection = ZVecOpen(collectionPath);
50
+ console.log(`Using collection: ${sanitized}`);
51
+ return collection;
52
+ }
53
+ const schema = buildSchema(sanitized, dimension);
54
+ const collection = ZVecCreateAndOpen(collectionPath, schema);
55
+ console.log(`Using collection: ${sanitized}`);
56
+ return collection;
57
+ }
58
+ export function openCollection(name) {
59
+ const collectionPath = getCollectionPath(name);
60
+ if (!fs.existsSync(collectionPath)) {
61
+ throw new Error(`Collection "${name}" not found at ${collectionPath}`);
62
+ }
63
+ return ZVecOpen(collectionPath);
64
+ }
65
+ export function storeEmbeddings(collection, chunks) {
66
+ if (chunks.length === 0) {
67
+ return;
68
+ }
69
+ const docs = chunks.map((c) => {
70
+ const fields = {
71
+ content: c.content,
72
+ sourcePath: c.metadata.sourcePath,
73
+ contentType: c.metadata.contentType,
74
+ chunkIndex: c.metadata.chunkIndex,
75
+ };
76
+ if (c.metadata.sectionTitle !== undefined) {
77
+ fields.sectionTitle = c.metadata.sectionTitle;
78
+ }
79
+ if (c.metadata.startPosition !== undefined) {
80
+ fields.startPosition = c.metadata.startPosition;
81
+ }
82
+ if (c.metadata.endPosition !== undefined) {
83
+ fields.endPosition = c.metadata.endPosition;
84
+ }
85
+ if (c.metadata.rowNumber !== undefined) {
86
+ fields.rowNumber = c.metadata.rowNumber;
87
+ }
88
+ return {
89
+ id: c.id,
90
+ vectors: {
91
+ embedding: c.embedding,
92
+ sparse_embedding: c.sparseEmbedding,
93
+ },
94
+ fields,
95
+ };
96
+ });
97
+ collection.insertSync(docs);
98
+ }
99
+ export function listCollections() {
100
+ const collectionsBase = ensureCollectionsDirectory();
101
+ if (!fs.existsSync(collectionsBase)) {
102
+ return [];
103
+ }
104
+ const entries = fs.readdirSync(collectionsBase);
105
+ const collectionInfos = [];
106
+ for (const entry of entries) {
107
+ const entryPath = `${collectionsBase}/${entry}`;
108
+ if (!fs.statSync(entryPath).isDirectory())
109
+ continue;
110
+ try {
111
+ const collection = ZVecOpen(entryPath);
112
+ const count = collection.stats.docCount;
113
+ collection.closeSync();
114
+ collectionInfos.push({ name: entry, count });
115
+ }
116
+ catch {
117
+ collectionInfos.push({ name: entry, count: 0 });
118
+ }
119
+ }
120
+ return collectionInfos;
121
+ }
122
+ export function deleteCollection(collectionName) {
123
+ const sanitized = sanitizeCollectionName(collectionName);
124
+ const collectionPath = getCollectionPath(collectionName);
125
+ if (!fs.existsSync(collectionPath)) {
126
+ throw new Error(`Collection "${sanitized}" not found.`);
127
+ }
128
+ try {
129
+ const collection = ZVecOpen(collectionPath);
130
+ collection.destroySync();
131
+ }
132
+ catch {
133
+ fs.rmSync(collectionPath, { recursive: true, force: true });
134
+ }
135
+ }
136
+ //# sourceMappingURL=zvec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zvec.js","sourceRoot":"","sources":["../../src/vector-store/zvec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiconnect/easy-rag",
3
- "version": "0.3.1",
3
+ "version": "1.0.0",
4
4
  "description": "A TypeScript CLI tool for local RAG indexing and querying",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "cli",
29
29
  "vector-search",
30
30
  "embeddings",
31
- "chromadb",
31
+ "zvec",
32
32
  "openai",
33
33
  "retrieval-augmented-generation"
34
34
  ],
@@ -43,13 +43,14 @@
43
43
  "@types/node": "^22.19.11",
44
44
  "jest": "^29.7.0",
45
45
  "ts-jest": "^29.4.6",
46
+ "tsx": "^4.21.0",
46
47
  "typescript": "^5.9.3"
47
48
  },
48
49
  "dependencies": {
50
+ "@zvec/zvec": "^0.2.3",
49
51
  "commander": "^13.1.0",
50
- "pdf-parse": "^1.1.1",
51
52
  "openai": "^4.89.0",
52
- "chromadb": "^2.1.5"
53
+ "pdf-parse": "^1.1.1"
53
54
  },
54
55
  "engines": {
55
56
  "node": ">=18.0.0"
@@ -3,7 +3,7 @@ name: easy-rag
3
3
  description: >
4
4
  Index documents and query them using local RAG (Retrieval-Augmented Generation).
5
5
  Use when you need to build a knowledge base from files (PDF, Markdown, CSV) and
6
- search it with natural language questions. Runs locally with ChromaDB embedded.
6
+ search it with natural language questions. Runs locally with Zvec embedded.
7
7
  ---
8
8
 
9
9
  # Easy RAG Skill
@@ -17,7 +17,7 @@ description: >
17
17
  ## Requirements
18
18
 
19
19
  - **OpenAI API key** must be configured (via `easy-rag init` or `OPENAI_API_KEY` env var)
20
- - No external services needed — ChromaDB runs embedded locally
20
+ - No external services needed — Zvec runs embedded locally (no server)
21
21
 
22
22
  ### Setting Up API Key
23
23
 
@@ -57,17 +57,22 @@ Run interactive setup to create global configuration.
57
57
  easy-rag init
58
58
  ```
59
59
 
60
- Prompts for:
60
+ **Basic Settings:**
61
61
  - OpenAI API key (masked input)
62
62
  - Embedding model selection (default: `text-embedding-3-large`)
63
63
 
64
+ **Advanced Settings (optional, prompted after basic setup):**
65
+ - Search mode: auto, hybrid, vector, or bm25 (default: auto)
66
+ - Vector weight: 0.0-1.0 (default: 0.6)
67
+ - BM25 weight: 0.0-1.0 (default: 0.4)
68
+
64
69
  Creates `~/.easy-rag/config.json` with your settings.
65
70
 
66
71
  **Always run this first** before indexing if you haven't configured EasyRAG yet.
67
72
 
68
73
  ### Index Documents
69
74
 
70
- Recursively scans a folder for supported files and indexes them into ChromaDB.
75
+ Recursively scans a folder for supported files and indexes them into Zvec.
71
76
 
72
77
  ```bash
73
78
  easy-rag index <folder>
@@ -86,7 +91,7 @@ easy-rag index ./knowledge-base
86
91
 
87
92
  ### Query Documents
88
93
 
89
- Search indexed documents using natural language. Returns the most relevant chunks.
94
+ Search indexed documents using natural language. Returns most relevant chunks.
90
95
 
91
96
  ```bash
92
97
  easy-rag query [options] "<question>"
@@ -97,17 +102,33 @@ easy-rag query [options] "<question>"
97
102
  | `--top <n>` | Number of results to return | 5 |
98
103
  | `--metadata` | Include source file, score, chunk index | off |
99
104
  | `--collection <name>` | Search a specific collection | all |
105
+ | `--mode <mode>` | Search mode: auto, hybrid, vector, or bm25 | auto |
100
106
 
101
107
  **Examples:**
102
108
  ```bash
103
- # Simple query
104
- easy-rag query "What is the refund policy?"
109
+ # Simple query (hybrid search by default)
110
+ easy-rag query "What is refund policy?"
105
111
 
106
112
  # Top 3 results with metadata
107
- easy-rag query --top 3 --metadata "How do I configure the API?"
113
+ easy-rag query --top 3 --metadata "How do I configure API?"
108
114
 
109
115
  # Search specific collection
110
116
  easy-rag query --collection my-docs "quarterly revenue"
117
+
118
+ # Vector-only search for semantic queries
119
+ easy-rag query --mode vector "how does it work?"
120
+
121
+ # BM25-only search for exact keywords
122
+ easy-rag query --mode bm25 "API endpoint /v1/users"
123
+ ```
124
+
125
+ **Output with `--metadata`:**
126
+ ```
127
+ [Hybrid Score: 0.0142 | Vector: 0.92 (rank: 1) | BM25: 2.5 (rank: 2) | Source: docs/api-guide.md | Chunk: 3]
128
+ To configure the API, set the following environment variables...
129
+
130
+ [Hybrid Score: 0.0121 | Vector: 0.87 (rank: 2) | BM25: 3.1 (rank: 1) | Source: docs/setup.pdf | Chunk: 12]
131
+ The API configuration requires...
111
132
  ```
112
133
 
113
134
  **Output with `--metadata`:**
@@ -183,10 +204,20 @@ Config is stored at `~/.easy-rag/config.json`:
183
204
  ```json
184
205
  {
185
206
  "openai_api_key": "sk-...",
186
- "embedding_model": "text-embedding-3-large"
207
+ "embedding_model": "text-embedding-3-large",
208
+ "search_mode": "auto",
209
+ "vector_weight": 0.6,
210
+ "bm25_weight": 0.4
187
211
  }
188
212
  ```
189
213
 
214
+ **Settings:**
215
+ - `search_mode`: Search mode (auto, hybrid, vector, or bm25)
216
+ - `vector_weight`: Weight for vector results in hybrid search (0.0-1.0)
217
+ - `bm25_weight`: Weight for BM25 results in hybrid search (0.0-1.0)
218
+
219
+ Weights don't need to sum to 1.0 — they are used independently in the RRF formula.
220
+
190
221
  **Priority (highest first):**
191
222
  1. Environment variables
192
223
  2. Config file