fmea-api-mcp-server 1.1.28 → 1.1.30
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/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { create, load, search } from '@orama/orama';
|
|
2
|
-
import { pipeline } from '@xenova/transformers';
|
|
3
2
|
import fs from 'fs/promises';
|
|
4
3
|
import path from 'path';
|
|
5
4
|
import { paginateResults, DEFAULT_PAGE_SIZE } from '../../utils/search-helper.js';
|
|
@@ -51,9 +50,16 @@ export class OramaSearchService {
|
|
|
51
50
|
catch (lookupError) {
|
|
52
51
|
console.error('⚠️ OramaSearchService: endpoint-lookup.json not found, falling back to index-only mode.');
|
|
53
52
|
}
|
|
54
|
-
// Initialize model
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
// Initialize embedding model (fastembed / onnxruntime-node)
|
|
54
|
+
try {
|
|
55
|
+
const { FlagEmbedding, EmbeddingModel } = await import('fastembed');
|
|
56
|
+
this.extractor = await FlagEmbedding.init({ model: EmbeddingModel.BGESmallENV15 });
|
|
57
|
+
console.error('✅ OramaSearchService: Index loaded and model ready (hybrid mode).');
|
|
58
|
+
}
|
|
59
|
+
catch (embeddingError) {
|
|
60
|
+
console.error('⚠️ OramaSearchService: Embedding model unavailable, using BM25 text search only.', embeddingError);
|
|
61
|
+
this.extractor = null;
|
|
62
|
+
}
|
|
57
63
|
}
|
|
58
64
|
catch (error) {
|
|
59
65
|
console.error('❌ OramaSearchService initialization failed:', error);
|
|
@@ -61,7 +67,7 @@ export class OramaSearchService {
|
|
|
61
67
|
}
|
|
62
68
|
async search(query, filterMethod, filterVersion, page = 1, explicitPath) {
|
|
63
69
|
await this.initPromise; // Ensure service is ready
|
|
64
|
-
if (!this.db
|
|
70
|
+
if (!this.db) {
|
|
65
71
|
return { results: [], meta: { total: 0, page, totalPages: 0 }, warning: 'Search service not initialized' };
|
|
66
72
|
}
|
|
67
73
|
if (!query || query.trim() === '') {
|
|
@@ -139,33 +145,50 @@ export class OramaSearchService {
|
|
|
139
145
|
expandedQuery += ' ' + extraSynonyms.join(' ');
|
|
140
146
|
}
|
|
141
147
|
console.error(`[Orama] Expanded Query: "${expandedQuery}"`);
|
|
142
|
-
const output = await this.extractor(safeQuery, { pooling: 'mean', normalize: true });
|
|
143
|
-
const embedding = Array.from(output.data);
|
|
144
148
|
// 3. Build Where Clauses
|
|
145
149
|
const where = {};
|
|
146
150
|
if (filterMethod)
|
|
147
151
|
where.method = filterMethod;
|
|
148
152
|
if (filterVersion)
|
|
149
153
|
where.version = filterVersion;
|
|
150
|
-
// 4. Search —
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
154
|
+
// 4. Search — hybrid (BM25 + vector) when embedding available, BM25-only otherwise
|
|
155
|
+
let searchResult;
|
|
156
|
+
if (this.extractor) {
|
|
157
|
+
const embedding = await this.extractor.queryEmbed(safeQuery);
|
|
158
|
+
searchResult = await search(this.db, {
|
|
159
|
+
term: expandedQuery,
|
|
160
|
+
tolerance: 2,
|
|
161
|
+
properties: ['description', 'path'],
|
|
162
|
+
boost: {
|
|
163
|
+
description: 5.0,
|
|
164
|
+
path: 10.0
|
|
165
|
+
},
|
|
166
|
+
vector: {
|
|
167
|
+
value: embedding,
|
|
168
|
+
property: 'embedding'
|
|
169
|
+
},
|
|
170
|
+
mode: 'hybrid',
|
|
171
|
+
similarity: 0,
|
|
172
|
+
where,
|
|
173
|
+
limit: 1000,
|
|
174
|
+
offset: 0
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// BM25-only fallback (no embedding model available)
|
|
179
|
+
searchResult = await search(this.db, {
|
|
180
|
+
term: expandedQuery,
|
|
181
|
+
tolerance: 2,
|
|
182
|
+
properties: ['description', 'path'],
|
|
183
|
+
boost: {
|
|
184
|
+
description: 5.0,
|
|
185
|
+
path: 10.0
|
|
186
|
+
},
|
|
187
|
+
where,
|
|
188
|
+
limit: 1000,
|
|
189
|
+
offset: 0
|
|
190
|
+
});
|
|
191
|
+
}
|
|
169
192
|
// 5. Threshold Filtering & Mapping with Structural Analysis
|
|
170
193
|
const results = [];
|
|
171
194
|
for (const hit of searchResult.hits) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fmea-api-mcp-server",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.30",
|
|
4
4
|
"description": "MCP server for serving API documentation from endpoints directory",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
30
30
|
"@orama/orama": "^3.1.18",
|
|
31
|
-
"
|
|
31
|
+
"fastembed": "^2.1.0",
|
|
32
32
|
"stemmer": "^2.0.1",
|
|
33
33
|
"zod": "^3.22.4"
|
|
34
34
|
},
|
|
@@ -39,9 +39,6 @@
|
|
|
39
39
|
"eslint": "^9.39.2",
|
|
40
40
|
"typescript": "^5.3.0"
|
|
41
41
|
},
|
|
42
|
-
"overrides": {
|
|
43
|
-
"sharp": "^0.33.5"
|
|
44
|
-
},
|
|
45
42
|
"files": [
|
|
46
43
|
"dist",
|
|
47
44
|
"endpoints",
|