@scenemesh/entity-engine-aimodule 1.0.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/LICENSE +21 -0
- package/README.md +854 -0
- package/dist/ai-core-LBGYFGOK.mjs +17 -0
- package/dist/ai-core-LBGYFGOK.mjs.map +1 -0
- package/dist/ai-core-UGJWSCQN.js +17 -0
- package/dist/ai-core-UGJWSCQN.js.map +1 -0
- package/dist/ai-core-manager-B3Z34RHA.mjs +9 -0
- package/dist/ai-core-manager-B3Z34RHA.mjs.map +1 -0
- package/dist/ai-core-manager-W7SSDCG5.js +9 -0
- package/dist/ai-core-manager-W7SSDCG5.js.map +1 -0
- package/dist/ai-embeddings-5ED5LDXX.mjs +17 -0
- package/dist/ai-embeddings-5ED5LDXX.mjs.map +1 -0
- package/dist/ai-embeddings-WCXZMMTZ.js +17 -0
- package/dist/ai-embeddings-WCXZMMTZ.js.map +1 -0
- package/dist/ai-form-renderer-24IWNMX5.js +233 -0
- package/dist/ai-form-renderer-24IWNMX5.js.map +1 -0
- package/dist/ai-form-renderer-BORQABF2.mjs +233 -0
- package/dist/ai-form-renderer-BORQABF2.mjs.map +1 -0
- package/dist/ai-provider-3PSCVEEN.mjs +17 -0
- package/dist/ai-provider-3PSCVEEN.mjs.map +1 -0
- package/dist/ai-provider-WMPMVZFL.js +17 -0
- package/dist/ai-provider-WMPMVZFL.js.map +1 -0
- package/dist/ai-renderer-7WGGWH5D.mjs +134 -0
- package/dist/ai-renderer-7WGGWH5D.mjs.map +1 -0
- package/dist/ai-renderer-OILYWAJV.js +134 -0
- package/dist/ai-renderer-OILYWAJV.js.map +1 -0
- package/dist/ai-settings-DGCFPK3U.js +15 -0
- package/dist/ai-settings-DGCFPK3U.js.map +1 -0
- package/dist/ai-settings-DTXEAB64.mjs +15 -0
- package/dist/ai-settings-DTXEAB64.mjs.map +1 -0
- package/dist/ai-structured-EGZ26ZS4.mjs +13 -0
- package/dist/ai-structured-EGZ26ZS4.mjs.map +1 -0
- package/dist/ai-structured-N2FZLO4A.js +13 -0
- package/dist/ai-structured-N2FZLO4A.js.map +1 -0
- package/dist/ai-tools-B3R77HZ3.js +19 -0
- package/dist/ai-tools-B3R77HZ3.js.map +1 -0
- package/dist/ai-tools-JAPVYQGE.mjs +19 -0
- package/dist/ai-tools-JAPVYQGE.mjs.map +1 -0
- package/dist/ai.module-GAHVCBTP.js +7 -0
- package/dist/ai.module-GAHVCBTP.js.map +1 -0
- package/dist/ai.module-TTPMTPB3.mjs +7 -0
- package/dist/ai.module-TTPMTPB3.mjs.map +1 -0
- package/dist/chunk-25C2NRSD.mjs +611 -0
- package/dist/chunk-25C2NRSD.mjs.map +1 -0
- package/dist/chunk-4JQ7UOXH.js +427 -0
- package/dist/chunk-4JQ7UOXH.js.map +1 -0
- package/dist/chunk-6IUKES2L.js +290 -0
- package/dist/chunk-6IUKES2L.js.map +1 -0
- package/dist/chunk-COWPK7XN.mjs +834 -0
- package/dist/chunk-COWPK7XN.mjs.map +1 -0
- package/dist/chunk-CTEXPMVZ.js +512 -0
- package/dist/chunk-CTEXPMVZ.js.map +1 -0
- package/dist/chunk-DXQTHA75.js +573 -0
- package/dist/chunk-DXQTHA75.js.map +1 -0
- package/dist/chunk-DZFQ6I23.js +72 -0
- package/dist/chunk-DZFQ6I23.js.map +1 -0
- package/dist/chunk-J323UTPE.mjs +650 -0
- package/dist/chunk-J323UTPE.mjs.map +1 -0
- package/dist/chunk-LHNNALVF.js +834 -0
- package/dist/chunk-LHNNALVF.js.map +1 -0
- package/dist/chunk-O7SZSMXV.js +1621 -0
- package/dist/chunk-O7SZSMXV.js.map +1 -0
- package/dist/chunk-OTNOFOVW.js +650 -0
- package/dist/chunk-OTNOFOVW.js.map +1 -0
- package/dist/chunk-PRIGZEI4.mjs +72 -0
- package/dist/chunk-PRIGZEI4.mjs.map +1 -0
- package/dist/chunk-SBSZ3IPB.mjs +573 -0
- package/dist/chunk-SBSZ3IPB.mjs.map +1 -0
- package/dist/chunk-SXPA6SSD.mjs +1621 -0
- package/dist/chunk-SXPA6SSD.mjs.map +1 -0
- package/dist/chunk-T5A4KAVS.mjs +512 -0
- package/dist/chunk-T5A4KAVS.mjs.map +1 -0
- package/dist/chunk-TDRKKUNT.mjs +357 -0
- package/dist/chunk-TDRKKUNT.mjs.map +1 -0
- package/dist/chunk-TJFNODPE.js +357 -0
- package/dist/chunk-TJFNODPE.js.map +1 -0
- package/dist/chunk-V2SSI3SL.mjs +427 -0
- package/dist/chunk-V2SSI3SL.mjs.map +1 -0
- package/dist/chunk-X42L6MTY.mjs +290 -0
- package/dist/chunk-X42L6MTY.mjs.map +1 -0
- package/dist/chunk-YSVMY77H.js +611 -0
- package/dist/chunk-YSVMY77H.js.map +1 -0
- package/dist/core-ANYRS6EF.mjs +73 -0
- package/dist/core-ANYRS6EF.mjs.map +1 -0
- package/dist/core-K5K34DCS.js +73 -0
- package/dist/core-K5K34DCS.js.map +1 -0
- package/dist/core-index.d.mts +1668 -0
- package/dist/core-index.d.ts +1668 -0
- package/dist/core-index.js +101 -0
- package/dist/core-index.js.map +1 -0
- package/dist/core-index.mjs +101 -0
- package/dist/core-index.mjs.map +1 -0
- package/dist/index.d.mts +2911 -0
- package/dist/index.d.ts +2911 -0
- package/dist/index.js +1177 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1177 -0
- package/dist/index.mjs.map +1 -0
- package/dist/tools-352X7A6X.mjs +366 -0
- package/dist/tools-352X7A6X.mjs.map +1 -0
- package/dist/tools-YLEX6GNO.js +366 -0
- package/dist/tools-YLEX6GNO.js.map +1 -0
- package/dist/ui-index.d.mts +627 -0
- package/dist/ui-index.d.ts +627 -0
- package/dist/ui-index.js +2354 -0
- package/dist/ui-index.js.map +1 -0
- package/dist/ui-index.mjs +2353 -0
- package/dist/ui-index.mjs.map +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
// src/core/ai-embeddings.ts
|
|
2
|
+
import { EventEmitter } from "events";
|
|
3
|
+
import {
|
|
4
|
+
embed,
|
|
5
|
+
embedMany,
|
|
6
|
+
cosineSimilarity
|
|
7
|
+
} from "ai";
|
|
8
|
+
var SupportedEmbeddingModels = {
|
|
9
|
+
// Qwen
|
|
10
|
+
"qwen:text-embedding-v3": {
|
|
11
|
+
provider: "qwen",
|
|
12
|
+
model: "text-embedding-v3",
|
|
13
|
+
dimensions: 1024,
|
|
14
|
+
description: "Qwen latest embedding model with 1024 dimensions"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var AIEmbeddingsIntegration = class extends EventEmitter {
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this.initialized = false;
|
|
21
|
+
this.requestCounter = 0;
|
|
22
|
+
this.embeddingCache = /* @__PURE__ */ new Map();
|
|
23
|
+
this.usageStats = /* @__PURE__ */ new Map();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 初始化
|
|
27
|
+
*/
|
|
28
|
+
async initialize() {
|
|
29
|
+
if (this.initialized) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
this.emit("ai_embeddings:initializing");
|
|
34
|
+
this.initialized = true;
|
|
35
|
+
this.emit("ai_embeddings:initialized");
|
|
36
|
+
} catch (error) {
|
|
37
|
+
this.emit("ai_embeddings:initialization_failed", { error });
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 生成请求ID
|
|
43
|
+
*/
|
|
44
|
+
generateRequestId() {
|
|
45
|
+
return `ai-embeddings-${Date.now()}-${++this.requestCounter}`;
|
|
46
|
+
}
|
|
47
|
+
// Single value embedding methods
|
|
48
|
+
/**
|
|
49
|
+
* Embed single value - embed() API
|
|
50
|
+
*/
|
|
51
|
+
async embed(options) {
|
|
52
|
+
return this.embedSingleValue(options);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Embed single value - complete embed() implementation
|
|
56
|
+
*/
|
|
57
|
+
async embedSingleValue(options) {
|
|
58
|
+
if (!this.initialized) {
|
|
59
|
+
throw new Error("AIEmbeddingsIntegration not initialized. Call initialize() first.");
|
|
60
|
+
}
|
|
61
|
+
const requestId = this.generateRequestId();
|
|
62
|
+
const startTime = Date.now();
|
|
63
|
+
try {
|
|
64
|
+
this.emit("ai_embeddings:embed_started", {
|
|
65
|
+
requestId,
|
|
66
|
+
model: typeof options.model === "string" ? options.model : "unknown",
|
|
67
|
+
valueLength: options.value.length,
|
|
68
|
+
hasProviderOptions: !!options.providerOptions,
|
|
69
|
+
maxRetries: options.maxRetries || 2
|
|
70
|
+
});
|
|
71
|
+
const cacheKey = this.generateCacheKey(options.model, options.value, options.providerOptions);
|
|
72
|
+
if (this.embeddingCache.has(cacheKey)) {
|
|
73
|
+
const cached = this.embeddingCache.get(cacheKey);
|
|
74
|
+
this.emit("ai_embeddings:embed_cache_hit", { requestId, cacheKey });
|
|
75
|
+
return cached;
|
|
76
|
+
}
|
|
77
|
+
const result = await embed({
|
|
78
|
+
model: options.model,
|
|
79
|
+
value: options.value,
|
|
80
|
+
providerOptions: options.providerOptions,
|
|
81
|
+
maxRetries: options.maxRetries,
|
|
82
|
+
abortSignal: options.abortSignal,
|
|
83
|
+
headers: options.headers
|
|
84
|
+
});
|
|
85
|
+
this.embeddingCache.set(cacheKey, result);
|
|
86
|
+
this.recordUsage(options.model, 1, result.usage.tokens || 0);
|
|
87
|
+
this.emit("ai_embeddings:embed_completed", {
|
|
88
|
+
requestId,
|
|
89
|
+
latency: Date.now() - startTime,
|
|
90
|
+
embeddingDimensions: result.embedding.length,
|
|
91
|
+
usage: result.usage,
|
|
92
|
+
cached: false
|
|
93
|
+
});
|
|
94
|
+
return result;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
this.emit("ai_embeddings:embed_failed", {
|
|
97
|
+
requestId,
|
|
98
|
+
error: error.message,
|
|
99
|
+
latency: Date.now() - startTime,
|
|
100
|
+
errorType: error.constructor.name
|
|
101
|
+
});
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Batch embedding methods
|
|
106
|
+
/**
|
|
107
|
+
* Embed multiple values - embedMany() API
|
|
108
|
+
*/
|
|
109
|
+
async embedMany(options) {
|
|
110
|
+
return this.embedManyValues(options);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Embed multiple values - complete embedMany() implementation
|
|
114
|
+
*/
|
|
115
|
+
async embedManyValues(options) {
|
|
116
|
+
if (!this.initialized) {
|
|
117
|
+
throw new Error("AIEmbeddingsIntegration not initialized. Call initialize() first.");
|
|
118
|
+
}
|
|
119
|
+
const requestId = this.generateRequestId();
|
|
120
|
+
const startTime = Date.now();
|
|
121
|
+
try {
|
|
122
|
+
this.emit("ai_embeddings:embed_many_started", {
|
|
123
|
+
requestId,
|
|
124
|
+
model: typeof options.model === "string" ? options.model : "unknown",
|
|
125
|
+
valuesCount: options.values.length,
|
|
126
|
+
maxParallelCalls: options.maxParallelCalls,
|
|
127
|
+
hasProviderOptions: !!options.providerOptions,
|
|
128
|
+
maxRetries: options.maxRetries || 2
|
|
129
|
+
});
|
|
130
|
+
const result = await embedMany({
|
|
131
|
+
model: options.model,
|
|
132
|
+
values: options.values,
|
|
133
|
+
maxParallelCalls: options.maxParallelCalls,
|
|
134
|
+
providerOptions: options.providerOptions,
|
|
135
|
+
maxRetries: options.maxRetries,
|
|
136
|
+
abortSignal: options.abortSignal,
|
|
137
|
+
headers: options.headers
|
|
138
|
+
});
|
|
139
|
+
this.recordUsage(options.model, options.values.length, result.usage.tokens || 0);
|
|
140
|
+
this.emit("ai_embeddings:embed_many_completed", {
|
|
141
|
+
requestId,
|
|
142
|
+
latency: Date.now() - startTime,
|
|
143
|
+
valuesCount: options.values.length,
|
|
144
|
+
embeddingsCount: result.embeddings.length,
|
|
145
|
+
embeddingDimensions: result.embeddings[0]?.length || 0,
|
|
146
|
+
usage: result.usage
|
|
147
|
+
});
|
|
148
|
+
return result;
|
|
149
|
+
} catch (error) {
|
|
150
|
+
this.emit("ai_embeddings:embed_many_failed", {
|
|
151
|
+
requestId,
|
|
152
|
+
error: error.message,
|
|
153
|
+
latency: Date.now() - startTime,
|
|
154
|
+
errorType: error.constructor.name,
|
|
155
|
+
valuesCount: options.values.length
|
|
156
|
+
});
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Similarity calculation methods
|
|
161
|
+
/**
|
|
162
|
+
* Cosine similarity calculation - cosineSimilarity() implementation
|
|
163
|
+
*/
|
|
164
|
+
calculateCosineSimilarity(vector1, vector2) {
|
|
165
|
+
if (vector1.length !== vector2.length) {
|
|
166
|
+
throw new Error("Vectors must have the same dimensions");
|
|
167
|
+
}
|
|
168
|
+
const similarity = cosineSimilarity(vector1, vector2);
|
|
169
|
+
this.emit("ai_embeddings:similarity_calculated", {
|
|
170
|
+
method: "cosine",
|
|
171
|
+
similarity,
|
|
172
|
+
vector1Dimensions: vector1.length,
|
|
173
|
+
vector2Dimensions: vector2.length
|
|
174
|
+
});
|
|
175
|
+
return similarity;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* 批量相似度计算
|
|
179
|
+
*/
|
|
180
|
+
calculateSimilarities(targetVector, vectors, method = "cosine") {
|
|
181
|
+
return vectors.map((vector) => ({
|
|
182
|
+
similarity: method === "cosine" ? this.calculateCosineSimilarity(targetVector, vector) : method === "euclidean" ? this.calculateEuclideanSimilarity(targetVector, vector) : this.calculateDotProduct(targetVector, vector),
|
|
183
|
+
vector1: targetVector,
|
|
184
|
+
vector2: vector,
|
|
185
|
+
method
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 欧几里得距离相似度
|
|
190
|
+
*/
|
|
191
|
+
calculateEuclideanSimilarity(vector1, vector2) {
|
|
192
|
+
if (vector1.length !== vector2.length) {
|
|
193
|
+
throw new Error("Vectors must have the same dimensions");
|
|
194
|
+
}
|
|
195
|
+
const sumSquared = vector1.reduce((sum, val, i) => {
|
|
196
|
+
const diff = val - vector2[i];
|
|
197
|
+
return sum + diff * diff;
|
|
198
|
+
}, 0);
|
|
199
|
+
return 1 / (1 + Math.sqrt(sumSquared));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* 点积相似度
|
|
203
|
+
*/
|
|
204
|
+
calculateDotProduct(vector1, vector2) {
|
|
205
|
+
if (vector1.length !== vector2.length) {
|
|
206
|
+
throw new Error("Vectors must have the same dimensions");
|
|
207
|
+
}
|
|
208
|
+
return vector1.reduce((sum, val, i) => sum + val * vector2[i], 0);
|
|
209
|
+
}
|
|
210
|
+
// Similarity search and ranking
|
|
211
|
+
/**
|
|
212
|
+
* Find most similar embeddings
|
|
213
|
+
*/
|
|
214
|
+
findMostSimilar(queryVector, candidateVectors, topK = 5, method = "cosine") {
|
|
215
|
+
const similarities = this.calculateSimilarities(queryVector, candidateVectors, method);
|
|
216
|
+
return similarities.map((result, index) => ({
|
|
217
|
+
index,
|
|
218
|
+
similarity: result.similarity,
|
|
219
|
+
vector: result.vector2
|
|
220
|
+
})).sort((a, b) => b.similarity - a.similarity).slice(0, topK);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* 文本相似性搜索
|
|
224
|
+
*/
|
|
225
|
+
async searchSimilarTexts(queryText, candidateTexts, model, topK = 5, options) {
|
|
226
|
+
const queryResult = await this.embedSingleValue({
|
|
227
|
+
model,
|
|
228
|
+
value: queryText,
|
|
229
|
+
...options
|
|
230
|
+
});
|
|
231
|
+
const candidatesResult = await this.embedManyValues({
|
|
232
|
+
model,
|
|
233
|
+
values: candidateTexts,
|
|
234
|
+
...options
|
|
235
|
+
});
|
|
236
|
+
const similarities = this.findMostSimilar(
|
|
237
|
+
queryResult.embedding,
|
|
238
|
+
candidatesResult.embeddings,
|
|
239
|
+
topK
|
|
240
|
+
);
|
|
241
|
+
return similarities.map((result) => ({
|
|
242
|
+
index: result.index,
|
|
243
|
+
text: candidateTexts[result.index],
|
|
244
|
+
similarity: result.similarity
|
|
245
|
+
}));
|
|
246
|
+
}
|
|
247
|
+
// Utility methods and cache management
|
|
248
|
+
/**
|
|
249
|
+
* Generate cache key
|
|
250
|
+
*/
|
|
251
|
+
generateCacheKey(model, value, providerOptions) {
|
|
252
|
+
const modelKey = typeof model === "string" ? model : "unknown";
|
|
253
|
+
const optionsKey = providerOptions ? JSON.stringify(providerOptions) : "";
|
|
254
|
+
return `${modelKey}:${value}:${optionsKey}`;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Record usage statistics
|
|
258
|
+
*/
|
|
259
|
+
recordUsage(model, embeddingCount, tokens) {
|
|
260
|
+
const modelKey = typeof model === "string" ? model : "unknown";
|
|
261
|
+
const existing = this.usageStats.get(modelKey);
|
|
262
|
+
if (existing) {
|
|
263
|
+
existing.totalEmbeddings += embeddingCount;
|
|
264
|
+
existing.totalTokens += tokens;
|
|
265
|
+
existing.lastUsed = /* @__PURE__ */ new Date();
|
|
266
|
+
} else {
|
|
267
|
+
this.usageStats.set(modelKey, {
|
|
268
|
+
totalEmbeddings: embeddingCount,
|
|
269
|
+
totalTokens: tokens,
|
|
270
|
+
lastUsed: /* @__PURE__ */ new Date()
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* 获取支持的模型信息
|
|
276
|
+
*/
|
|
277
|
+
getSupportedModels() {
|
|
278
|
+
return Object.values(SupportedEmbeddingModels);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* 根据提供商筛选模型
|
|
282
|
+
*/
|
|
283
|
+
getModelsByProvider(provider) {
|
|
284
|
+
return Object.values(SupportedEmbeddingModels).filter((model) => model.provider === provider);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* 获取使用统计
|
|
288
|
+
*/
|
|
289
|
+
getUsageStats() {
|
|
290
|
+
const stats = {};
|
|
291
|
+
this.usageStats.forEach((stat, model) => {
|
|
292
|
+
stats[model] = { ...stat };
|
|
293
|
+
});
|
|
294
|
+
return stats;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* 清理缓存
|
|
298
|
+
*/
|
|
299
|
+
clearCache() {
|
|
300
|
+
this.embeddingCache.clear();
|
|
301
|
+
this.emit("ai_embeddings:cache_cleared");
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* 获取缓存统计
|
|
305
|
+
*/
|
|
306
|
+
getCacheStats() {
|
|
307
|
+
return {
|
|
308
|
+
size: this.embeddingCache.size,
|
|
309
|
+
keys: Array.from(this.embeddingCache.keys())
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* 检查初始化状态
|
|
314
|
+
*/
|
|
315
|
+
isInitialized() {
|
|
316
|
+
return this.initialized;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* 获取统计信息
|
|
320
|
+
*/
|
|
321
|
+
getStats() {
|
|
322
|
+
const totalUsage = Array.from(this.usageStats.values()).reduce(
|
|
323
|
+
(sum, stat) => ({
|
|
324
|
+
embeddings: sum.embeddings + stat.totalEmbeddings,
|
|
325
|
+
tokens: sum.tokens + stat.totalTokens
|
|
326
|
+
}),
|
|
327
|
+
{ embeddings: 0, tokens: 0 }
|
|
328
|
+
);
|
|
329
|
+
return {
|
|
330
|
+
isInitialized: this.initialized,
|
|
331
|
+
requestCount: this.requestCounter,
|
|
332
|
+
cacheSize: this.embeddingCache.size,
|
|
333
|
+
totalUsage
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* 销毁实例
|
|
338
|
+
*/
|
|
339
|
+
destroy() {
|
|
340
|
+
this.embeddingCache.clear();
|
|
341
|
+
this.usageStats.clear();
|
|
342
|
+
this.removeAllListeners();
|
|
343
|
+
this.initialized = false;
|
|
344
|
+
this.requestCounter = 0;
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
var ai_embeddings_default = AIEmbeddingsIntegration;
|
|
348
|
+
|
|
349
|
+
export {
|
|
350
|
+
embed,
|
|
351
|
+
embedMany,
|
|
352
|
+
cosineSimilarity,
|
|
353
|
+
SupportedEmbeddingModels,
|
|
354
|
+
AIEmbeddingsIntegration,
|
|
355
|
+
ai_embeddings_default
|
|
356
|
+
};
|
|
357
|
+
//# sourceMappingURL=chunk-TDRKKUNT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/ai-embeddings.ts"],"sourcesContent":["/**\n * AI Embeddings Complete Integration\n * \n * Complete embeddings functionality:\n * - embed: Single value embedding\n * - embedMany: Batch embedding \n * - cosineSimilarity: Similarity calculation\n * - All configuration parameters supported\n * - Provider-specific configurations\n */\n\nimport { EventEmitter } from 'events';\nimport {\n embed,\n embedMany,\n cosineSimilarity,\n type EmbeddingModel,\n type LanguageModelUsage,\n type LanguageModelRequestMetadata,\n type LanguageModelResponseMetadata\n} from 'ai';\n\n// Type Definitions\n\n/**\n * Complete embedding model configuration\n */\nexport interface EmbeddingModelConfig {\n // 基础模型\n model: EmbeddingModel;\n \n // 提供商特定选项 - 官方文档支持\n providerOptions?: Record<string, any>; // 如 { openai: { dimensions: 512 } }\n \n // 控制参数\n maxRetries?: number; // 最大重试次数,默认 2\n abortSignal?: AbortSignal; // 取消信号\n headers?: Record<string, string>; // 自定义 HTTP 头\n}\n\n/**\n * 批量嵌入配置 - embedMany 专用参数\n */\nexport interface EmbedManyConfig extends EmbeddingModelConfig {\n maxParallelCalls?: number; // 并行请求数 - 官方文档功能\n}\n\n/**\n * 单值嵌入选项 - embed() 完整参数\n */\nexport interface EmbedOptions extends EmbeddingModelConfig {\n value: string; // 要嵌入的文本\n}\n\n/**\n * 批量嵌入选项 - embedMany() 完整参数 \n */\nexport interface EmbedManyOptions extends EmbedManyConfig {\n values: string[]; // 要嵌入的文本数组\n}\n\n/**\n * 嵌入结果类型 - 官方规范\n */\nexport interface EmbedResult {\n embedding: number[]; // 嵌入向量\n usage: LanguageModelUsage; // 令牌使用情况\n request?: LanguageModelRequestMetadata; // 请求元数据\n response?: LanguageModelResponseMetadata; // 响应元数据\n}\n\n/**\n * 批量嵌入结果类型 - 官方规范\n */\nexport interface EmbedManyResult {\n embeddings: number[][]; // 嵌入向量数组,与输入顺序一致\n usage: LanguageModelUsage; // 令牌使用情况\n request?: LanguageModelRequestMetadata; // 请求元数据\n response?: LanguageModelResponseMetadata; // 响应元数据\n}\n\n/**\n * 相似度计算结果\n */\nexport interface SimilarityResult {\n similarity: number;\n vector1: number[];\n vector2: number[];\n method: 'cosine' | 'euclidean' | 'dot';\n}\n\n/**\n * 嵌入提供商信息 - 基于官方文档表格\n */\nexport interface EmbeddingProviderInfo {\n provider: string;\n model: string;\n dimensions: number;\n description?: string;\n}\n\n// Predefined provider model configurations\n\n/**\n * Supported embedding models\n */\nexport const SupportedEmbeddingModels: Record<string, EmbeddingProviderInfo> = {\n // Qwen\n 'qwen:text-embedding-v3': {\n provider: 'qwen',\n model: 'text-embedding-v3',\n dimensions: 1024,\n description: 'Qwen latest embedding model with 1024 dimensions'\n }\n};\n\n// Core Embeddings Integration Class\n\n/**\n * Complete embeddings integration class\n */\nexport class AIEmbeddingsIntegration extends EventEmitter {\n private initialized: boolean = false;\n private requestCounter: number = 0;\n private embeddingCache: Map<string, EmbedResult> = new Map();\n private usageStats: Map<string, { totalEmbeddings: number; totalTokens: number; lastUsed: Date }> = new Map();\n\n constructor() {\n super();\n }\n\n /**\n * 初始化\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n try {\n this.emit('ai_embeddings:initializing');\n this.initialized = true;\n this.emit('ai_embeddings:initialized');\n } catch (error) {\n this.emit('ai_embeddings:initialization_failed', { error });\n throw error;\n }\n }\n\n /**\n * 生成请求ID\n */\n private generateRequestId(): string {\n return `ai-embeddings-${Date.now()}-${++this.requestCounter}`;\n }\n\n // Single value embedding methods\n\n /**\n * Embed single value - embed() API\n */\n async embed(options: EmbedOptions): Promise<EmbedResult> {\n return this.embedSingleValue(options);\n }\n\n /**\n * Embed single value - complete embed() implementation\n */\n async embedSingleValue(options: EmbedOptions): Promise<EmbedResult> {\n if (!this.initialized) {\n throw new Error('AIEmbeddingsIntegration not initialized. Call initialize() first.');\n }\n\n const requestId = this.generateRequestId();\n const startTime = Date.now();\n\n try {\n this.emit('ai_embeddings:embed_started', {\n requestId,\n model: typeof options.model === 'string' ? options.model : 'unknown',\n valueLength: options.value.length,\n hasProviderOptions: !!options.providerOptions,\n maxRetries: options.maxRetries || 2\n });\n\n // 检查缓存\n const cacheKey = this.generateCacheKey(options.model, options.value, options.providerOptions);\n if (this.embeddingCache.has(cacheKey)) {\n const cached = this.embeddingCache.get(cacheKey)!;\n this.emit('ai_embeddings:embed_cache_hit', { requestId, cacheKey });\n return cached;\n }\n\n // 调用官方 embed 函数\n const result = await embed({\n model: options.model,\n value: options.value,\n providerOptions: options.providerOptions,\n maxRetries: options.maxRetries,\n abortSignal: options.abortSignal,\n headers: options.headers\n });\n\n // 缓存结果 \n this.embeddingCache.set(cacheKey, result as any);\n\n // 记录统计\n this.recordUsage(options.model, 1, result.usage.tokens || 0);\n\n this.emit('ai_embeddings:embed_completed', {\n requestId,\n latency: Date.now() - startTime,\n embeddingDimensions: result.embedding.length,\n usage: result.usage,\n cached: false\n });\n\n return result as any;\n\n } catch (error: any) {\n this.emit('ai_embeddings:embed_failed', {\n requestId,\n error: error.message,\n latency: Date.now() - startTime,\n errorType: error.constructor.name\n });\n\n throw error;\n }\n }\n\n // Batch embedding methods\n\n /**\n * Embed multiple values - embedMany() API\n */\n async embedMany(options: EmbedManyOptions): Promise<EmbedManyResult> {\n return this.embedManyValues(options);\n }\n\n /**\n * Embed multiple values - complete embedMany() implementation \n */\n async embedManyValues(options: EmbedManyOptions): Promise<EmbedManyResult> {\n if (!this.initialized) {\n throw new Error('AIEmbeddingsIntegration not initialized. Call initialize() first.');\n }\n\n const requestId = this.generateRequestId();\n const startTime = Date.now();\n\n try {\n this.emit('ai_embeddings:embed_many_started', {\n requestId,\n model: typeof options.model === 'string' ? options.model : 'unknown',\n valuesCount: options.values.length,\n maxParallelCalls: options.maxParallelCalls,\n hasProviderOptions: !!options.providerOptions,\n maxRetries: options.maxRetries || 2\n });\n\n // 调用官方 embedMany 函数\n const result = await embedMany({\n model: options.model,\n values: options.values,\n maxParallelCalls: options.maxParallelCalls,\n providerOptions: options.providerOptions,\n maxRetries: options.maxRetries,\n abortSignal: options.abortSignal,\n headers: options.headers\n });\n\n // 记录统计\n this.recordUsage(options.model, options.values.length, result.usage.tokens || 0);\n\n this.emit('ai_embeddings:embed_many_completed', {\n requestId,\n latency: Date.now() - startTime,\n valuesCount: options.values.length,\n embeddingsCount: result.embeddings.length,\n embeddingDimensions: result.embeddings[0]?.length || 0,\n usage: result.usage\n });\n\n return result as any;\n\n } catch (error: any) {\n this.emit('ai_embeddings:embed_many_failed', {\n requestId,\n error: error.message,\n latency: Date.now() - startTime,\n errorType: error.constructor.name,\n valuesCount: options.values.length\n });\n\n throw error;\n }\n }\n\n // Similarity calculation methods\n\n /**\n * Cosine similarity calculation - cosineSimilarity() implementation\n */\n calculateCosineSimilarity(vector1: number[], vector2: number[]): number {\n if (vector1.length !== vector2.length) {\n throw new Error('Vectors must have the same dimensions');\n }\n\n const similarity = cosineSimilarity(vector1, vector2);\n \n this.emit('ai_embeddings:similarity_calculated', {\n method: 'cosine',\n similarity,\n vector1Dimensions: vector1.length,\n vector2Dimensions: vector2.length\n });\n\n return similarity;\n }\n\n /**\n * 批量相似度计算\n */\n calculateSimilarities(\n targetVector: number[],\n vectors: number[][],\n method: 'cosine' | 'euclidean' | 'dot' = 'cosine'\n ): SimilarityResult[] {\n return vectors.map(vector => ({\n similarity: method === 'cosine' \n ? this.calculateCosineSimilarity(targetVector, vector)\n : method === 'euclidean'\n ? this.calculateEuclideanSimilarity(targetVector, vector) \n : this.calculateDotProduct(targetVector, vector),\n vector1: targetVector,\n vector2: vector,\n method\n }));\n }\n\n /**\n * 欧几里得距离相似度\n */\n private calculateEuclideanSimilarity(vector1: number[], vector2: number[]): number {\n if (vector1.length !== vector2.length) {\n throw new Error('Vectors must have the same dimensions');\n }\n\n const sumSquared = vector1.reduce((sum, val, i) => {\n const diff = val - vector2[i];\n return sum + diff * diff;\n }, 0);\n\n // 转换为相似度(距离越小,相似度越高)\n return 1 / (1 + Math.sqrt(sumSquared));\n }\n\n /**\n * 点积相似度\n */\n private calculateDotProduct(vector1: number[], vector2: number[]): number {\n if (vector1.length !== vector2.length) {\n throw new Error('Vectors must have the same dimensions');\n }\n\n return vector1.reduce((sum, val, i) => sum + val * vector2[i], 0);\n }\n\n // Similarity search and ranking\n\n /**\n * Find most similar embeddings\n */\n findMostSimilar(\n queryVector: number[],\n candidateVectors: number[][],\n topK: number = 5,\n method: 'cosine' | 'euclidean' | 'dot' = 'cosine'\n ): Array<{ index: number; similarity: number; vector: number[] }> {\n const similarities = this.calculateSimilarities(queryVector, candidateVectors, method);\n \n return similarities\n .map((result, index) => ({\n index,\n similarity: result.similarity,\n vector: result.vector2\n }))\n .sort((a, b) => b.similarity - a.similarity) // 按相似度降序排列\n .slice(0, topK);\n }\n\n /**\n * 文本相似性搜索\n */\n async searchSimilarTexts(\n queryText: string,\n candidateTexts: string[],\n model: EmbeddingModel,\n topK: number = 5,\n options?: Partial<EmbeddingModelConfig>\n ): Promise<Array<{ index: number; text: string; similarity: number }>> {\n // 嵌入查询文本和候选文本\n const queryResult = await this.embedSingleValue({\n model,\n value: queryText,\n ...options\n });\n\n const candidatesResult = await this.embedManyValues({\n model,\n values: candidateTexts,\n ...options\n });\n\n // 计算相似度\n const similarities = this.findMostSimilar(\n queryResult.embedding,\n candidatesResult.embeddings,\n topK\n );\n\n return similarities.map(result => ({\n index: result.index,\n text: candidateTexts[result.index],\n similarity: result.similarity\n }));\n }\n\n // Utility methods and cache management\n\n /**\n * Generate cache key\n */\n private generateCacheKey(model: EmbeddingModel, value: string, providerOptions?: any): string {\n const modelKey = typeof model === 'string' ? model : 'unknown';\n const optionsKey = providerOptions ? JSON.stringify(providerOptions) : '';\n return `${modelKey}:${value}:${optionsKey}`;\n }\n\n /**\n * Record usage statistics\n */\n private recordUsage(model: EmbeddingModel, embeddingCount: number, tokens: number): void {\n const modelKey = typeof model === 'string' ? model : 'unknown';\n \n const existing = this.usageStats.get(modelKey);\n if (existing) {\n existing.totalEmbeddings += embeddingCount;\n existing.totalTokens += tokens;\n existing.lastUsed = new Date();\n } else {\n this.usageStats.set(modelKey, {\n totalEmbeddings: embeddingCount,\n totalTokens: tokens,\n lastUsed: new Date()\n });\n }\n }\n\n /**\n * 获取支持的模型信息\n */\n getSupportedModels(): EmbeddingProviderInfo[] {\n return Object.values(SupportedEmbeddingModels);\n }\n\n /**\n * 根据提供商筛选模型\n */\n getModelsByProvider(provider: string): EmbeddingProviderInfo[] {\n return Object.values(SupportedEmbeddingModels)\n .filter(model => model.provider === provider);\n }\n\n /**\n * 获取使用统计\n */\n getUsageStats(): Record<string, { totalEmbeddings: number; totalTokens: number; lastUsed: Date }> {\n const stats: Record<string, { totalEmbeddings: number; totalTokens: number; lastUsed: Date }> = {};\n this.usageStats.forEach((stat, model) => {\n stats[model] = { ...stat };\n });\n return stats;\n }\n\n /**\n * 清理缓存\n */\n clearCache(): void {\n this.embeddingCache.clear();\n this.emit('ai_embeddings:cache_cleared');\n }\n\n /**\n * 获取缓存统计\n */\n getCacheStats(): { size: number; keys: string[] } {\n return {\n size: this.embeddingCache.size,\n keys: Array.from(this.embeddingCache.keys())\n };\n }\n\n /**\n * 检查初始化状态\n */\n isInitialized(): boolean {\n return this.initialized;\n }\n\n /**\n * 获取统计信息\n */\n getStats(): {\n isInitialized: boolean;\n requestCount: number;\n cacheSize: number;\n totalUsage: { embeddings: number; tokens: number };\n } {\n const totalUsage = Array.from(this.usageStats.values()).reduce(\n (sum, stat) => ({\n embeddings: sum.embeddings + stat.totalEmbeddings,\n tokens: sum.tokens + stat.totalTokens\n }),\n { embeddings: 0, tokens: 0 }\n );\n\n return {\n isInitialized: this.initialized,\n requestCount: this.requestCounter,\n cacheSize: this.embeddingCache.size,\n totalUsage\n };\n }\n\n /**\n * 销毁实例\n */\n destroy(): void {\n this.embeddingCache.clear();\n this.usageStats.clear();\n this.removeAllListeners();\n this.initialized = false;\n this.requestCounter = 0;\n }\n}\n\n// Exports\n\nexport {\n // Core functions\n embed,\n embedMany,\n cosineSimilarity,\n // Core types\n type EmbeddingModel,\n \n type LanguageModelUsage,\n type LanguageModelRequestMetadata,\n type LanguageModelResponseMetadata\n};\n\n// Default export\nexport default AIEmbeddingsIntegration;"],"mappings":"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","names":[]}
|