recker 1.0.68 → 1.0.70-next.9b4eebc
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/ai/index.d.ts +0 -1
- package/dist/ai/index.js +0 -1
- package/dist/browser/ai/index.d.ts +0 -1
- package/dist/browser/ai/index.js +0 -1
- package/dist/browser/index.iife.min.js +51 -51
- package/dist/browser/index.min.js +51 -51
- package/dist/browser/index.umd.min.js +51 -51
- package/dist/cli/index.js +0 -2
- package/dist/cli/tui/components/command-palette.d.ts +0 -3
- package/dist/cli/tui/components/command-palette.js +0 -16
- package/dist/cli/tui/shell-search.d.ts +10 -4
- package/dist/cli/tui/shell-search.js +55 -92
- package/dist/mcp/index.d.ts +0 -1
- package/dist/mcp/index.js +0 -1
- package/dist/mcp/server.d.ts +0 -6
- package/dist/mcp/server.js +27 -138
- package/dist/mcp/tools/ai.js +0 -82
- package/dist/mini.d.ts +0 -6
- package/dist/mini.js +0 -3
- package/dist/version.js +1 -1
- package/package.json +12 -16
- package/dist/ai/vector/index.d.ts +0 -2
- package/dist/ai/vector/index.js +0 -2
- package/dist/ai/vector/similarity.d.ts +0 -2
- package/dist/ai/vector/similarity.js +0 -27
- package/dist/ai/vector/store.d.ts +0 -27
- package/dist/ai/vector/store.js +0 -82
- package/dist/browser/ai/vector/index.d.ts +0 -2
- package/dist/browser/ai/vector/index.js +0 -2
- package/dist/browser/ai/vector/similarity.d.ts +0 -2
- package/dist/browser/ai/vector/similarity.js +0 -27
- package/dist/browser/ai/vector/store.d.ts +0 -27
- package/dist/browser/ai/vector/store.js +0 -82
- package/dist/cli/commands/vector.d.ts +0 -8
- package/dist/cli/commands/vector.js +0 -214
- package/dist/mcp/embeddings-loader.d.ts +0 -17
- package/dist/mcp/embeddings-loader.js +0 -162
- package/dist/mcp/search/embedder.d.ts +0 -9
- package/dist/mcp/search/embedder.js +0 -83
- package/dist/mcp/search/hybrid-search.d.ts +0 -30
- package/dist/mcp/search/hybrid-search.js +0 -402
- package/dist/mcp/search/index.d.ts +0 -4
- package/dist/mcp/search/index.js +0 -3
- package/dist/mcp/search/math.d.ts +0 -5
- package/dist/mcp/search/math.js +0 -63
- package/dist/mcp/search/types.d.ts +0 -51
- package/dist/mcp/search/types.js +0 -1
package/dist/mcp/tools/ai.js
CHANGED
|
@@ -125,66 +125,6 @@ export const aiToolHandlers = {
|
|
|
125
125
|
};
|
|
126
126
|
}
|
|
127
127
|
},
|
|
128
|
-
rek_ai_embed: async (args) => {
|
|
129
|
-
const input = args.input;
|
|
130
|
-
const model = args.model;
|
|
131
|
-
const provider = args.provider;
|
|
132
|
-
if (!input) {
|
|
133
|
-
return {
|
|
134
|
-
content: [{ type: 'text', text: 'Error: input text is required' }],
|
|
135
|
-
isError: true,
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
const availableProviders = getAvailableProviders();
|
|
139
|
-
if (availableProviders.length === 0) {
|
|
140
|
-
return {
|
|
141
|
-
content: [{
|
|
142
|
-
type: 'text',
|
|
143
|
-
text: 'Error: No AI provider configured for embeddings',
|
|
144
|
-
}],
|
|
145
|
-
isError: true,
|
|
146
|
-
};
|
|
147
|
-
}
|
|
148
|
-
const embeddingProviders = ['openai', 'cohere', 'google'];
|
|
149
|
-
const selectedProvider = provider ||
|
|
150
|
-
embeddingProviders.find(p => availableProviders.includes(p)) ||
|
|
151
|
-
availableProviders[0];
|
|
152
|
-
try {
|
|
153
|
-
const ai = getAIClient();
|
|
154
|
-
const embeddingModels = {
|
|
155
|
-
openai: 'text-embedding-3-small',
|
|
156
|
-
cohere: 'embed-english-v3.0',
|
|
157
|
-
google: 'text-embedding-004',
|
|
158
|
-
};
|
|
159
|
-
const response = await ai.embed({
|
|
160
|
-
input,
|
|
161
|
-
model: model || embeddingModels[selectedProvider] || 'text-embedding-3-small',
|
|
162
|
-
provider: selectedProvider,
|
|
163
|
-
});
|
|
164
|
-
return {
|
|
165
|
-
content: [{
|
|
166
|
-
type: 'text',
|
|
167
|
-
text: JSON.stringify({
|
|
168
|
-
dimensions: response.embeddings[0].length,
|
|
169
|
-
model: response.model,
|
|
170
|
-
provider: selectedProvider,
|
|
171
|
-
usage: response.usage,
|
|
172
|
-
preview: response.embeddings[0].slice(0, 10),
|
|
173
|
-
note: `Full embedding has ${response.embeddings[0].length} dimensions`,
|
|
174
|
-
}, null, 2),
|
|
175
|
-
}],
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
catch (error) {
|
|
179
|
-
return {
|
|
180
|
-
content: [{
|
|
181
|
-
type: 'text',
|
|
182
|
-
text: `Error generating embedding: ${error instanceof Error ? error.message : String(error)}`,
|
|
183
|
-
}],
|
|
184
|
-
isError: true,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
},
|
|
188
128
|
rek_ai_providers: async () => {
|
|
189
129
|
const available = getAvailableProviders();
|
|
190
130
|
const allProviders = [
|
|
@@ -283,28 +223,6 @@ export const aiTools = [
|
|
|
283
223
|
required: ['prompt'],
|
|
284
224
|
},
|
|
285
225
|
},
|
|
286
|
-
{
|
|
287
|
-
name: 'rek_ai_embed',
|
|
288
|
-
description: 'Generate embeddings for text. Useful for semantic search, similarity comparison, and vector storage. Returns embedding dimensions and preview.',
|
|
289
|
-
inputSchema: {
|
|
290
|
-
type: 'object',
|
|
291
|
-
properties: {
|
|
292
|
-
input: {
|
|
293
|
-
type: 'string',
|
|
294
|
-
description: 'Text to generate embeddings for',
|
|
295
|
-
},
|
|
296
|
-
model: {
|
|
297
|
-
type: 'string',
|
|
298
|
-
description: 'Embedding model (e.g., text-embedding-3-small)',
|
|
299
|
-
},
|
|
300
|
-
provider: {
|
|
301
|
-
type: 'string',
|
|
302
|
-
description: 'Provider for embeddings (openai, cohere, google)',
|
|
303
|
-
},
|
|
304
|
-
},
|
|
305
|
-
required: ['input'],
|
|
306
|
-
},
|
|
307
|
-
},
|
|
308
226
|
{
|
|
309
227
|
name: 'rek_ai_providers',
|
|
310
228
|
description: 'List all available AI providers and their configuration status. Shows which providers are configured via environment variables.',
|
package/dist/mini.d.ts
CHANGED
|
@@ -27,9 +27,3 @@ export interface MiniClient {
|
|
|
27
27
|
export declare function createMiniClient(options: MiniClientOptions): MiniClient;
|
|
28
28
|
export declare function miniGet<T = unknown>(url: string, headers?: Record<string, string>): Promise<MiniResponse<T>>;
|
|
29
29
|
export declare function miniPost<T = unknown>(url: string, data?: unknown, headers?: Record<string, string>): Promise<MiniResponse<T>>;
|
|
30
|
-
export declare const createBareClient: typeof createMiniClient;
|
|
31
|
-
export type BareClientOptions = MiniClientOptions;
|
|
32
|
-
export type BareResponse<T = unknown> = MiniResponse<T>;
|
|
33
|
-
export type BareClient = MiniClient;
|
|
34
|
-
export declare const bareGet: typeof miniGet;
|
|
35
|
-
export declare const barePost: typeof miniPost;
|
package/dist/mini.js
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "recker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.70-next.9b4eebc",
|
|
4
4
|
"description": "Multi-Protocol SDK for the AI Era - HTTP, WebSocket, DNS, FTP, SFTP, Telnet, HLS unified with AI providers and MCP tools",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -221,13 +221,12 @@
|
|
|
221
221
|
},
|
|
222
222
|
"dependencies": {
|
|
223
223
|
"@maxmind/geoip2-node": "^6.3.4",
|
|
224
|
-
"cli-args-parser": "^1.0.
|
|
224
|
+
"cli-args-parser": "^1.0.6",
|
|
225
225
|
"css-select": "^6.0.0",
|
|
226
|
-
"fuse.js": "^7.1.0",
|
|
227
226
|
"he": "^1.2.0",
|
|
228
|
-
"tuiuiu.js": "^1.0.
|
|
229
|
-
"undici": "^7.
|
|
230
|
-
"zod": "^4.3.
|
|
227
|
+
"tuiuiu.js": "^1.0.53",
|
|
228
|
+
"undici": "^7.19.0",
|
|
229
|
+
"zod": "^4.3.6"
|
|
231
230
|
},
|
|
232
231
|
"peerDependencies": {
|
|
233
232
|
"cardinal": "^2.1.0",
|
|
@@ -249,19 +248,18 @@
|
|
|
249
248
|
"@hapi/wreck": "^18.1.0",
|
|
250
249
|
"@types/he": "^1.2.3",
|
|
251
250
|
"@types/needle": "^3.3.0",
|
|
252
|
-
"@types/node": "^25.0.
|
|
251
|
+
"@types/node": "^25.0.10",
|
|
253
252
|
"@types/ssh2-sftp-client": "^9.0.6",
|
|
254
253
|
"@types/superagent": "^8.1.9",
|
|
255
254
|
"@types/ws": "^8.18.1",
|
|
256
|
-
"@vitest/coverage-v8": "^4.0.
|
|
255
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
257
256
|
"axios": "^1.13.2",
|
|
258
257
|
"cardinal": "^2.1.1",
|
|
259
258
|
"cross-fetch": "^4.1.0",
|
|
260
259
|
"domhandler": "^5.0.3",
|
|
261
260
|
"esbuild": "^0.27.2",
|
|
262
|
-
"fastembed": "^2.1.0",
|
|
263
261
|
"got": "^14.6.6",
|
|
264
|
-
"happy-dom": "^20.3.
|
|
262
|
+
"happy-dom": "^20.3.4",
|
|
265
263
|
"husky": "^9.1.7",
|
|
266
264
|
"ky": "^1.14.2",
|
|
267
265
|
"make-fetch-happen": "^15.0.3",
|
|
@@ -276,19 +274,18 @@
|
|
|
276
274
|
"superagent": "^10.3.0",
|
|
277
275
|
"tsx": "^4.21.0",
|
|
278
276
|
"typescript": "^5.9.3",
|
|
279
|
-
"vitest": "^4.0.
|
|
277
|
+
"vitest": "^4.0.18",
|
|
280
278
|
"wretch": "^3.0.6",
|
|
281
279
|
"ws": "^8.19.0",
|
|
282
|
-
"zod": "^4.3.
|
|
280
|
+
"zod": "^4.3.6"
|
|
283
281
|
},
|
|
284
282
|
"scripts": {
|
|
285
283
|
"build": "pnpm build:node && pnpm build:browser",
|
|
286
|
-
"build:node": "tsc
|
|
284
|
+
"build:node": "tsc",
|
|
287
285
|
"build:browser": "tsc -p tsconfig.browser.json",
|
|
288
286
|
"build:browser:bundle": "pnpm build:browser && node scripts/bundle-browser.js",
|
|
289
287
|
"build:cli": "node scripts/bundle-cli.js",
|
|
290
288
|
"build:binary": "npx pkg ./dist/bin/rek.cjs --output dist/bin/recker --targets node18-linux-x64,node18-macos-x64,node18-win-x64",
|
|
291
|
-
"build:embeddings": "tsx scripts/build-embeddings.ts",
|
|
292
289
|
"test": "NODE_OPTIONS='--max-old-space-size=512' vitest run",
|
|
293
290
|
"test:coverage": "NODE_OPTIONS='--max-old-space-size=512' vitest run --coverage",
|
|
294
291
|
"test:light": "NODE_OPTIONS='--max-old-space-size=256' vitest run --maxWorkers=1 --fileParallelism=false",
|
|
@@ -314,7 +311,6 @@
|
|
|
314
311
|
"docs": "pnpm serve docs -p 3000",
|
|
315
312
|
"lint": "echo \"No linting configured for this project.\" && exit 0",
|
|
316
313
|
"cli": "NODE_OPTIONS='--disable-warning=ExperimentalWarning' tsx src/cli/bootstrap.ts",
|
|
317
|
-
"mcp:start": "NODE_OPTIONS='--disable-warning=ExperimentalWarning' tsx src/mcp/bootstrap.ts"
|
|
318
|
-
"mcp:reindex": "tsx scripts/build-embeddings.ts"
|
|
314
|
+
"mcp:start": "NODE_OPTIONS='--disable-warning=ExperimentalWarning' tsx src/mcp/bootstrap.ts"
|
|
319
315
|
}
|
|
320
316
|
}
|
package/dist/ai/vector/index.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export function cosineSimilarity(a, b) {
|
|
2
|
-
if (a.length !== b.length) {
|
|
3
|
-
throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);
|
|
4
|
-
}
|
|
5
|
-
let dot = 0;
|
|
6
|
-
let normA = 0;
|
|
7
|
-
let normB = 0;
|
|
8
|
-
for (let i = 0; i < a.length; i++) {
|
|
9
|
-
dot += a[i] * b[i];
|
|
10
|
-
normA += a[i] * a[i];
|
|
11
|
-
normB += b[i] * b[i];
|
|
12
|
-
}
|
|
13
|
-
if (normA === 0 || normB === 0)
|
|
14
|
-
return 0;
|
|
15
|
-
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
16
|
-
}
|
|
17
|
-
export function euclideanDistance(a, b) {
|
|
18
|
-
if (a.length !== b.length) {
|
|
19
|
-
throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);
|
|
20
|
-
}
|
|
21
|
-
let sum = 0;
|
|
22
|
-
for (let i = 0; i < a.length; i++) {
|
|
23
|
-
const diff = a[i] - b[i];
|
|
24
|
-
sum += diff * diff;
|
|
25
|
-
}
|
|
26
|
-
return Math.sqrt(sum);
|
|
27
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { AIClient } from '../../types/ai.js';
|
|
2
|
-
export interface VectorDocument {
|
|
3
|
-
id: string;
|
|
4
|
-
content: string;
|
|
5
|
-
embedding?: number[];
|
|
6
|
-
metadata?: Record<string, unknown>;
|
|
7
|
-
}
|
|
8
|
-
export interface SearchResult extends VectorDocument {
|
|
9
|
-
score: number;
|
|
10
|
-
}
|
|
11
|
-
export interface VectorStoreOptions {
|
|
12
|
-
client?: AIClient;
|
|
13
|
-
model?: string;
|
|
14
|
-
}
|
|
15
|
-
export declare class MemoryVectorStore {
|
|
16
|
-
private documents;
|
|
17
|
-
private client?;
|
|
18
|
-
private model?;
|
|
19
|
-
constructor(options?: VectorStoreOptions);
|
|
20
|
-
add(docs: Array<Partial<VectorDocument> & {
|
|
21
|
-
content: string;
|
|
22
|
-
}>): Promise<void>;
|
|
23
|
-
search(query: string, limit?: number, threshold?: number): Promise<SearchResult[]>;
|
|
24
|
-
delete(id: string): boolean;
|
|
25
|
-
clear(): void;
|
|
26
|
-
get count(): number;
|
|
27
|
-
}
|
package/dist/ai/vector/store.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { cosineSimilarity } from './similarity.js';
|
|
2
|
-
export class MemoryVectorStore {
|
|
3
|
-
documents = new Map();
|
|
4
|
-
client;
|
|
5
|
-
model;
|
|
6
|
-
constructor(options = {}) {
|
|
7
|
-
this.client = options.client;
|
|
8
|
-
this.model = options.model;
|
|
9
|
-
}
|
|
10
|
-
async add(docs) {
|
|
11
|
-
const docsToEmbed = [];
|
|
12
|
-
const readyDocs = [];
|
|
13
|
-
for (const doc of docs) {
|
|
14
|
-
const id = doc.id || Math.random().toString(36).substring(7);
|
|
15
|
-
const fullDoc = {
|
|
16
|
-
id,
|
|
17
|
-
content: doc.content,
|
|
18
|
-
metadata: doc.metadata || {},
|
|
19
|
-
embedding: doc.embedding,
|
|
20
|
-
};
|
|
21
|
-
if (!fullDoc.embedding) {
|
|
22
|
-
docsToEmbed.push(fullDoc);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
readyDocs.push(fullDoc);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (docsToEmbed.length > 0) {
|
|
29
|
-
if (!this.client) {
|
|
30
|
-
throw new Error('AI Client required to generate embeddings. Pass "client" to constructor or provide "embedding" in document.');
|
|
31
|
-
}
|
|
32
|
-
const contents = docsToEmbed.map(d => d.content);
|
|
33
|
-
const response = await this.client.embed({
|
|
34
|
-
model: this.model,
|
|
35
|
-
input: contents,
|
|
36
|
-
});
|
|
37
|
-
docsToEmbed.forEach((doc, i) => {
|
|
38
|
-
doc.embedding = response.embeddings[i];
|
|
39
|
-
readyDocs.push(doc);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
for (const doc of readyDocs) {
|
|
43
|
-
this.documents.set(doc.id, doc);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
async search(query, limit = 3, threshold = 0.0) {
|
|
47
|
-
if (this.documents.size === 0)
|
|
48
|
-
return [];
|
|
49
|
-
if (!this.client) {
|
|
50
|
-
throw new Error('AI Client required to search by text query.');
|
|
51
|
-
}
|
|
52
|
-
const response = await this.client.embed({
|
|
53
|
-
model: this.model,
|
|
54
|
-
input: query,
|
|
55
|
-
});
|
|
56
|
-
const queryEmbedding = response.embeddings[0];
|
|
57
|
-
const results = [];
|
|
58
|
-
for (const doc of this.documents.values()) {
|
|
59
|
-
if (!doc.embedding)
|
|
60
|
-
continue;
|
|
61
|
-
const score = cosineSimilarity(queryEmbedding, doc.embedding);
|
|
62
|
-
if (score >= threshold) {
|
|
63
|
-
results.push({
|
|
64
|
-
...doc,
|
|
65
|
-
score,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return results
|
|
70
|
-
.sort((a, b) => b.score - a.score)
|
|
71
|
-
.slice(0, limit);
|
|
72
|
-
}
|
|
73
|
-
delete(id) {
|
|
74
|
-
return this.documents.delete(id);
|
|
75
|
-
}
|
|
76
|
-
clear() {
|
|
77
|
-
this.documents.clear();
|
|
78
|
-
}
|
|
79
|
-
get count() {
|
|
80
|
-
return this.documents.size;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export function cosineSimilarity(a, b) {
|
|
2
|
-
if (a.length !== b.length) {
|
|
3
|
-
throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);
|
|
4
|
-
}
|
|
5
|
-
let dot = 0;
|
|
6
|
-
let normA = 0;
|
|
7
|
-
let normB = 0;
|
|
8
|
-
for (let i = 0; i < a.length; i++) {
|
|
9
|
-
dot += a[i] * b[i];
|
|
10
|
-
normA += a[i] * a[i];
|
|
11
|
-
normB += b[i] * b[i];
|
|
12
|
-
}
|
|
13
|
-
if (normA === 0 || normB === 0)
|
|
14
|
-
return 0;
|
|
15
|
-
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
16
|
-
}
|
|
17
|
-
export function euclideanDistance(a, b) {
|
|
18
|
-
if (a.length !== b.length) {
|
|
19
|
-
throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);
|
|
20
|
-
}
|
|
21
|
-
let sum = 0;
|
|
22
|
-
for (let i = 0; i < a.length; i++) {
|
|
23
|
-
const diff = a[i] - b[i];
|
|
24
|
-
sum += diff * diff;
|
|
25
|
-
}
|
|
26
|
-
return Math.sqrt(sum);
|
|
27
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { AIClient } from '../../types/ai.js';
|
|
2
|
-
export interface VectorDocument {
|
|
3
|
-
id: string;
|
|
4
|
-
content: string;
|
|
5
|
-
embedding?: number[];
|
|
6
|
-
metadata?: Record<string, unknown>;
|
|
7
|
-
}
|
|
8
|
-
export interface SearchResult extends VectorDocument {
|
|
9
|
-
score: number;
|
|
10
|
-
}
|
|
11
|
-
export interface VectorStoreOptions {
|
|
12
|
-
client?: AIClient;
|
|
13
|
-
model?: string;
|
|
14
|
-
}
|
|
15
|
-
export declare class MemoryVectorStore {
|
|
16
|
-
private documents;
|
|
17
|
-
private client?;
|
|
18
|
-
private model?;
|
|
19
|
-
constructor(options?: VectorStoreOptions);
|
|
20
|
-
add(docs: Array<Partial<VectorDocument> & {
|
|
21
|
-
content: string;
|
|
22
|
-
}>): Promise<void>;
|
|
23
|
-
search(query: string, limit?: number, threshold?: number): Promise<SearchResult[]>;
|
|
24
|
-
delete(id: string): boolean;
|
|
25
|
-
clear(): void;
|
|
26
|
-
get count(): number;
|
|
27
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { cosineSimilarity } from './similarity.js';
|
|
2
|
-
export class MemoryVectorStore {
|
|
3
|
-
documents = new Map();
|
|
4
|
-
client;
|
|
5
|
-
model;
|
|
6
|
-
constructor(options = {}) {
|
|
7
|
-
this.client = options.client;
|
|
8
|
-
this.model = options.model;
|
|
9
|
-
}
|
|
10
|
-
async add(docs) {
|
|
11
|
-
const docsToEmbed = [];
|
|
12
|
-
const readyDocs = [];
|
|
13
|
-
for (const doc of docs) {
|
|
14
|
-
const id = doc.id || Math.random().toString(36).substring(7);
|
|
15
|
-
const fullDoc = {
|
|
16
|
-
id,
|
|
17
|
-
content: doc.content,
|
|
18
|
-
metadata: doc.metadata || {},
|
|
19
|
-
embedding: doc.embedding,
|
|
20
|
-
};
|
|
21
|
-
if (!fullDoc.embedding) {
|
|
22
|
-
docsToEmbed.push(fullDoc);
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
readyDocs.push(fullDoc);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (docsToEmbed.length > 0) {
|
|
29
|
-
if (!this.client) {
|
|
30
|
-
throw new Error('AI Client required to generate embeddings. Pass "client" to constructor or provide "embedding" in document.');
|
|
31
|
-
}
|
|
32
|
-
const contents = docsToEmbed.map(d => d.content);
|
|
33
|
-
const response = await this.client.embed({
|
|
34
|
-
model: this.model,
|
|
35
|
-
input: contents,
|
|
36
|
-
});
|
|
37
|
-
docsToEmbed.forEach((doc, i) => {
|
|
38
|
-
doc.embedding = response.embeddings[i];
|
|
39
|
-
readyDocs.push(doc);
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
for (const doc of readyDocs) {
|
|
43
|
-
this.documents.set(doc.id, doc);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
async search(query, limit = 3, threshold = 0.0) {
|
|
47
|
-
if (this.documents.size === 0)
|
|
48
|
-
return [];
|
|
49
|
-
if (!this.client) {
|
|
50
|
-
throw new Error('AI Client required to search by text query.');
|
|
51
|
-
}
|
|
52
|
-
const response = await this.client.embed({
|
|
53
|
-
model: this.model,
|
|
54
|
-
input: query,
|
|
55
|
-
});
|
|
56
|
-
const queryEmbedding = response.embeddings[0];
|
|
57
|
-
const results = [];
|
|
58
|
-
for (const doc of this.documents.values()) {
|
|
59
|
-
if (!doc.embedding)
|
|
60
|
-
continue;
|
|
61
|
-
const score = cosineSimilarity(queryEmbedding, doc.embedding);
|
|
62
|
-
if (score >= threshold) {
|
|
63
|
-
results.push({
|
|
64
|
-
...doc,
|
|
65
|
-
score,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return results
|
|
70
|
-
.sort((a, b) => b.score - a.score)
|
|
71
|
-
.slice(0, limit);
|
|
72
|
-
}
|
|
73
|
-
delete(id) {
|
|
74
|
-
return this.documents.delete(id);
|
|
75
|
-
}
|
|
76
|
-
clear() {
|
|
77
|
-
this.documents.clear();
|
|
78
|
-
}
|
|
79
|
-
get count() {
|
|
80
|
-
return this.documents.size;
|
|
81
|
-
}
|
|
82
|
-
}
|