rag-lite-ts 1.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/LICENSE +21 -0
- package/README.md +240 -0
- package/dist/api-errors.d.ts +90 -0
- package/dist/api-errors.d.ts.map +1 -0
- package/dist/api-errors.js +320 -0
- package/dist/api-errors.js.map +1 -0
- package/dist/chunker.d.ts +47 -0
- package/dist/chunker.d.ts.map +1 -0
- package/dist/chunker.js +256 -0
- package/dist/chunker.js.map +1 -0
- package/dist/cli/indexer.d.ts +11 -0
- package/dist/cli/indexer.d.ts.map +1 -0
- package/dist/cli/indexer.js +272 -0
- package/dist/cli/indexer.js.map +1 -0
- package/dist/cli/search.d.ts +7 -0
- package/dist/cli/search.d.ts.map +1 -0
- package/dist/cli/search.js +206 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +362 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +90 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +281 -0
- package/dist/config.js.map +1 -0
- package/dist/db.d.ts +90 -0
- package/dist/db.d.ts.map +1 -0
- package/dist/db.js +340 -0
- package/dist/db.js.map +1 -0
- package/dist/embedder.d.ts +101 -0
- package/dist/embedder.d.ts.map +1 -0
- package/dist/embedder.js +323 -0
- package/dist/embedder.js.map +1 -0
- package/dist/error-handler.d.ts +91 -0
- package/dist/error-handler.d.ts.map +1 -0
- package/dist/error-handler.js +196 -0
- package/dist/error-handler.js.map +1 -0
- package/dist/file-processor.d.ts +59 -0
- package/dist/file-processor.d.ts.map +1 -0
- package/dist/file-processor.js +312 -0
- package/dist/file-processor.js.map +1 -0
- package/dist/index-manager.d.ts +99 -0
- package/dist/index-manager.d.ts.map +1 -0
- package/dist/index-manager.js +444 -0
- package/dist/index-manager.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +7 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +51 -0
- package/dist/indexer.js.map +1 -0
- package/dist/ingestion.d.ts +175 -0
- package/dist/ingestion.d.ts.map +1 -0
- package/dist/ingestion.js +705 -0
- package/dist/ingestion.js.map +1 -0
- package/dist/mcp-server.d.ts +14 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +680 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/path-manager.d.ts +42 -0
- package/dist/path-manager.d.ts.map +1 -0
- package/dist/path-manager.js +66 -0
- package/dist/path-manager.js.map +1 -0
- package/dist/preprocess.d.ts +19 -0
- package/dist/preprocess.d.ts.map +1 -0
- package/dist/preprocess.js +203 -0
- package/dist/preprocess.js.map +1 -0
- package/dist/preprocessors/index.d.ts +17 -0
- package/dist/preprocessors/index.d.ts.map +1 -0
- package/dist/preprocessors/index.js +38 -0
- package/dist/preprocessors/index.js.map +1 -0
- package/dist/preprocessors/mdx.d.ts +25 -0
- package/dist/preprocessors/mdx.d.ts.map +1 -0
- package/dist/preprocessors/mdx.js +101 -0
- package/dist/preprocessors/mdx.js.map +1 -0
- package/dist/preprocessors/mermaid.d.ts +68 -0
- package/dist/preprocessors/mermaid.d.ts.map +1 -0
- package/dist/preprocessors/mermaid.js +329 -0
- package/dist/preprocessors/mermaid.js.map +1 -0
- package/dist/preprocessors/registry.d.ts +56 -0
- package/dist/preprocessors/registry.d.ts.map +1 -0
- package/dist/preprocessors/registry.js +179 -0
- package/dist/preprocessors/registry.js.map +1 -0
- package/dist/reranker.d.ts +40 -0
- package/dist/reranker.d.ts.map +1 -0
- package/dist/reranker.js +212 -0
- package/dist/reranker.js.map +1 -0
- package/dist/resource-manager-demo.d.ts +7 -0
- package/dist/resource-manager-demo.d.ts.map +1 -0
- package/dist/resource-manager-demo.js +52 -0
- package/dist/resource-manager-demo.js.map +1 -0
- package/dist/resource-manager.d.ts +129 -0
- package/dist/resource-manager.d.ts.map +1 -0
- package/dist/resource-manager.js +389 -0
- package/dist/resource-manager.js.map +1 -0
- package/dist/search-standalone.d.ts +7 -0
- package/dist/search-standalone.d.ts.map +1 -0
- package/dist/search-standalone.js +117 -0
- package/dist/search-standalone.js.map +1 -0
- package/dist/search.d.ts +92 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +454 -0
- package/dist/search.js.map +1 -0
- package/dist/test-utils.d.ts +36 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +27 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/tokenizer.d.ts +21 -0
- package/dist/tokenizer.d.ts.map +1 -0
- package/dist/tokenizer.js +59 -0
- package/dist/tokenizer.js.map +1 -0
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/vector-index.d.ts +64 -0
- package/dist/vector-index.d.ts.map +1 -0
- package/dist/vector-index.js +308 -0
- package/dist/vector-index.js.map +1 -0
- package/package.json +80 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 RAG-lite TS
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# RAG-lite TS
|
|
2
|
+
*A local-first, TypeScript-friendly retrieval engine*
|
|
3
|
+
|
|
4
|
+
A local-first TypeScript retrieval engine for semantic search over static documents. Built to be lightweight, modular, and hackable with zero external run-time dependencies.
|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- 🏠 **Local-first**: All processing happens offline on your machine
|
|
11
|
+
- 🚀 **Fast**: Sub-100ms queries for typical document collections
|
|
12
|
+
- 📝 **Simple**: No ORMs, frameworks, or complex abstractions
|
|
13
|
+
- 🔍 **Semantic**: Uses embeddings for meaning-based search, not just keywords
|
|
14
|
+
- 🛠️ **Hackable**: Clear module boundaries and minimal dependencies
|
|
15
|
+
- 📦 **Dual Interface**: CLI + MCP server entry points in one package
|
|
16
|
+
- 🎯 **TypeScript**: Full type safety with ESM-only architecture
|
|
17
|
+
- 🧠 **Multi-Model**: Support for multiple embedding models with automatic compatibility checking
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
|
|
21
|
+
- [Quick Start](#quick-start)
|
|
22
|
+
- [How It Works](#how-it-works)
|
|
23
|
+
- [Supported Models](#supported-models)
|
|
24
|
+
- [MCP Server Integration](#mcp-server-integration)
|
|
25
|
+
- [Documentation](#documentation)
|
|
26
|
+
- [Development](#development)
|
|
27
|
+
- [Contributing](#contributing)
|
|
28
|
+
- [License](#license)
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g rag-lite-ts
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Basic Usage
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Ingest documents
|
|
42
|
+
raglite ingest ./docs/
|
|
43
|
+
|
|
44
|
+
# Search your documents
|
|
45
|
+
raglite search "machine learning concepts"
|
|
46
|
+
|
|
47
|
+
# Get more results with reranking
|
|
48
|
+
raglite search "API documentation" --top-k 10 --rerank
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Using Different Models
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Use higher quality model (auto-rebuilds if needed)
|
|
55
|
+
raglite ingest ./docs/ --model Xenova/all-mpnet-base-v2 --rebuild-if-needed
|
|
56
|
+
|
|
57
|
+
# Search automatically uses the correct model
|
|
58
|
+
raglite search "complex query"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Programmatic Usage
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { SearchEngine, IngestionPipeline, initializeEmbeddingEngine } from 'rag-lite-ts';
|
|
65
|
+
|
|
66
|
+
// Initialize and ingest
|
|
67
|
+
const embedder = await initializeEmbeddingEngine();
|
|
68
|
+
const pipeline = new IngestionPipeline('./data/', embedder);
|
|
69
|
+
await pipeline.ingestDirectory('./docs/');
|
|
70
|
+
|
|
71
|
+
// Search
|
|
72
|
+
const searchEngine = new SearchEngine('./vector-index.bin', './db.sqlite');
|
|
73
|
+
const results = await searchEngine.search('machine learning', { top_k: 10 });
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
→ **[Complete CLI Reference](docs/cli-reference.md)** | **[API Documentation](docs/api-reference.md)**
|
|
77
|
+
|
|
78
|
+
## How It Works
|
|
79
|
+
|
|
80
|
+
RAG-lite TS follows a simple pipeline:
|
|
81
|
+
|
|
82
|
+
1. **Document Ingestion**: Reads `.md`, `.txt`, `.mdx`, `.pdf`, and `.docx` files
|
|
83
|
+
2. **Preprocessing**: Cleans content (JSX components, Mermaid diagrams, code blocks)
|
|
84
|
+
3. **Semantic Chunking**: Splits documents at natural boundaries with token limits
|
|
85
|
+
4. **Embedding Generation**: Uses transformers.js models for semantic vectors
|
|
86
|
+
5. **Vector Storage**: Fast similarity search with hnswlib-wasm
|
|
87
|
+
6. **Metadata Storage**: SQLite for document info and model compatibility
|
|
88
|
+
7. **Search**: Embeds queries and finds similar chunks using cosine similarity
|
|
89
|
+
8. **Reranking** (optional): Cross-encoder models for improved relevance
|
|
90
|
+
|
|
91
|
+
### Architecture
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
Documents → Preprocessor → Chunker → Embedder → Vector Index
|
|
95
|
+
↓
|
|
96
|
+
Query → Embedder → Vector Search → SQLite Lookup → Results
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
→ **[Document Preprocessing Guide](docs/preprocessing.md)** | **[Model Management Details](models/README.md)**
|
|
100
|
+
|
|
101
|
+
## Supported Models
|
|
102
|
+
|
|
103
|
+
RAG-lite TS supports multiple embedding models with automatic optimization:
|
|
104
|
+
|
|
105
|
+
| Model | Dimensions | Speed | Use Case |
|
|
106
|
+
|-------|------------|-------|----------|
|
|
107
|
+
| `sentence-transformers/all-MiniLM-L6-v2` | 384 | Fast | General purpose (default) |
|
|
108
|
+
| `Xenova/all-mpnet-base-v2` | 768 | Slower | Higher quality, complex queries |
|
|
109
|
+
|
|
110
|
+
**Model Features:**
|
|
111
|
+
- **Automatic downloads**: Models cached locally on first use
|
|
112
|
+
- **Smart compatibility**: Detects model changes and prompts rebuilds
|
|
113
|
+
- **Offline support**: Pre-download for offline environments
|
|
114
|
+
- **Reranking**: Optional cross-encoder models for better relevance
|
|
115
|
+
|
|
116
|
+
→ **[Complete Model Guide](docs/model-guide.md)** | **[Performance Benchmarks](docs/EMBEDDING_MODELS_COMPARISON.md)**
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
## MCP Server Integration
|
|
122
|
+
|
|
123
|
+
RAG-lite TS includes a Model Context Protocol (MCP) server for integration with AI agents.
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Start MCP server
|
|
127
|
+
raglite-mcp
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**MCP Configuration:**
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"mcpServers": {
|
|
134
|
+
"rag-lite": {
|
|
135
|
+
"command": "raglite-mcp",
|
|
136
|
+
"args": []
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Available Tools:** `search_documents`, `ingest_documents`, `rebuild_index`, `get_stats`
|
|
143
|
+
|
|
144
|
+
→ **[Complete MCP Integration Guide](docs/cli-reference.md#mcp-server)**
|
|
145
|
+
|
|
146
|
+
## Documentation
|
|
147
|
+
|
|
148
|
+
### 📚 Core Guides
|
|
149
|
+
- **[CLI Reference](docs/cli-reference.md)** - Complete command-line documentation
|
|
150
|
+
- **[API Reference](docs/api-reference.md)** - Programmatic usage and types
|
|
151
|
+
- **[Configuration Guide](docs/configuration.md)** - Advanced configuration options
|
|
152
|
+
|
|
153
|
+
### 🔧 Specialized Guides
|
|
154
|
+
- **[Model Selection Guide](docs/model-guide.md)** - Embedding models and performance
|
|
155
|
+
- **[Path Storage Strategies](docs/path-strategies.md)** - Document path management
|
|
156
|
+
- **[Document Preprocessing](docs/preprocessing.md)** - Content processing options
|
|
157
|
+
- **[Troubleshooting Guide](docs/troubleshooting.md)** - Common issues and solutions
|
|
158
|
+
|
|
159
|
+
### 📊 Technical References
|
|
160
|
+
- **[Embedding Models Comparison](docs/EMBEDDING_MODELS_COMPARISON.md)** - Detailed benchmarks
|
|
161
|
+
- **[Documentation Hub](docs/README.md)** - Complete documentation index
|
|
162
|
+
|
|
163
|
+
### Quick Links by Use Case
|
|
164
|
+
|
|
165
|
+
| Use Case | Primary Guide | Supporting Guides |
|
|
166
|
+
|----------|---------------|-------------------|
|
|
167
|
+
| **Getting Started** | [CLI Reference](docs/cli-reference.md) | [Configuration](docs/configuration.md) |
|
|
168
|
+
| **Model Selection** | [Model Guide](docs/model-guide.md) | [Performance Benchmarks](docs/EMBEDDING_MODELS_COMPARISON.md) |
|
|
169
|
+
| **Production Setup** | [Configuration Guide](docs/configuration.md) | [Path Strategies](docs/path-strategies.md) |
|
|
170
|
+
| **File Processing** | [Preprocessing Guide](docs/preprocessing.md) | [Troubleshooting](docs/troubleshooting.md) |
|
|
171
|
+
| **Integration** | [API Reference](docs/api-reference.md) | [Configuration](docs/configuration.md) |
|
|
172
|
+
| **Issue Resolution** | [Troubleshooting Guide](docs/troubleshooting.md) | All guides |
|
|
173
|
+
|
|
174
|
+
## Development
|
|
175
|
+
|
|
176
|
+
### Building from Source
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Clone and setup
|
|
180
|
+
git clone https://github.com/your-username/rag-lite-ts.git
|
|
181
|
+
cd rag-lite-ts
|
|
182
|
+
npm install
|
|
183
|
+
|
|
184
|
+
# Build and link for development
|
|
185
|
+
npm run build
|
|
186
|
+
npm link # Makes raglite/raglite-mcp available globally
|
|
187
|
+
|
|
188
|
+
# Run tests
|
|
189
|
+
npm test
|
|
190
|
+
npm run test:integration
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Project Structure
|
|
194
|
+
|
|
195
|
+
```
|
|
196
|
+
src/
|
|
197
|
+
├── index.ts # Main exports
|
|
198
|
+
├── config.ts # Configuration system
|
|
199
|
+
├── db.ts # SQLite operations
|
|
200
|
+
├── embedder.ts # Embedding generation
|
|
201
|
+
├── search.ts # Search engine
|
|
202
|
+
├── ingestion.ts # Document ingestion
|
|
203
|
+
├── preprocess.ts # Document preprocessing
|
|
204
|
+
├── cli.ts # CLI interface
|
|
205
|
+
├── mcp-server.ts # MCP server
|
|
206
|
+
└── preprocessors/ # Content type processors
|
|
207
|
+
|
|
208
|
+
dist/ # Compiled output
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Design Philosophy
|
|
212
|
+
|
|
213
|
+
**"Boringly Simple" Approach:**
|
|
214
|
+
- ✅ Raw SQLite queries (no ORMs)
|
|
215
|
+
- ✅ Direct function calls (no REST/GraphQL)
|
|
216
|
+
- ✅ Simple configuration objects
|
|
217
|
+
- ✅ Minimal abstractions
|
|
218
|
+
- ❌ No complex frameworks or dependency injection
|
|
219
|
+
|
|
220
|
+
This keeps the codebase hackable and maintainable while providing all functionality needed for local semantic search.
|
|
221
|
+
|
|
222
|
+
## Contributing
|
|
223
|
+
|
|
224
|
+
1. Fork the repository
|
|
225
|
+
2. Create a feature branch
|
|
226
|
+
3. Make your changes
|
|
227
|
+
4. Add tests for new functionality
|
|
228
|
+
5. Ensure all tests pass
|
|
229
|
+
6. Submit a pull request
|
|
230
|
+
|
|
231
|
+
Please maintain the "boringly simple" philosophy - avoid unnecessary abstractions or dependencies.
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
236
|
+
|
|
237
|
+
## Related Projects
|
|
238
|
+
|
|
239
|
+
- **[transformers.js](https://github.com/xenova/transformers.js)** - Client-side ML models
|
|
240
|
+
- **[hnswlib](https://github.com/nmslib/hnswlib)** - Fast approximate nearest neighbor search
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-friendly error classes with actionable suggestions
|
|
3
|
+
* Requirements: 5.3 - Create user-friendly error classes with actionable suggestions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Base class for API errors with actionable suggestions
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class APIError extends Error {
|
|
9
|
+
code: string;
|
|
10
|
+
suggestions: string[];
|
|
11
|
+
context?: string | undefined;
|
|
12
|
+
constructor(message: string, code: string, suggestions: string[], context?: string | undefined);
|
|
13
|
+
/**
|
|
14
|
+
* Get formatted error message with suggestions
|
|
15
|
+
*/
|
|
16
|
+
getFormattedMessage(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Log the error with proper formatting
|
|
19
|
+
*/
|
|
20
|
+
logError(): void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Ingestion-related errors
|
|
24
|
+
*/
|
|
25
|
+
export declare class IngestionError extends APIError {
|
|
26
|
+
constructor(message: string, code: string, suggestions: string[], context?: string);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Search-related errors
|
|
30
|
+
*/
|
|
31
|
+
export declare class SearchError extends APIError {
|
|
32
|
+
constructor(message: string, code: string, suggestions: string[], context?: string);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Resource management errors
|
|
36
|
+
*/
|
|
37
|
+
export declare class ResourceError extends APIError {
|
|
38
|
+
constructor(message: string, code: string, suggestions: string[], context?: string);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Model compatibility errors
|
|
42
|
+
*/
|
|
43
|
+
export declare class ModelCompatibilityError extends APIError {
|
|
44
|
+
constructor(message: string, code: string, suggestions: string[], context?: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Error factory for creating user-friendly errors from internal errors
|
|
48
|
+
* Requirements: 5.3 - Map internal errors to clear guidance
|
|
49
|
+
*/
|
|
50
|
+
export declare class ErrorFactory {
|
|
51
|
+
/**
|
|
52
|
+
* Create user-friendly ingestion error from internal error
|
|
53
|
+
*/
|
|
54
|
+
static createIngestionError(error: unknown, context: string): IngestionError;
|
|
55
|
+
/**
|
|
56
|
+
* Create user-friendly search error from internal error
|
|
57
|
+
*/
|
|
58
|
+
static createSearchError(error: unknown, context: string): SearchError;
|
|
59
|
+
/**
|
|
60
|
+
* Create user-friendly resource error from internal error
|
|
61
|
+
*/
|
|
62
|
+
static createResourceError(error: unknown, context: string): ResourceError;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Common error scenarios with predefined messages and suggestions
|
|
66
|
+
* Requirements: 5.3 - Add specific error handling for common scenarios
|
|
67
|
+
*/
|
|
68
|
+
export declare const CommonErrors: {
|
|
69
|
+
/**
|
|
70
|
+
* Error when trying to search without running ingestion first
|
|
71
|
+
*/
|
|
72
|
+
NO_DOCUMENTS_INGESTED: SearchError;
|
|
73
|
+
/**
|
|
74
|
+
* Error when model versions don't match
|
|
75
|
+
*/
|
|
76
|
+
MODEL_VERSION_MISMATCH: ModelCompatibilityError;
|
|
77
|
+
/**
|
|
78
|
+
* Error when required files are missing
|
|
79
|
+
*/
|
|
80
|
+
MISSING_REQUIRED_FILES: SearchError;
|
|
81
|
+
/**
|
|
82
|
+
* Error when initialization fails
|
|
83
|
+
*/
|
|
84
|
+
INITIALIZATION_FAILED: ResourceError;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Utility function to handle and log errors appropriately
|
|
88
|
+
*/
|
|
89
|
+
export declare function handleAPIError(error: unknown, context: string, operation: 'ingestion' | 'search' | 'resource'): never;
|
|
90
|
+
//# sourceMappingURL=api-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-errors.d.ts","sourceRoot":"","sources":["../src/api-errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,8BAAsB,QAAS,SAAQ,KAAK;IAGjC,IAAI,EAAE,MAAM;IACZ,WAAW,EAAE,MAAM,EAAE;IACrB,OAAO,CAAC,EAAE,MAAM;gBAHvB,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE,MAAM,YAAA;IAMzB;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAa7B;;OAEG;IACH,QAAQ,IAAI,IAAI;CAejB;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,QAAQ;gBAC9B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM;CAGnF;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,QAAQ;gBAC3B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM;CAGnF;AAED;;GAEG;AACH,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM;CAGnF;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,QAAQ;gBACvC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM;CAGnF;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc;IA+G5E;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,WAAW;IA4HtE;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa;CA4C3E;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;;IAYH;;OAEG;;IAYH;;OAEG;;IAYH;;OAEG;;CAYJ,CAAC;AAEF;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,GAAG,QAAQ,GAAG,UAAU,GAAG,KAAK,CA4BrH"}
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-friendly error classes with actionable suggestions
|
|
3
|
+
* Requirements: 5.3 - Create user-friendly error classes with actionable suggestions
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Base class for API errors with actionable suggestions
|
|
7
|
+
*/
|
|
8
|
+
export class APIError extends Error {
|
|
9
|
+
code;
|
|
10
|
+
suggestions;
|
|
11
|
+
context;
|
|
12
|
+
constructor(message, code, suggestions, context) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.suggestions = suggestions;
|
|
16
|
+
this.context = context;
|
|
17
|
+
this.name = this.constructor.name;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get formatted error message with suggestions
|
|
21
|
+
*/
|
|
22
|
+
getFormattedMessage() {
|
|
23
|
+
let formatted = this.message;
|
|
24
|
+
if (this.suggestions.length > 0) {
|
|
25
|
+
formatted += '\n\nSuggestions:';
|
|
26
|
+
this.suggestions.forEach((suggestion, index) => {
|
|
27
|
+
formatted += `\n ${index + 1}. ${suggestion}`;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return formatted;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Log the error with proper formatting
|
|
34
|
+
*/
|
|
35
|
+
logError() {
|
|
36
|
+
console.error(`\n${this.name}: ${this.message}`);
|
|
37
|
+
if (this.context) {
|
|
38
|
+
console.error(`Context: ${this.context}`);
|
|
39
|
+
}
|
|
40
|
+
if (this.suggestions.length > 0) {
|
|
41
|
+
console.error('\nSuggestions:');
|
|
42
|
+
this.suggestions.forEach((suggestion, index) => {
|
|
43
|
+
console.error(` ${index + 1}. ${suggestion}`);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
console.error(''); // Empty line for better readability
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Ingestion-related errors
|
|
51
|
+
*/
|
|
52
|
+
export class IngestionError extends APIError {
|
|
53
|
+
constructor(message, code, suggestions, context) {
|
|
54
|
+
super(message, code, suggestions, context);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Search-related errors
|
|
59
|
+
*/
|
|
60
|
+
export class SearchError extends APIError {
|
|
61
|
+
constructor(message, code, suggestions, context) {
|
|
62
|
+
super(message, code, suggestions, context);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Resource management errors
|
|
67
|
+
*/
|
|
68
|
+
export class ResourceError extends APIError {
|
|
69
|
+
constructor(message, code, suggestions, context) {
|
|
70
|
+
super(message, code, suggestions, context);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Model compatibility errors
|
|
75
|
+
*/
|
|
76
|
+
export class ModelCompatibilityError extends APIError {
|
|
77
|
+
constructor(message, code, suggestions, context) {
|
|
78
|
+
super(message, code, suggestions, context);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Error factory for creating user-friendly errors from internal errors
|
|
83
|
+
* Requirements: 5.3 - Map internal errors to clear guidance
|
|
84
|
+
*/
|
|
85
|
+
export class ErrorFactory {
|
|
86
|
+
/**
|
|
87
|
+
* Create user-friendly ingestion error from internal error
|
|
88
|
+
*/
|
|
89
|
+
static createIngestionError(error, context) {
|
|
90
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
91
|
+
// Handle common error scenarios with specific guidance
|
|
92
|
+
if (errorMessage.includes('ENOENT') || errorMessage.includes('no such file')) {
|
|
93
|
+
if (context === 'path_validation') {
|
|
94
|
+
return new IngestionError(`Directory or file path does not exist: ${errorMessage}`, 'PATH_NOT_FOUND', [
|
|
95
|
+
'Check that the path exists and is accessible',
|
|
96
|
+
'Ensure you have read permissions for the directory',
|
|
97
|
+
'Use an absolute path if the relative path is not working'
|
|
98
|
+
], context);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
return new IngestionError(`Required files not found during ${context}`, 'FILES_NOT_FOUND', [
|
|
102
|
+
'Ensure the base directory exists and is writable',
|
|
103
|
+
'Check file permissions in the target directory',
|
|
104
|
+
'Try using an absolute path instead of a relative path'
|
|
105
|
+
], context);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (errorMessage.includes('EACCES') || errorMessage.includes('permission denied')) {
|
|
109
|
+
return new IngestionError(`Permission denied during ${context}`, 'PERMISSION_DENIED', [
|
|
110
|
+
'Check that you have write permissions to the directory',
|
|
111
|
+
'Try running with appropriate permissions',
|
|
112
|
+
'Ensure the directory is not read-only'
|
|
113
|
+
], context);
|
|
114
|
+
}
|
|
115
|
+
if (errorMessage.includes('ENOSPC') || errorMessage.includes('no space left')) {
|
|
116
|
+
return new IngestionError(`Insufficient disk space during ${context}`, 'DISK_SPACE_FULL', [
|
|
117
|
+
'Free up disk space in the target directory',
|
|
118
|
+
'Choose a different location with more available space',
|
|
119
|
+
'Check disk usage with your system tools'
|
|
120
|
+
], context);
|
|
121
|
+
}
|
|
122
|
+
if (errorMessage.includes('model') && errorMessage.includes('version')) {
|
|
123
|
+
return new ModelCompatibilityError(`Embedding model compatibility issue: ${errorMessage}`, 'MODEL_COMPATIBILITY', [
|
|
124
|
+
'Run pipeline.rebuildIndex() to rebuild with the current model',
|
|
125
|
+
'Or specify the same model that was used during original ingestion',
|
|
126
|
+
'Check the model configuration in your setup'
|
|
127
|
+
], context);
|
|
128
|
+
}
|
|
129
|
+
if (errorMessage.includes('embedding') || errorMessage.includes('model')) {
|
|
130
|
+
return new IngestionError(`Embedding model initialization failed: ${errorMessage}`, 'MODEL_INIT_FAILED', [
|
|
131
|
+
'Check your internet connection for model downloads',
|
|
132
|
+
'Ensure you have sufficient memory available',
|
|
133
|
+
'Try specifying a different embedding model',
|
|
134
|
+
'Check that the model name is correct and supported'
|
|
135
|
+
], context);
|
|
136
|
+
}
|
|
137
|
+
if (errorMessage.includes('database') || errorMessage.includes('sqlite')) {
|
|
138
|
+
return new IngestionError(`Database initialization failed: ${errorMessage}`, 'DATABASE_ERROR', [
|
|
139
|
+
'Check that the database file is not corrupted',
|
|
140
|
+
'Ensure the directory is writable',
|
|
141
|
+
'Try deleting the database file to start fresh',
|
|
142
|
+
'Check for sufficient disk space'
|
|
143
|
+
], context);
|
|
144
|
+
}
|
|
145
|
+
// Generic error with basic suggestions
|
|
146
|
+
return new IngestionError(`${context} failed: ${errorMessage}`, 'GENERAL_ERROR', [
|
|
147
|
+
'Check the error message above for specific details',
|
|
148
|
+
'Ensure all file paths are correct and accessible',
|
|
149
|
+
'Verify you have necessary permissions',
|
|
150
|
+
'Try the operation again or contact support if the issue persists'
|
|
151
|
+
], context);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Create user-friendly search error from internal error
|
|
155
|
+
*/
|
|
156
|
+
static createSearchError(error, context) {
|
|
157
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
158
|
+
// Handle common search error scenarios
|
|
159
|
+
if (context === 'missing_database') {
|
|
160
|
+
return new SearchError(`Database file not found`, 'DATABASE_NOT_FOUND', [
|
|
161
|
+
'Run ingestion first to create the database: pipeline.ingestDirectory("./docs/")',
|
|
162
|
+
'Check that the database path is correct',
|
|
163
|
+
'Ensure the ingestion process completed successfully'
|
|
164
|
+
], context);
|
|
165
|
+
}
|
|
166
|
+
if (context === 'missing_index') {
|
|
167
|
+
return new SearchError(`Vector index file not found`, 'INDEX_NOT_FOUND', [
|
|
168
|
+
'Run ingestion first to create the index: pipeline.ingestDirectory("./docs/")',
|
|
169
|
+
'Check that the index path is correct',
|
|
170
|
+
'Ensure the ingestion process completed successfully'
|
|
171
|
+
], context);
|
|
172
|
+
}
|
|
173
|
+
if (context === 'missing_model_info') {
|
|
174
|
+
return new SearchError('No embedding model information found in database. The database may be from an older version or corrupted.', 'MODEL_INFO_NOT_FOUND', [
|
|
175
|
+
'Run ingestion again to store model information: pipeline.ingestDirectory("./docs/")',
|
|
176
|
+
'If the problem persists, delete the database and index files and run ingestion from scratch',
|
|
177
|
+
'Check that the database was created with a compatible version of the library'
|
|
178
|
+
], context);
|
|
179
|
+
}
|
|
180
|
+
if (context === 'model_loading') {
|
|
181
|
+
return new SearchError(`Failed to load embedding model: ${errorMessage}`, 'MODEL_LOADING_FAILED', [
|
|
182
|
+
'Check that the model name is correct and supported',
|
|
183
|
+
'Ensure you have internet connection for model download',
|
|
184
|
+
'Try running ingestion again with a supported model',
|
|
185
|
+
'Check the model configuration in your setup'
|
|
186
|
+
], context);
|
|
187
|
+
}
|
|
188
|
+
if (context === 'model_compatibility' || (errorMessage.includes('model') && errorMessage.includes('mismatch'))) {
|
|
189
|
+
return new ModelCompatibilityError(`Model compatibility issue detected: ${errorMessage}`, 'MODEL_COMPATIBILITY', [
|
|
190
|
+
'The stored model information doesn\'t match the current configuration',
|
|
191
|
+
'Run pipeline.rebuildIndex() to rebuild with the current model',
|
|
192
|
+
'Or ensure you\'re using the same model that was used during ingestion',
|
|
193
|
+
'Check that the index and database files are from the same ingestion run'
|
|
194
|
+
], context);
|
|
195
|
+
}
|
|
196
|
+
if (errorMessage.includes('ENOENT') || errorMessage.includes('no such file')) {
|
|
197
|
+
return new SearchError(`Required files not found: ${errorMessage}`, 'FILES_NOT_FOUND', [
|
|
198
|
+
'Run ingestion first to create the required files',
|
|
199
|
+
'Check that the file paths are correct',
|
|
200
|
+
'Ensure you have read permissions for the files'
|
|
201
|
+
], context);
|
|
202
|
+
}
|
|
203
|
+
if (errorMessage.includes('EACCES') || errorMessage.includes('permission denied')) {
|
|
204
|
+
return new SearchError(`Permission denied: ${errorMessage}`, 'PERMISSION_DENIED', [
|
|
205
|
+
'Check that you have read permissions for the database and index files',
|
|
206
|
+
'Ensure the files are not locked by another process',
|
|
207
|
+
'Try running with appropriate permissions'
|
|
208
|
+
], context);
|
|
209
|
+
}
|
|
210
|
+
if (errorMessage.includes('database') || errorMessage.includes('sqlite')) {
|
|
211
|
+
return new SearchError(`Database error: ${errorMessage}`, 'DATABASE_ERROR', [
|
|
212
|
+
'Check that the database file is not corrupted',
|
|
213
|
+
'Ensure no other processes are using the database',
|
|
214
|
+
'Try recreating the database by running ingestion again'
|
|
215
|
+
], context);
|
|
216
|
+
}
|
|
217
|
+
// Generic error with basic suggestions
|
|
218
|
+
return new SearchError(`Search engine ${context} failed: ${errorMessage}`, 'GENERAL_ERROR', [
|
|
219
|
+
'Check the error message above for specific details',
|
|
220
|
+
'Ensure all required files exist and are accessible',
|
|
221
|
+
'Try running ingestion first if you haven\'t already',
|
|
222
|
+
'Contact support if the issue persists'
|
|
223
|
+
], context);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Create user-friendly resource error from internal error
|
|
227
|
+
*/
|
|
228
|
+
static createResourceError(error, context) {
|
|
229
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
230
|
+
if (errorMessage.includes('initialization')) {
|
|
231
|
+
return new ResourceError(`Resource initialization failed: ${errorMessage}`, 'INITIALIZATION_FAILED', [
|
|
232
|
+
'Check that all required files exist and are accessible',
|
|
233
|
+
'Ensure you have proper permissions for the resource files',
|
|
234
|
+
'Try cleaning up and reinitializing the resources',
|
|
235
|
+
'Check for sufficient disk space and memory'
|
|
236
|
+
], context);
|
|
237
|
+
}
|
|
238
|
+
if (errorMessage.includes('cleanup')) {
|
|
239
|
+
return new ResourceError(`Resource cleanup failed: ${errorMessage}`, 'CLEANUP_FAILED', [
|
|
240
|
+
'Some resources may not have been properly released',
|
|
241
|
+
'Try restarting the application to ensure clean state',
|
|
242
|
+
'Check for any locked files or processes',
|
|
243
|
+
'This may not affect functionality but could cause resource leaks'
|
|
244
|
+
], context);
|
|
245
|
+
}
|
|
246
|
+
// Generic resource error
|
|
247
|
+
return new ResourceError(`Resource management error: ${errorMessage}`, 'RESOURCE_ERROR', [
|
|
248
|
+
'Check the error message above for specific details',
|
|
249
|
+
'Try restarting the application',
|
|
250
|
+
'Ensure sufficient system resources are available',
|
|
251
|
+
'Contact support if the issue persists'
|
|
252
|
+
], context);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Common error scenarios with predefined messages and suggestions
|
|
257
|
+
* Requirements: 5.3 - Add specific error handling for common scenarios
|
|
258
|
+
*/
|
|
259
|
+
export const CommonErrors = {
|
|
260
|
+
/**
|
|
261
|
+
* Error when trying to search without running ingestion first
|
|
262
|
+
*/
|
|
263
|
+
NO_DOCUMENTS_INGESTED: new SearchError('No documents found to search. Run ingestion first.', 'NO_DOCUMENTS', [
|
|
264
|
+
'Call pipeline.ingestDirectory("./docs/") to add documents',
|
|
265
|
+
'Check that your document directory contains .md, .txt, or .mdx files',
|
|
266
|
+
'Ensure the ingestion process completed successfully'
|
|
267
|
+
], 'search_initialization'),
|
|
268
|
+
/**
|
|
269
|
+
* Error when model versions don't match
|
|
270
|
+
*/
|
|
271
|
+
MODEL_VERSION_MISMATCH: new ModelCompatibilityError('Embedding model version mismatch detected between stored index and current configuration.', 'MODEL_MISMATCH', [
|
|
272
|
+
'Run pipeline.rebuildIndex() to rebuild with current model',
|
|
273
|
+
'Or specify the same model used during ingestion',
|
|
274
|
+
'Check your model configuration settings'
|
|
275
|
+
], 'model_validation'),
|
|
276
|
+
/**
|
|
277
|
+
* Error when required files are missing
|
|
278
|
+
*/
|
|
279
|
+
MISSING_REQUIRED_FILES: new SearchError('Required database or index files are missing.', 'MISSING_FILES', [
|
|
280
|
+
'Run ingestion first: pipeline.ingestDirectory("./docs/")',
|
|
281
|
+
'Check that the file paths are correct',
|
|
282
|
+
'Ensure the ingestion process completed without errors'
|
|
283
|
+
], 'file_validation'),
|
|
284
|
+
/**
|
|
285
|
+
* Error when initialization fails
|
|
286
|
+
*/
|
|
287
|
+
INITIALIZATION_FAILED: new ResourceError('Failed to initialize required resources.', 'INIT_FAILED', [
|
|
288
|
+
'Check that all file paths are correct and accessible',
|
|
289
|
+
'Ensure you have proper read/write permissions',
|
|
290
|
+
'Try running ingestion first if this is a new setup',
|
|
291
|
+
'Check for sufficient disk space and memory'
|
|
292
|
+
], 'resource_initialization')
|
|
293
|
+
};
|
|
294
|
+
/**
|
|
295
|
+
* Utility function to handle and log errors appropriately
|
|
296
|
+
*/
|
|
297
|
+
export function handleAPIError(error, context, operation) {
|
|
298
|
+
let apiError;
|
|
299
|
+
if (error instanceof APIError) {
|
|
300
|
+
apiError = error;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
switch (operation) {
|
|
304
|
+
case 'ingestion':
|
|
305
|
+
apiError = ErrorFactory.createIngestionError(error, context);
|
|
306
|
+
break;
|
|
307
|
+
case 'search':
|
|
308
|
+
apiError = ErrorFactory.createSearchError(error, context);
|
|
309
|
+
break;
|
|
310
|
+
case 'resource':
|
|
311
|
+
apiError = ErrorFactory.createResourceError(error, context);
|
|
312
|
+
break;
|
|
313
|
+
default:
|
|
314
|
+
apiError = new ResourceError(`Unexpected error in ${context}: ${error instanceof Error ? error.message : String(error)}`, 'UNEXPECTED_ERROR', ['Contact support with the error details above'], context);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
apiError.logError();
|
|
318
|
+
throw apiError;
|
|
319
|
+
}
|
|
320
|
+
//# sourceMappingURL=api-errors.js.map
|