cmp-standards 2.4.0 → 2.6.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/README.md +633 -611
- package/dist/db/drizzle-client.d.ts +3 -3
- package/dist/db/drizzle-client.d.ts.map +1 -1
- package/dist/db/drizzle-client.js +57 -58
- package/dist/db/drizzle-client.js.map +1 -1
- package/dist/db/turso-client.js +11 -11
- package/dist/eslint/rules/no-async-useeffect.js +6 -6
- package/dist/hooks/cloud-pre-tool-use.js +20 -20
- package/dist/hooks/cloud-session-start.d.ts +15 -3
- package/dist/hooks/cloud-session-start.d.ts.map +1 -1
- package/dist/hooks/cloud-session-start.js +135 -8
- package/dist/hooks/cloud-session-start.js.map +1 -1
- package/dist/hooks/session-start.d.ts +2 -1
- package/dist/hooks/session-start.d.ts.map +1 -1
- package/dist/hooks/session-start.js +99 -74
- package/dist/hooks/session-start.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +2 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/schema/plans.d.ts +194 -0
- package/dist/schema/plans.d.ts.map +1 -0
- package/dist/schema/plans.js +180 -0
- package/dist/schema/plans.js.map +1 -0
- package/dist/services/ContextGenerator.d.ts +16 -0
- package/dist/services/ContextGenerator.d.ts.map +1 -0
- package/dist/services/ContextGenerator.js +62 -0
- package/dist/services/ContextGenerator.js.map +1 -0
- package/dist/services/PlanManager.d.ts +99 -0
- package/dist/services/PlanManager.d.ts.map +1 -0
- package/dist/services/PlanManager.js +372 -0
- package/dist/services/PlanManager.js.map +1 -0
- package/dist/services/ProjectScaffold.js +76 -76
- package/dist/services/context-injector.d.ts +105 -0
- package/dist/services/context-injector.d.ts.map +1 -0
- package/dist/services/context-injector.js +357 -0
- package/dist/services/context-injector.js.map +1 -0
- package/dist/services/index.d.ts +15 -15
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +18 -20
- package/dist/services/index.js.map +1 -1
- package/dist/services/memory-router.d.ts +98 -0
- package/dist/services/memory-router.d.ts.map +1 -0
- package/dist/services/memory-router.js +373 -0
- package/dist/services/memory-router.js.map +1 -0
- package/dist/services/pattern-tracker.d.ts +93 -0
- package/dist/services/pattern-tracker.d.ts.map +1 -0
- package/dist/services/pattern-tracker.js +347 -0
- package/dist/services/pattern-tracker.js.map +1 -0
- package/dist/services/semantic-search.d.ts +33 -35
- package/dist/services/semantic-search.d.ts.map +1 -1
- package/dist/services/semantic-search.js +207 -165
- package/dist/services/semantic-search.js.map +1 -1
- package/package.json +100 -100
- package/standards/README.md +50 -50
- package/standards/experts/expert-routing.md +215 -215
- package/standards/general/code-quality.md +86 -86
- package/standards/general/memory-usage.md +205 -205
- package/standards/general/sync-workflow.md +235 -235
- package/standards/general/workflow.md +82 -82
- package/standards/hooks/mandatory-tracking.md +446 -446
- package/standards/infrastructure/cloud-database.md +287 -287
- package/standards/mcp/server-design.md +243 -243
- package/standards/mcp/tool-patterns.md +354 -354
- package/standards/skills/skill-structure.md +286 -286
- package/standards/skills/workflow-design.md +323 -323
- package/standards/tools/tool-design.md +297 -297
- package/templates/agents/architecture-expert.md +61 -61
- package/templates/agents/database-expert.md +62 -62
- package/templates/agents/documentation-expert.md +57 -57
- package/templates/agents/memory-expert.md +88 -88
- package/templates/agents/performance-expert.md +61 -61
- package/templates/agents/security-expert.md +59 -59
- package/templates/agents/ux-expert.md +63 -63
- package/templates/agents/worker.md +75 -75
- package/templates/ai-skills/SKILL_TEMPLATE.md +55 -55
- package/templates/claude-settings.json +72 -72
- package/templates/commands/experts.md +138 -138
- package/templates/hooks/README.md +158 -158
- package/templates/hooks/project.config.json.template +77 -77
- package/templates/hooks/settings.local.json.template +57 -57
- package/templates/memory-config.json +56 -56
- package/templates/memory-config.schema.json +212 -212
- package/templates/settings.json +58 -58
- package/templates/skills/continue.md +205 -205
- package/templates/workflows/business-improvement.md +264 -264
- package/templates/workflows/expert-review.md +153 -153
- package/templates/workflows/internal-app.md +245 -245
- package/templates/workflows/sync-docs.md +187 -187
|
@@ -1,91 +1,101 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Semantic Search Service
|
|
3
3
|
*
|
|
4
|
-
* Provides
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* - Performs cosine similarity search
|
|
4
|
+
* Provides hybrid search for memories:
|
|
5
|
+
* 1. Vector Search (Upstash): Semantic understanding
|
|
6
|
+
* 2. Text Search (MySQL): Keyword matching
|
|
8
7
|
*/
|
|
9
|
-
import { EmbeddingService } from
|
|
8
|
+
import { EmbeddingService } from "../registry/embeddings.js";
|
|
9
|
+
import { Index } from "@upstash/vector";
|
|
10
10
|
// =============================================================================
|
|
11
11
|
// SEMANTIC SEARCH SERVICE
|
|
12
12
|
// =============================================================================
|
|
13
13
|
export class SemanticSearchService {
|
|
14
14
|
embeddingService;
|
|
15
15
|
client;
|
|
16
|
+
vectorIndex;
|
|
16
17
|
cache = new Map();
|
|
17
18
|
constructor(client) {
|
|
18
19
|
this.client = client;
|
|
19
20
|
this.embeddingService = new EmbeddingService({
|
|
20
|
-
providers: [
|
|
21
|
+
providers: ["openai", "gemini"],
|
|
21
22
|
openaiApiKey: process.env.OPENAI_API_KEY,
|
|
22
23
|
geminiApiKey: process.env.GEMINI_API_KEY,
|
|
23
24
|
});
|
|
25
|
+
if (process.env.UPSTASH_VECTOR_REST_URL && process.env.UPSTASH_VECTOR_REST_TOKEN) {
|
|
26
|
+
this.vectorIndex = new Index({
|
|
27
|
+
url: process.env.UPSTASH_VECTOR_REST_URL,
|
|
28
|
+
token: process.env.UPSTASH_VECTOR_REST_TOKEN,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
24
31
|
}
|
|
25
32
|
/**
|
|
26
|
-
* Search
|
|
33
|
+
* Hybrid Search: Vector + Keyword
|
|
27
34
|
*/
|
|
28
35
|
async search(query, options) {
|
|
29
36
|
const limit = options?.limit ?? 10;
|
|
30
37
|
const threshold = options?.threshold ?? 0.5;
|
|
31
|
-
const type = options?.type ??
|
|
38
|
+
const type = options?.type ?? "memory";
|
|
39
|
+
const [vectorResults, textResults] = await Promise.all([
|
|
40
|
+
this.searchVector(query, { limit, threshold }),
|
|
41
|
+
this.fallbackTextSearch(query, options),
|
|
42
|
+
]);
|
|
43
|
+
// Merge and deduplicate by item ID
|
|
44
|
+
const merged = new Map();
|
|
45
|
+
// Text results first (base)
|
|
46
|
+
textResults.forEach((r) => merged.set(r.item.id, r));
|
|
47
|
+
// Vector results (override/add)
|
|
48
|
+
vectorResults.forEach((r) => {
|
|
49
|
+
const existing = merged.get(r.item.id);
|
|
50
|
+
if (!existing || r.score > existing.score) {
|
|
51
|
+
merged.set(r.item.id, r);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return Array.from(merged.values())
|
|
55
|
+
.sort((a, b) => b.score - a.score)
|
|
56
|
+
.slice(0, limit);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Search via Upstash Vector
|
|
60
|
+
*/
|
|
61
|
+
async searchVector(query, options) {
|
|
62
|
+
if (!this.vectorIndex)
|
|
63
|
+
return [];
|
|
32
64
|
try {
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
limit: 200, // Get more items to filter
|
|
65
|
+
const embedding = await this.getEmbedding(query);
|
|
66
|
+
const results = await this.vectorIndex.query({
|
|
67
|
+
vector: embedding,
|
|
68
|
+
topK: options.limit,
|
|
69
|
+
includeMetadata: true,
|
|
39
70
|
});
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
const content = item.content;
|
|
44
|
-
if (!content)
|
|
45
|
-
continue;
|
|
46
|
-
// Filter by domain if specified
|
|
47
|
-
if (options?.domain && content.domain !== options.domain)
|
|
71
|
+
const matchedResults = [];
|
|
72
|
+
for (const res of results) {
|
|
73
|
+
if (res.score < options.threshold)
|
|
48
74
|
continue;
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
if (
|
|
52
|
-
|
|
53
|
-
const text = `${content.title}\n${content.body}`;
|
|
54
|
-
try {
|
|
55
|
-
itemEmbedding = await this.getEmbedding(text);
|
|
56
|
-
// Update the item with embedding (async, don't wait)
|
|
57
|
-
this.updateWithEmbedding(item.id, content, itemEmbedding).catch(() => { });
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
continue; // Skip items we can't embed
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
// Calculate cosine similarity
|
|
64
|
-
const score = this.cosineSimilarity(queryEmbedding, itemEmbedding);
|
|
65
|
-
if (score >= threshold) {
|
|
66
|
-
scored.push({
|
|
75
|
+
// Fetch full item from DB to ensure schema consistency
|
|
76
|
+
const item = await this.client.get(res.id);
|
|
77
|
+
if (item) {
|
|
78
|
+
matchedResults.push({
|
|
67
79
|
item,
|
|
68
|
-
score,
|
|
69
|
-
content: content,
|
|
80
|
+
score: res.score,
|
|
81
|
+
content: item.content,
|
|
82
|
+
source: "vector",
|
|
70
83
|
});
|
|
71
84
|
}
|
|
72
85
|
}
|
|
73
|
-
|
|
74
|
-
scored.sort((a, b) => b.score - a.score);
|
|
75
|
-
return scored.slice(0, limit);
|
|
86
|
+
return matchedResults;
|
|
76
87
|
}
|
|
77
88
|
catch (error) {
|
|
78
|
-
console.
|
|
79
|
-
|
|
80
|
-
return this.fallbackTextSearch(query, options);
|
|
89
|
+
console.warn("[SemanticSearch] Vector search failed:", error);
|
|
90
|
+
return [];
|
|
81
91
|
}
|
|
82
92
|
}
|
|
83
93
|
/**
|
|
84
|
-
* Create memory with embedding
|
|
94
|
+
* Create memory with embedding and sync to Vector DB
|
|
85
95
|
*/
|
|
86
96
|
async createMemoryWithEmbedding(title, body, options) {
|
|
87
|
-
|
|
88
|
-
|
|
97
|
+
const text = `${title}
|
|
98
|
+
${body}`;
|
|
89
99
|
let embedding;
|
|
90
100
|
let embeddingModel;
|
|
91
101
|
try {
|
|
@@ -93,23 +103,44 @@ export class SemanticSearchService {
|
|
|
93
103
|
embeddingModel = this.embeddingService.getProviderInfo().provider;
|
|
94
104
|
}
|
|
95
105
|
catch (error) {
|
|
96
|
-
console.warn(
|
|
106
|
+
console.warn("[SemanticSearch] Could not generate embedding:", error);
|
|
97
107
|
}
|
|
98
|
-
// Create content with embedding
|
|
99
108
|
const content = {
|
|
100
109
|
title,
|
|
101
110
|
body,
|
|
102
111
|
domain: options?.domain,
|
|
103
|
-
source: options?.source ??
|
|
112
|
+
source: options?.source ?? "system",
|
|
104
113
|
relatedFiles: options?.relatedFiles,
|
|
105
114
|
embedding,
|
|
106
115
|
embeddingModel,
|
|
107
116
|
embeddedAt: embedding ? new Date().toISOString() : undefined,
|
|
108
117
|
};
|
|
109
118
|
const result = await this.client.createMemory(content, options?.tags);
|
|
119
|
+
// Sync to Upstash Vector if available
|
|
120
|
+
let synced = false;
|
|
121
|
+
if (this.vectorIndex && embedding) {
|
|
122
|
+
try {
|
|
123
|
+
await this.vectorIndex.upsert({
|
|
124
|
+
id: result.id,
|
|
125
|
+
vector: embedding,
|
|
126
|
+
metadata: {
|
|
127
|
+
title,
|
|
128
|
+
type: "memory",
|
|
129
|
+
source: content.source,
|
|
130
|
+
domain: content.domain,
|
|
131
|
+
timestamp: new Date().toISOString(),
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
synced = true;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
console.warn("[SemanticSearch] Vector sync failed:", error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
110
140
|
return {
|
|
111
141
|
id: result.id,
|
|
112
142
|
embedded: !!embedding,
|
|
143
|
+
synced,
|
|
113
144
|
};
|
|
114
145
|
}
|
|
115
146
|
/**
|
|
@@ -122,77 +153,10 @@ export class SemanticSearchService {
|
|
|
122
153
|
const content = memory.content;
|
|
123
154
|
if (!content)
|
|
124
155
|
return [];
|
|
125
|
-
const text = `${content.title}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Batch embed all memories without embeddings
|
|
131
|
-
*/
|
|
132
|
-
async batchEmbed(options) {
|
|
133
|
-
const type = options?.type ?? 'memory';
|
|
134
|
-
const limit = options?.limit ?? 100;
|
|
135
|
-
const force = options?.force ?? false;
|
|
136
|
-
const items = await this.client.list({ type, limit });
|
|
137
|
-
let processed = 0;
|
|
138
|
-
let embedded = 0;
|
|
139
|
-
let failed = 0;
|
|
140
|
-
for (const item of items) {
|
|
141
|
-
processed++;
|
|
142
|
-
const content = item.content;
|
|
143
|
-
if (!content) {
|
|
144
|
-
failed++;
|
|
145
|
-
continue;
|
|
146
|
-
}
|
|
147
|
-
// Skip if already has embedding (unless force)
|
|
148
|
-
if (content.embedding && !force)
|
|
149
|
-
continue;
|
|
150
|
-
const text = `${content.title || ''}\n${content.body || ''}`;
|
|
151
|
-
if (!text.trim()) {
|
|
152
|
-
failed++;
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
try {
|
|
156
|
-
const embedding = await this.embeddingService.embed(text);
|
|
157
|
-
await this.updateWithEmbedding(item.id, content, embedding);
|
|
158
|
-
embedded++;
|
|
159
|
-
// Rate limit
|
|
160
|
-
await new Promise(r => setTimeout(r, 100));
|
|
161
|
-
}
|
|
162
|
-
catch {
|
|
163
|
-
failed++;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
return { processed, embedded, failed };
|
|
156
|
+
const text = `${content.title}
|
|
157
|
+
${content.body}`;
|
|
158
|
+
return this.search(text, { limit: limit + 1 }).then((results) => results.filter((r) => r.item.id !== memoryId).slice(0, limit));
|
|
167
159
|
}
|
|
168
|
-
/**
|
|
169
|
-
* Get embedding statistics
|
|
170
|
-
*/
|
|
171
|
-
async getEmbeddingStats() {
|
|
172
|
-
const items = await this.client.list({ type: 'memory', limit: 1000 });
|
|
173
|
-
let withEmbedding = 0;
|
|
174
|
-
let withoutEmbedding = 0;
|
|
175
|
-
for (const item of items) {
|
|
176
|
-
const content = item.content;
|
|
177
|
-
if (content?.embedding) {
|
|
178
|
-
withEmbedding++;
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
withoutEmbedding++;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
const total = withEmbedding + withoutEmbedding;
|
|
185
|
-
const coverage = total > 0 ? (withEmbedding / total) * 100 : 0;
|
|
186
|
-
return {
|
|
187
|
-
total,
|
|
188
|
-
withEmbedding,
|
|
189
|
-
withoutEmbedding,
|
|
190
|
-
coverage: Math.round(coverage * 10) / 10,
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
// ===========================================================================
|
|
194
|
-
// PRIVATE METHODS
|
|
195
|
-
// ===========================================================================
|
|
196
160
|
/**
|
|
197
161
|
* Get embedding with caching
|
|
198
162
|
*/
|
|
@@ -202,7 +166,6 @@ export class SemanticSearchService {
|
|
|
202
166
|
if (cached)
|
|
203
167
|
return cached;
|
|
204
168
|
const embedding = await this.embeddingService.embed(text);
|
|
205
|
-
// Cache with LRU eviction
|
|
206
169
|
if (this.cache.size > 100) {
|
|
207
170
|
const firstKey = this.cache.keys().next().value;
|
|
208
171
|
if (firstKey)
|
|
@@ -211,39 +174,6 @@ export class SemanticSearchService {
|
|
|
211
174
|
this.cache.set(cacheKey, embedding);
|
|
212
175
|
return embedding;
|
|
213
176
|
}
|
|
214
|
-
/**
|
|
215
|
-
* Update memory with embedding
|
|
216
|
-
*/
|
|
217
|
-
async updateWithEmbedding(id, content, embedding) {
|
|
218
|
-
const updatedContent = {
|
|
219
|
-
...content,
|
|
220
|
-
embedding,
|
|
221
|
-
embeddingModel: this.embeddingService.getProviderInfo().provider,
|
|
222
|
-
embeddedAt: new Date().toISOString(),
|
|
223
|
-
};
|
|
224
|
-
await this.client.update(id, {
|
|
225
|
-
content: updatedContent,
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Calculate cosine similarity between two vectors
|
|
230
|
-
*/
|
|
231
|
-
cosineSimilarity(a, b) {
|
|
232
|
-
if (a.length !== b.length)
|
|
233
|
-
return 0;
|
|
234
|
-
let dotProduct = 0;
|
|
235
|
-
let normA = 0;
|
|
236
|
-
let normB = 0;
|
|
237
|
-
for (let i = 0; i < a.length; i++) {
|
|
238
|
-
dotProduct += a[i] * b[i];
|
|
239
|
-
normA += a[i] * a[i];
|
|
240
|
-
normB += b[i] * b[i];
|
|
241
|
-
}
|
|
242
|
-
const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
|
|
243
|
-
if (magnitude === 0)
|
|
244
|
-
return 0;
|
|
245
|
-
return dotProduct / magnitude;
|
|
246
|
-
}
|
|
247
177
|
/**
|
|
248
178
|
* Fallback to text search when embedding fails
|
|
249
179
|
*/
|
|
@@ -253,24 +183,136 @@ export class SemanticSearchService {
|
|
|
253
183
|
limit: options?.limit,
|
|
254
184
|
});
|
|
255
185
|
return results
|
|
256
|
-
.filter(item => {
|
|
186
|
+
.filter((item) => {
|
|
257
187
|
if (!options?.domain)
|
|
258
188
|
return true;
|
|
259
189
|
const content = item.content;
|
|
260
190
|
return content?.domain === options.domain;
|
|
261
191
|
})
|
|
262
|
-
.map(item => ({
|
|
192
|
+
.map((item) => ({
|
|
263
193
|
item,
|
|
264
|
-
score: 1.0,
|
|
194
|
+
score: 1.0,
|
|
265
195
|
content: item.content,
|
|
196
|
+
source: "text",
|
|
266
197
|
}));
|
|
267
198
|
}
|
|
199
|
+
/**
|
|
200
|
+
* Batch embed memories that don't have embeddings yet
|
|
201
|
+
*/
|
|
202
|
+
async batchEmbed(options) {
|
|
203
|
+
const limit = options.limit ?? 50;
|
|
204
|
+
let processed = 0;
|
|
205
|
+
let succeeded = 0;
|
|
206
|
+
let failed = 0;
|
|
207
|
+
let synced = 0;
|
|
208
|
+
try {
|
|
209
|
+
// Get memories without embeddings
|
|
210
|
+
const items = await this.client.list({
|
|
211
|
+
type: 'memory',
|
|
212
|
+
limit,
|
|
213
|
+
});
|
|
214
|
+
for (const item of items) {
|
|
215
|
+
const content = item.content;
|
|
216
|
+
if (content?.embedding)
|
|
217
|
+
continue; // Already has embedding
|
|
218
|
+
processed++;
|
|
219
|
+
try {
|
|
220
|
+
const text = `${content?.title || ''}\n${content?.body || ''}`;
|
|
221
|
+
if (!text.trim())
|
|
222
|
+
continue;
|
|
223
|
+
const embedding = await this.embeddingService.embed(text);
|
|
224
|
+
// Update item with embedding
|
|
225
|
+
await this.client.update(item.id, {
|
|
226
|
+
content: {
|
|
227
|
+
...content,
|
|
228
|
+
embedding,
|
|
229
|
+
embeddingModel: this.embeddingService.getProviderInfo().provider,
|
|
230
|
+
embeddedAt: new Date().toISOString(),
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
succeeded++;
|
|
234
|
+
// Sync to vector DB
|
|
235
|
+
if (this.vectorIndex) {
|
|
236
|
+
try {
|
|
237
|
+
await this.vectorIndex.upsert({
|
|
238
|
+
id: item.id,
|
|
239
|
+
vector: embedding,
|
|
240
|
+
metadata: {
|
|
241
|
+
title: content?.title,
|
|
242
|
+
type: 'memory',
|
|
243
|
+
domain: content?.domain,
|
|
244
|
+
timestamp: new Date().toISOString(),
|
|
245
|
+
},
|
|
246
|
+
});
|
|
247
|
+
synced++;
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
// Vector sync failed but embedding succeeded
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
failed++;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
console.error('[SemanticSearch] batchEmbed error:', error);
|
|
261
|
+
}
|
|
262
|
+
return { processed, succeeded, failed, synced };
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Get embedding statistics
|
|
266
|
+
*/
|
|
267
|
+
async getEmbeddingStats() {
|
|
268
|
+
try {
|
|
269
|
+
const items = await this.client.list({
|
|
270
|
+
type: 'memory',
|
|
271
|
+
limit: 1000,
|
|
272
|
+
});
|
|
273
|
+
let withEmbeddings = 0;
|
|
274
|
+
for (const item of items) {
|
|
275
|
+
const content = item.content;
|
|
276
|
+
if (content?.embedding)
|
|
277
|
+
withEmbeddings++;
|
|
278
|
+
}
|
|
279
|
+
let vectorIndexCount = 0;
|
|
280
|
+
if (this.vectorIndex) {
|
|
281
|
+
try {
|
|
282
|
+
const info = await this.vectorIndex.info();
|
|
283
|
+
vectorIndexCount = info.vectorCount ?? 0;
|
|
284
|
+
}
|
|
285
|
+
catch {
|
|
286
|
+
// Vector index info failed
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const totalMemories = items.length;
|
|
290
|
+
const withoutEmbeddings = totalMemories - withEmbeddings;
|
|
291
|
+
const embeddingRate = totalMemories > 0
|
|
292
|
+
? `${Math.round((withEmbeddings / totalMemories) * 100)}%`
|
|
293
|
+
: '0%';
|
|
294
|
+
return {
|
|
295
|
+
totalMemories,
|
|
296
|
+
withEmbeddings,
|
|
297
|
+
withoutEmbeddings,
|
|
298
|
+
vectorIndexCount,
|
|
299
|
+
embeddingRate,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
console.error('[SemanticSearch] getEmbeddingStats error:', error);
|
|
304
|
+
return {
|
|
305
|
+
totalMemories: 0,
|
|
306
|
+
withEmbeddings: 0,
|
|
307
|
+
withoutEmbeddings: 0,
|
|
308
|
+
vectorIndexCount: 0,
|
|
309
|
+
embeddingRate: '0%',
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
}
|
|
268
313
|
}
|
|
269
|
-
// =============================================================================
|
|
270
|
-
// FACTORY
|
|
271
|
-
// =============================================================================
|
|
272
314
|
/**
|
|
273
|
-
*
|
|
315
|
+
* Factory
|
|
274
316
|
*/
|
|
275
317
|
export function createSemanticSearchService(client) {
|
|
276
318
|
return new SemanticSearchService(client);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../src/services/semantic-search.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"semantic-search.js","sourceRoot":"","sources":["../../src/services/semantic-search.ts"],"names":[],"mappings":"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"}
|