bigtool-ts 0.1.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.
- package/CHANGELOG.md +27 -0
- package/LICENSE +21 -0
- package/README.md +641 -0
- package/dist/adapters/agent-protocol.d.ts +149 -0
- package/dist/adapters/agent-protocol.d.ts.map +1 -0
- package/dist/adapters/agent-protocol.js +133 -0
- package/dist/adapters/agent-protocol.js.map +1 -0
- package/dist/adapters/index.d.ts +39 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +42 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/inngest.d.ts +234 -0
- package/dist/adapters/inngest.d.ts.map +1 -0
- package/dist/adapters/inngest.js +276 -0
- package/dist/adapters/inngest.js.map +1 -0
- package/dist/adapters/mastra.d.ts +201 -0
- package/dist/adapters/mastra.d.ts.map +1 -0
- package/dist/adapters/mastra.js +250 -0
- package/dist/adapters/mastra.js.map +1 -0
- package/dist/adapters/types.d.ts +42 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +6 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/vercel-ai.d.ts +176 -0
- package/dist/adapters/vercel-ai.d.ts.map +1 -0
- package/dist/adapters/vercel-ai.js +244 -0
- package/dist/adapters/vercel-ai.js.map +1 -0
- package/dist/catalog/index.d.ts +177 -0
- package/dist/catalog/index.d.ts.map +1 -0
- package/dist/catalog/index.js +244 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/graph/agent.d.ts +214 -0
- package/dist/graph/agent.d.ts.map +1 -0
- package/dist/graph/agent.js +196 -0
- package/dist/graph/agent.js.map +1 -0
- package/dist/graph/index.d.ts +5 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +4 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/nodes.d.ts +100 -0
- package/dist/graph/nodes.d.ts.map +1 -0
- package/dist/graph/nodes.js +190 -0
- package/dist/graph/nodes.js.map +1 -0
- package/dist/graph/search-tool.d.ts +34 -0
- package/dist/graph/search-tool.d.ts.map +1 -0
- package/dist/graph/search-tool.js +54 -0
- package/dist/graph/search-tool.js.map +1 -0
- package/dist/graph/state.d.ts +26 -0
- package/dist/graph/state.d.ts.map +1 -0
- package/dist/graph/state.js +29 -0
- package/dist/graph/state.js.map +1 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/loader/index.d.ts +172 -0
- package/dist/loader/index.d.ts.map +1 -0
- package/dist/loader/index.js +179 -0
- package/dist/loader/index.js.map +1 -0
- package/dist/loader/loader.d.ts +114 -0
- package/dist/loader/loader.d.ts.map +1 -0
- package/dist/loader/loader.js +185 -0
- package/dist/loader/loader.js.map +1 -0
- package/dist/search/cache.d.ts +76 -0
- package/dist/search/cache.d.ts.map +1 -0
- package/dist/search/cache.js +135 -0
- package/dist/search/cache.js.map +1 -0
- package/dist/search/index.d.ts +63 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +122 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/normalize.d.ts +104 -0
- package/dist/search/normalize.d.ts.map +1 -0
- package/dist/search/normalize.js +211 -0
- package/dist/search/normalize.js.map +1 -0
- package/dist/search/orama.d.ts +256 -0
- package/dist/search/orama.d.ts.map +1 -0
- package/dist/search/orama.js +511 -0
- package/dist/search/orama.js.map +1 -0
- package/dist/search/types.d.ts +96 -0
- package/dist/search/types.d.ts.map +1 -0
- package/dist/search/types.js +8 -0
- package/dist/search/types.js.map +1 -0
- package/dist/sources/dynamic.d.ts +200 -0
- package/dist/sources/dynamic.d.ts.map +1 -0
- package/dist/sources/dynamic.js +194 -0
- package/dist/sources/dynamic.js.map +1 -0
- package/dist/sources/index.d.ts +11 -0
- package/dist/sources/index.d.ts.map +1 -0
- package/dist/sources/index.js +14 -0
- package/dist/sources/index.js.map +1 -0
- package/dist/sources/local.d.ts +128 -0
- package/dist/sources/local.d.ts.map +1 -0
- package/dist/sources/local.js +155 -0
- package/dist/sources/local.js.map +1 -0
- package/dist/sources/mcp.d.ts +438 -0
- package/dist/sources/mcp.d.ts.map +1 -0
- package/dist/sources/mcp.js +438 -0
- package/dist/sources/mcp.js.map +1 -0
- package/dist/sources/types.d.ts +16 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +7 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/sources/with-metadata.d.ts +7 -0
- package/dist/sources/with-metadata.d.ts.map +1 -0
- package/dist/sources/with-metadata.js +7 -0
- package/dist/sources/with-metadata.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types.d.ts +700 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +97 -0
- package/dist/types.js.map +1 -0
- package/package.json +118 -0
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OramaSearch module.
|
|
3
|
+
*
|
|
4
|
+
* Provides a powerful search index implementation using @orama/orama,
|
|
5
|
+
* supporting BM25 text search, vector semantic search, and hybrid modes.
|
|
6
|
+
*
|
|
7
|
+
* @module search/orama
|
|
8
|
+
*/
|
|
9
|
+
import { create, insert, search, count, } from "@orama/orama";
|
|
10
|
+
import { normalizeBM25Scores, normalizeOramaVectorScore, mergeHybridResults, } from "./normalize.js";
|
|
11
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
12
|
+
// Orama Schema Types
|
|
13
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
14
|
+
const oramaSchema = {
|
|
15
|
+
id: "string",
|
|
16
|
+
name: "string",
|
|
17
|
+
description: "string",
|
|
18
|
+
keywords: "string",
|
|
19
|
+
categories: "string",
|
|
20
|
+
};
|
|
21
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
22
|
+
// Helper Functions
|
|
23
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
24
|
+
/**
|
|
25
|
+
* Convert ToolMetadata to a flat document for Orama indexing.
|
|
26
|
+
* Arrays are joined into space-separated strings for BM25 search.
|
|
27
|
+
*/
|
|
28
|
+
function toolToDocument(tool, embedding) {
|
|
29
|
+
const doc = {
|
|
30
|
+
id: tool.id,
|
|
31
|
+
name: tool.name,
|
|
32
|
+
description: tool.description,
|
|
33
|
+
keywords: (tool.keywords ?? []).join(" "),
|
|
34
|
+
categories: (tool.categories ?? []).join(" "),
|
|
35
|
+
};
|
|
36
|
+
if (embedding) {
|
|
37
|
+
doc.embedding = embedding;
|
|
38
|
+
}
|
|
39
|
+
return doc;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Create text for embedding by combining all searchable fields.
|
|
43
|
+
*/
|
|
44
|
+
function toolToEmbeddingText(tool) {
|
|
45
|
+
const parts = [
|
|
46
|
+
tool.name,
|
|
47
|
+
tool.description,
|
|
48
|
+
...(tool.keywords ?? []),
|
|
49
|
+
...(tool.categories ?? []),
|
|
50
|
+
];
|
|
51
|
+
return parts.filter(Boolean).join(" ");
|
|
52
|
+
}
|
|
53
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
54
|
+
// OramaSearch Implementation
|
|
55
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
56
|
+
/**
|
|
57
|
+
* Search index implementation using @orama/orama.
|
|
58
|
+
*
|
|
59
|
+
* OramaSearch provides fast, in-memory search for tool discovery.
|
|
60
|
+
* It supports three search modes:
|
|
61
|
+
*
|
|
62
|
+
* - **BM25**: Fast text search using TF-IDF/BM25 algorithm. No API keys
|
|
63
|
+
* needed. Best for keyword-based queries.
|
|
64
|
+
*
|
|
65
|
+
* - **Vector**: Semantic search using embeddings. Requires an embeddings
|
|
66
|
+
* provider (e.g., OpenAIEmbeddings). Best for natural language queries.
|
|
67
|
+
*
|
|
68
|
+
* - **Hybrid**: Combines BM25 and vector scores for best results. Uses
|
|
69
|
+
* weighted combination with configurable weights.
|
|
70
|
+
*
|
|
71
|
+
* @example BM25 Mode (default, no API keys needed)
|
|
72
|
+
* ```typescript
|
|
73
|
+
* import { OramaSearch } from '@repo/bigtool-ts';
|
|
74
|
+
*
|
|
75
|
+
* const search = new OramaSearch({ mode: 'bm25' });
|
|
76
|
+
* await search.index(catalog.getAllMetadata());
|
|
77
|
+
*
|
|
78
|
+
* const results = await search.search('github pull request');
|
|
79
|
+
* console.log(results[0].toolId); // 'github:create_pr'
|
|
80
|
+
* ```
|
|
81
|
+
*
|
|
82
|
+
* @example Vector Mode (semantic search)
|
|
83
|
+
* ```typescript
|
|
84
|
+
* import { OramaSearch } from '@repo/bigtool-ts';
|
|
85
|
+
* import { OpenAIEmbeddings } from '@langchain/openai';
|
|
86
|
+
*
|
|
87
|
+
* const search = new OramaSearch({
|
|
88
|
+
* mode: 'vector',
|
|
89
|
+
* embeddings: new OpenAIEmbeddings(),
|
|
90
|
+
* cache: new MemoryEmbeddingCache(),
|
|
91
|
+
* });
|
|
92
|
+
*
|
|
93
|
+
* await search.index(tools);
|
|
94
|
+
* const results = await search.search('help me merge code changes');
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @example Hybrid Mode (best of both)
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const search = new OramaSearch({
|
|
100
|
+
* mode: 'hybrid',
|
|
101
|
+
* embeddings: new OpenAIEmbeddings(),
|
|
102
|
+
* weights: { bm25: 0.4, vector: 0.6 },
|
|
103
|
+
* boost: { name: 3, keywords: 2 },
|
|
104
|
+
* });
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export class OramaSearch {
|
|
108
|
+
/** @internal BM25 database */
|
|
109
|
+
db = null;
|
|
110
|
+
/** @internal Vector database */
|
|
111
|
+
vectorDb = null;
|
|
112
|
+
/** @internal Resolved configuration */
|
|
113
|
+
config;
|
|
114
|
+
/** @internal Indexed tools for reindexing */
|
|
115
|
+
tools = [];
|
|
116
|
+
/** @internal Embeddings provider */
|
|
117
|
+
embeddings;
|
|
118
|
+
/** @internal Embedding cache */
|
|
119
|
+
cache;
|
|
120
|
+
/** @internal Whether index() has been called */
|
|
121
|
+
initialized = false;
|
|
122
|
+
/**
|
|
123
|
+
* Creates a new OramaSearch instance.
|
|
124
|
+
*
|
|
125
|
+
* @param config - Search configuration (mode, embeddings, etc.)
|
|
126
|
+
* @throws Error if vector/hybrid mode is used without embeddings
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* ```typescript
|
|
130
|
+
* // BM25 (default)
|
|
131
|
+
* const search = new OramaSearch();
|
|
132
|
+
*
|
|
133
|
+
* // Explicit mode
|
|
134
|
+
* const search = new OramaSearch({ mode: 'bm25' });
|
|
135
|
+
*
|
|
136
|
+
* // With custom boosts
|
|
137
|
+
* const search = new OramaSearch({
|
|
138
|
+
* mode: 'bm25',
|
|
139
|
+
* boost: { name: 3, keywords: 2, description: 1, categories: 1 },
|
|
140
|
+
* });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
constructor(config = { mode: "bm25" }) {
|
|
144
|
+
// Validate config
|
|
145
|
+
if ((config.mode === "vector" || config.mode === "hybrid") && !config.embeddings) {
|
|
146
|
+
throw new Error(`OramaSearch: Embeddings provider required for ${config.mode} mode. ` +
|
|
147
|
+
"Pass an embeddings instance (e.g., new OpenAIEmbeddings()) in config.");
|
|
148
|
+
}
|
|
149
|
+
this.embeddings = config.embeddings;
|
|
150
|
+
this.cache = config.cache;
|
|
151
|
+
// Set defaults for all config options
|
|
152
|
+
this.config = {
|
|
153
|
+
mode: config.mode,
|
|
154
|
+
embeddings: config.embeddings,
|
|
155
|
+
cache: config.cache,
|
|
156
|
+
boost: {
|
|
157
|
+
name: config.boost?.name ?? 2,
|
|
158
|
+
description: config.boost?.description ?? 1,
|
|
159
|
+
keywords: config.boost?.keywords ?? 1.5,
|
|
160
|
+
categories: config.boost?.categories ?? 1,
|
|
161
|
+
},
|
|
162
|
+
weights: {
|
|
163
|
+
bm25: config.weights?.bm25 ?? 0.5,
|
|
164
|
+
vector: config.weights?.vector ?? 0.5,
|
|
165
|
+
},
|
|
166
|
+
vectorSize: config.vectorSize ?? 1536,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
170
|
+
// Public API
|
|
171
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
172
|
+
/**
|
|
173
|
+
* Index a collection of tools for search.
|
|
174
|
+
*
|
|
175
|
+
* This creates the search index from the provided tool metadata.
|
|
176
|
+
* Call this after registering sources with the catalog.
|
|
177
|
+
* Replaces any existing index.
|
|
178
|
+
*
|
|
179
|
+
* For vector/hybrid modes, this also computes and caches embeddings.
|
|
180
|
+
*
|
|
181
|
+
* @param tools - Array of tool metadata to index
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* const search = new OramaSearch({ mode: 'bm25' });
|
|
186
|
+
* await search.index(catalog.getAllMetadata());
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
async index(tools) {
|
|
190
|
+
this.tools = tools;
|
|
191
|
+
// Create BM25 database
|
|
192
|
+
this.db = await create({
|
|
193
|
+
schema: oramaSchema,
|
|
194
|
+
});
|
|
195
|
+
// Insert all tools for BM25
|
|
196
|
+
for (const tool of tools) {
|
|
197
|
+
const doc = toolToDocument(tool);
|
|
198
|
+
await insert(this.db, doc);
|
|
199
|
+
}
|
|
200
|
+
// Create vector database if needed
|
|
201
|
+
const needsVectors = this.config.mode === "vector" || this.config.mode === "hybrid";
|
|
202
|
+
if (needsVectors && this.embeddings) {
|
|
203
|
+
const embeddings = await this.computeEmbeddings(tools);
|
|
204
|
+
// Create vector database with dynamic schema
|
|
205
|
+
const vectorSchema = {
|
|
206
|
+
id: "string",
|
|
207
|
+
embedding: `vector[${this.config.vectorSize}]`,
|
|
208
|
+
};
|
|
209
|
+
this.vectorDb = await create({
|
|
210
|
+
schema: vectorSchema,
|
|
211
|
+
});
|
|
212
|
+
// Insert tools with embeddings
|
|
213
|
+
for (const tool of tools) {
|
|
214
|
+
const embedding = embeddings.get(tool.id);
|
|
215
|
+
if (embedding) {
|
|
216
|
+
await insert(this.vectorDb, {
|
|
217
|
+
id: tool.id,
|
|
218
|
+
embedding,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
this.initialized = true;
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Search for tools matching a query.
|
|
227
|
+
*
|
|
228
|
+
* Uses the configured search mode (BM25, vector, or hybrid).
|
|
229
|
+
* Results are normalized to 0-1 scores and sorted by relevance.
|
|
230
|
+
*
|
|
231
|
+
* @param query - Natural language search query
|
|
232
|
+
* @param options - Search options (limit, threshold, categories)
|
|
233
|
+
* @returns Array of search results sorted by relevance
|
|
234
|
+
* @throws Error if index() has not been called
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* const results = await search.search('create github pull request', {
|
|
239
|
+
* limit: 10,
|
|
240
|
+
* threshold: 0.3,
|
|
241
|
+
* });
|
|
242
|
+
*
|
|
243
|
+
* for (const result of results) {
|
|
244
|
+
* console.log(`${result.toolId}: ${result.score.toFixed(2)}`);
|
|
245
|
+
* }
|
|
246
|
+
* ```
|
|
247
|
+
*/
|
|
248
|
+
async search(query, options) {
|
|
249
|
+
if (!this.db || !this.initialized) {
|
|
250
|
+
throw new Error("OramaSearch: Index not initialized. Call index() first.");
|
|
251
|
+
}
|
|
252
|
+
const mode = options?.mode ?? this.config.mode;
|
|
253
|
+
const limit = options?.limit ?? 5;
|
|
254
|
+
const threshold = options?.threshold;
|
|
255
|
+
let results;
|
|
256
|
+
switch (mode) {
|
|
257
|
+
case "bm25":
|
|
258
|
+
results = await this.searchBM25(query, limit);
|
|
259
|
+
break;
|
|
260
|
+
case "vector":
|
|
261
|
+
results = await this.searchVector(query, limit);
|
|
262
|
+
break;
|
|
263
|
+
case "hybrid":
|
|
264
|
+
results = await this.searchHybrid(query, limit);
|
|
265
|
+
break;
|
|
266
|
+
default:
|
|
267
|
+
throw new Error(`OramaSearch: Unknown search mode: ${mode}`);
|
|
268
|
+
}
|
|
269
|
+
// Apply threshold filter
|
|
270
|
+
if (threshold !== undefined) {
|
|
271
|
+
results = results.filter((r) => r.score >= threshold);
|
|
272
|
+
}
|
|
273
|
+
// Apply limit
|
|
274
|
+
return results.slice(0, limit);
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Rebuild the index from currently indexed tools.
|
|
278
|
+
*
|
|
279
|
+
* Call this when the catalog changes (tools added/removed).
|
|
280
|
+
* Uses the tools from the last index() call.
|
|
281
|
+
*
|
|
282
|
+
* @throws Error if index() has not been called
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
* ```typescript
|
|
286
|
+
* // Listen for catalog changes
|
|
287
|
+
* catalog.onToolsChanged.subscribe(async () => {
|
|
288
|
+
* await search.reindex();
|
|
289
|
+
* });
|
|
290
|
+
* ```
|
|
291
|
+
*/
|
|
292
|
+
async reindex() {
|
|
293
|
+
if (this.tools.length === 0) {
|
|
294
|
+
throw new Error("OramaSearch: No tools to reindex. Call index() first.");
|
|
295
|
+
}
|
|
296
|
+
await this.index(this.tools);
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Get the number of indexed tools.
|
|
300
|
+
*
|
|
301
|
+
* @returns Number of tools in the index
|
|
302
|
+
*
|
|
303
|
+
* @example
|
|
304
|
+
* ```typescript
|
|
305
|
+
* const indexed = await search.count();
|
|
306
|
+
* console.log(`${indexed} tools indexed`);
|
|
307
|
+
* ```
|
|
308
|
+
*/
|
|
309
|
+
async count() {
|
|
310
|
+
if (!this.db)
|
|
311
|
+
return 0;
|
|
312
|
+
return count(this.db);
|
|
313
|
+
}
|
|
314
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
315
|
+
// BM25 Search
|
|
316
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
317
|
+
async searchBM25(query, limit) {
|
|
318
|
+
if (!this.db)
|
|
319
|
+
return [];
|
|
320
|
+
const searchParams = {
|
|
321
|
+
term: query,
|
|
322
|
+
limit,
|
|
323
|
+
boost: {
|
|
324
|
+
name: this.config.boost.name,
|
|
325
|
+
description: this.config.boost.description,
|
|
326
|
+
keywords: this.config.boost.keywords,
|
|
327
|
+
categories: this.config.boost.categories,
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
const results = await search(this.db, searchParams);
|
|
331
|
+
// Extract raw scores for normalization
|
|
332
|
+
const rawScores = results.hits.map((hit) => hit.score);
|
|
333
|
+
const normalizedScores = normalizeBM25Scores(rawScores);
|
|
334
|
+
return results.hits.map((hit, index) => ({
|
|
335
|
+
toolId: hit.document.id,
|
|
336
|
+
score: normalizedScores[index],
|
|
337
|
+
matchType: "bm25",
|
|
338
|
+
}));
|
|
339
|
+
}
|
|
340
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
341
|
+
// Vector Search
|
|
342
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
343
|
+
async searchVector(query, limit) {
|
|
344
|
+
if (!this.vectorDb || !this.embeddings)
|
|
345
|
+
return [];
|
|
346
|
+
// Embed the query
|
|
347
|
+
const queryEmbedding = await this.embeddings.embedQuery(query);
|
|
348
|
+
// Search by vector similarity
|
|
349
|
+
const results = await search(this.vectorDb, {
|
|
350
|
+
mode: "vector",
|
|
351
|
+
vector: {
|
|
352
|
+
value: queryEmbedding,
|
|
353
|
+
property: "embedding",
|
|
354
|
+
},
|
|
355
|
+
limit,
|
|
356
|
+
similarity: 0.3, // Minimum similarity threshold
|
|
357
|
+
});
|
|
358
|
+
return results.hits.map((hit) => ({
|
|
359
|
+
toolId: hit.document.id,
|
|
360
|
+
score: normalizeOramaVectorScore(hit.score),
|
|
361
|
+
matchType: "vector",
|
|
362
|
+
}));
|
|
363
|
+
}
|
|
364
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
365
|
+
// Hybrid Search
|
|
366
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
367
|
+
async searchHybrid(query, limit) {
|
|
368
|
+
// Run both searches in parallel
|
|
369
|
+
const [bm25Results, vectorResults] = await Promise.all([
|
|
370
|
+
this.searchBM25(query, limit * 2), // Get more results for better fusion
|
|
371
|
+
this.searchVector(query, limit * 2),
|
|
372
|
+
]);
|
|
373
|
+
// Merge using weighted combination
|
|
374
|
+
const merged = mergeHybridResults(bm25Results, vectorResults, this.config.weights);
|
|
375
|
+
return merged.slice(0, limit);
|
|
376
|
+
}
|
|
377
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
378
|
+
// Embedding Computation
|
|
379
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
380
|
+
/**
|
|
381
|
+
* Compute embeddings for tools, using cache when available.
|
|
382
|
+
*/
|
|
383
|
+
async computeEmbeddings(tools) {
|
|
384
|
+
if (!this.embeddings) {
|
|
385
|
+
throw new Error("OramaSearch: Embeddings provider not configured.");
|
|
386
|
+
}
|
|
387
|
+
const embeddings = new Map();
|
|
388
|
+
const toCompute = [];
|
|
389
|
+
// Check cache for existing embeddings
|
|
390
|
+
for (const tool of tools) {
|
|
391
|
+
if (this.cache) {
|
|
392
|
+
const cached = await this.cache.get(tool.id);
|
|
393
|
+
if (cached) {
|
|
394
|
+
embeddings.set(tool.id, cached);
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
toCompute.push({ tool, text: toolToEmbeddingText(tool) });
|
|
399
|
+
}
|
|
400
|
+
// Compute missing embeddings in batch
|
|
401
|
+
if (toCompute.length > 0) {
|
|
402
|
+
const texts = toCompute.map((t) => t.text);
|
|
403
|
+
const computed = await this.embeddings.embedDocuments(texts);
|
|
404
|
+
for (let i = 0; i < toCompute.length; i++) {
|
|
405
|
+
const toolId = toCompute[i].tool.id;
|
|
406
|
+
const embedding = computed[i];
|
|
407
|
+
embeddings.set(toolId, embedding);
|
|
408
|
+
// Cache the computed embedding
|
|
409
|
+
if (this.cache) {
|
|
410
|
+
await this.cache.set(toolId, embedding);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return embeddings;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
418
|
+
// Factory Functions
|
|
419
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
420
|
+
/**
|
|
421
|
+
* Create a BM25-only search index.
|
|
422
|
+
*
|
|
423
|
+
* This is the simplest and fastest option, requiring no API keys.
|
|
424
|
+
* Uses TF-IDF/BM25 algorithm for text matching.
|
|
425
|
+
*
|
|
426
|
+
* @param options - Optional configuration for field boosting
|
|
427
|
+
* @returns Configured OramaSearch instance
|
|
428
|
+
*
|
|
429
|
+
* @example
|
|
430
|
+
* ```typescript
|
|
431
|
+
* import { createBM25Search } from '@repo/bigtool-ts';
|
|
432
|
+
*
|
|
433
|
+
* const search = createBM25Search();
|
|
434
|
+
* await search.index(tools);
|
|
435
|
+
* ```
|
|
436
|
+
*
|
|
437
|
+
* @example With custom boosts
|
|
438
|
+
* ```typescript
|
|
439
|
+
* const search = createBM25Search({
|
|
440
|
+
* boost: { name: 3, keywords: 2, description: 1, categories: 1 },
|
|
441
|
+
* });
|
|
442
|
+
* ```
|
|
443
|
+
*/
|
|
444
|
+
export function createBM25Search(options) {
|
|
445
|
+
return new OramaSearch({
|
|
446
|
+
mode: "bm25",
|
|
447
|
+
boost: options?.boost,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Create a vector search index.
|
|
452
|
+
*
|
|
453
|
+
* Uses semantic similarity via embeddings. Requires an embeddings
|
|
454
|
+
* provider (e.g., OpenAIEmbeddings).
|
|
455
|
+
*
|
|
456
|
+
* @param embeddings - Embeddings provider for computing vectors
|
|
457
|
+
* @param cache - Optional cache for storing computed embeddings
|
|
458
|
+
* @param vectorSize - Embedding dimension (default: 1536 for OpenAI)
|
|
459
|
+
* @returns Configured OramaSearch instance
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* ```typescript
|
|
463
|
+
* import { createVectorSearch } from '@repo/bigtool-ts';
|
|
464
|
+
* import { OpenAIEmbeddings } from '@langchain/openai';
|
|
465
|
+
*
|
|
466
|
+
* const search = createVectorSearch(
|
|
467
|
+
* new OpenAIEmbeddings(),
|
|
468
|
+
* new MemoryEmbeddingCache(),
|
|
469
|
+
* );
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
export function createVectorSearch(embeddings, cache, vectorSize) {
|
|
473
|
+
return new OramaSearch({
|
|
474
|
+
mode: "vector",
|
|
475
|
+
embeddings,
|
|
476
|
+
cache,
|
|
477
|
+
vectorSize,
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Create a hybrid search index.
|
|
482
|
+
*
|
|
483
|
+
* Combines BM25 text matching with vector semantic similarity
|
|
484
|
+
* for the best results. Uses weighted scoring to merge results.
|
|
485
|
+
*
|
|
486
|
+
* @param embeddings - Embeddings provider for computing vectors
|
|
487
|
+
* @param options - Configuration options
|
|
488
|
+
* @returns Configured OramaSearch instance
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```typescript
|
|
492
|
+
* import { createHybridSearch } from '@repo/bigtool-ts';
|
|
493
|
+
* import { OpenAIEmbeddings } from '@langchain/openai';
|
|
494
|
+
*
|
|
495
|
+
* const search = createHybridSearch(new OpenAIEmbeddings(), {
|
|
496
|
+
* weights: { bm25: 0.3, vector: 0.7 },
|
|
497
|
+
* cache: new MemoryEmbeddingCache(),
|
|
498
|
+
* });
|
|
499
|
+
* ```
|
|
500
|
+
*/
|
|
501
|
+
export function createHybridSearch(embeddings, options) {
|
|
502
|
+
return new OramaSearch({
|
|
503
|
+
mode: "hybrid",
|
|
504
|
+
embeddings,
|
|
505
|
+
cache: options?.cache,
|
|
506
|
+
weights: options?.weights,
|
|
507
|
+
boost: options?.boost,
|
|
508
|
+
vectorSize: options?.vectorSize,
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
//# sourceMappingURL=orama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orama.js","sourceRoot":"","sources":["../../src/search/orama.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Module Types
|
|
3
|
+
*
|
|
4
|
+
* Local type definitions for the search module.
|
|
5
|
+
* These extend or adapt the core types for search-specific use.
|
|
6
|
+
*/
|
|
7
|
+
export type { SearchOptions, SearchResult, SearchIndex } from '../types/index.js';
|
|
8
|
+
/** Search mode determines which algorithm is used */
|
|
9
|
+
export type SearchMode = "bm25" | "vector" | "hybrid";
|
|
10
|
+
/**
|
|
11
|
+
* ToolMetadata for search - adapts core type for search use
|
|
12
|
+
* The core ToolMetadata has required `sourceId` field that we make optional here
|
|
13
|
+
*/
|
|
14
|
+
export interface ToolMetadata {
|
|
15
|
+
/** Unique identifier for the tool */
|
|
16
|
+
id: string;
|
|
17
|
+
/** Human-readable name of the tool */
|
|
18
|
+
name: string;
|
|
19
|
+
/** Description of what the tool does */
|
|
20
|
+
description: string;
|
|
21
|
+
/** Tool parameter schema (JSON Schema format) */
|
|
22
|
+
parameters?: Record<string, unknown>;
|
|
23
|
+
/** Categories for grouping/filtering (e.g., ["github", "git"]) */
|
|
24
|
+
categories?: string[];
|
|
25
|
+
/** Keywords for improved search matching (e.g., ["PR", "pull request"]) */
|
|
26
|
+
keywords?: string[];
|
|
27
|
+
/** Source of the tool for tracking origin */
|
|
28
|
+
source?: "local" | "mcp" | "dynamic";
|
|
29
|
+
/** Source ID (optional for search) */
|
|
30
|
+
sourceId?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Interface for embedding providers (compatible with LangChain Embeddings)
|
|
34
|
+
*/
|
|
35
|
+
export interface Embeddings {
|
|
36
|
+
/** Embed a single text string */
|
|
37
|
+
embedQuery(text: string): Promise<number[]>;
|
|
38
|
+
/** Embed multiple texts (for batch efficiency) */
|
|
39
|
+
embedDocuments(texts: string[]): Promise<number[][]>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Cache interface for storing computed embeddings.
|
|
43
|
+
* Avoids recomputing embeddings on every index rebuild.
|
|
44
|
+
*/
|
|
45
|
+
export interface EmbeddingCache {
|
|
46
|
+
/** Retrieve a cached embedding by tool ID */
|
|
47
|
+
get(toolId: string): Promise<number[] | null>;
|
|
48
|
+
/** Store an embedding for a tool ID */
|
|
49
|
+
set(toolId: string, embedding: number[]): Promise<void>;
|
|
50
|
+
/** Remove a cached embedding */
|
|
51
|
+
invalidate(toolId: string): Promise<void>;
|
|
52
|
+
/** Clear all cached embeddings */
|
|
53
|
+
clear(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Field boost weights for BM25 search.
|
|
57
|
+
* Higher values make matches in that field more important.
|
|
58
|
+
*/
|
|
59
|
+
export interface FieldBoostConfig {
|
|
60
|
+
/** Boost for tool name matches (default: 2) */
|
|
61
|
+
name?: number;
|
|
62
|
+
/** Boost for description matches (default: 1) */
|
|
63
|
+
description?: number;
|
|
64
|
+
/** Boost for keyword matches (default: 1.5) */
|
|
65
|
+
keywords?: number;
|
|
66
|
+
/** Boost for category matches (default: 1) */
|
|
67
|
+
categories?: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Weight configuration for hybrid search.
|
|
71
|
+
* Values should sum to 1 for proper normalization.
|
|
72
|
+
*/
|
|
73
|
+
export interface HybridWeights {
|
|
74
|
+
/** Weight for BM25 text matching (default: 0.5) */
|
|
75
|
+
bm25: number;
|
|
76
|
+
/** Weight for vector similarity (default: 0.5) */
|
|
77
|
+
vector: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Configuration for OramaSearch
|
|
81
|
+
*/
|
|
82
|
+
export interface OramaSearchConfig {
|
|
83
|
+
/** Search mode: bm25, vector, or hybrid */
|
|
84
|
+
mode: SearchMode;
|
|
85
|
+
/** Required for vector/hybrid modes - embedding provider */
|
|
86
|
+
embeddings?: Embeddings;
|
|
87
|
+
/** Optional cache for embeddings to avoid recomputation */
|
|
88
|
+
cache?: EmbeddingCache;
|
|
89
|
+
/** Field boost weights for BM25 search */
|
|
90
|
+
boost?: FieldBoostConfig;
|
|
91
|
+
/** Weights for combining BM25 and vector scores in hybrid mode */
|
|
92
|
+
weights?: HybridWeights;
|
|
93
|
+
/** Vector embedding dimension (default: 1536 for OpenAI) */
|
|
94
|
+
vectorSize?: number;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAElF,qDAAqD;AACrD,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEtD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;IACrC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5C,kDAAkD;IAClD,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;CACtD;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9C,uCAAuC;IACvC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,gCAAgC;IAChC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,kCAAkC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,2CAA2C;IAC3C,IAAI,EAAE,UAAU,CAAC;IACjB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,0CAA0C;IAC1C,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,kEAAkE;IAClE,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|