@axiom-lattice/core 2.1.32 → 2.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +575 -123
- package/dist/index.d.ts +575 -123
- package/dist/index.js +1527 -410
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1525 -409
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -74,6 +74,7 @@ __export(index_exports, {
|
|
|
74
74
|
QueueLatticeManager: () => QueueLatticeManager,
|
|
75
75
|
SandboxFilesystem: () => SandboxFilesystem,
|
|
76
76
|
SandboxLatticeManager: () => SandboxLatticeManager,
|
|
77
|
+
SandboxSkillStore: () => SandboxSkillStore,
|
|
77
78
|
ScheduleLatticeManager: () => ScheduleLatticeManager,
|
|
78
79
|
SemanticMetricsClient: () => SemanticMetricsClient,
|
|
79
80
|
SkillLatticeManager: () => SkillLatticeManager,
|
|
@@ -121,7 +122,6 @@ __export(index_exports, {
|
|
|
121
122
|
formatReadResponse: () => formatReadResponse,
|
|
122
123
|
getAgentClient: () => getAgentClient,
|
|
123
124
|
getAgentConfig: () => getAgentConfig,
|
|
124
|
-
getAgentLattice: () => getAgentLattice,
|
|
125
125
|
getAllAgentConfigs: () => getAllAgentConfigs,
|
|
126
126
|
getAllToolDefinitions: () => getAllToolDefinitions,
|
|
127
127
|
getCheckpointSaver: () => getCheckpointSaver,
|
|
@@ -158,6 +158,7 @@ __export(index_exports, {
|
|
|
158
158
|
performStringReplacement: () => performStringReplacement,
|
|
159
159
|
queueLatticeManager: () => queueLatticeManager,
|
|
160
160
|
registerAgentLattice: () => registerAgentLattice,
|
|
161
|
+
registerAgentLatticeWithTenant: () => registerAgentLatticeWithTenant,
|
|
161
162
|
registerAgentLattices: () => registerAgentLattices,
|
|
162
163
|
registerCheckpointSaver: () => registerCheckpointSaver,
|
|
163
164
|
registerChunkBuffer: () => registerChunkBuffer,
|
|
@@ -204,37 +205,148 @@ var _BaseLatticeManager = class _BaseLatticeManager {
|
|
|
204
205
|
throw new Error("\u5FC5\u987B\u7531\u5B50\u7C7B\u5B9E\u73B0");
|
|
205
206
|
}
|
|
206
207
|
/**
|
|
207
|
-
*
|
|
208
|
+
* 构造完整的键名,包含类型前缀和租户ID
|
|
209
|
+
* @param tenantId 租户ID,全局共享使用 "default"
|
|
208
210
|
* @param key 原始键名
|
|
209
211
|
*/
|
|
210
|
-
getFullKey(key) {
|
|
211
|
-
return `${this.getLatticeType()}
|
|
212
|
+
getFullKey(tenantId, key) {
|
|
213
|
+
return `${this.getLatticeType()}:${tenantId}:${key}`;
|
|
212
214
|
}
|
|
215
|
+
// ========== 带租户的新API ==========
|
|
213
216
|
/**
|
|
214
|
-
*
|
|
217
|
+
* 带租户的注册项目
|
|
218
|
+
* @param tenantId 租户ID
|
|
215
219
|
* @param key 项目键名(不含前缀)
|
|
216
220
|
* @param item 项目实例
|
|
217
221
|
*/
|
|
218
|
-
|
|
219
|
-
const fullKey = this.getFullKey(key);
|
|
222
|
+
registerWithTenant(tenantId, key, item) {
|
|
223
|
+
const fullKey = this.getFullKey(tenantId, key);
|
|
220
224
|
if (_BaseLatticeManager.registry.has(fullKey)) {
|
|
221
225
|
throw new Error(`\u9879\u76EE "${fullKey}" \u5DF2\u7ECF\u5B58\u5728\uFF0C\u65E0\u6CD5\u91CD\u590D\u6CE8\u518C`);
|
|
222
226
|
}
|
|
223
227
|
_BaseLatticeManager.registry.set(fullKey, item);
|
|
224
228
|
}
|
|
225
229
|
/**
|
|
226
|
-
*
|
|
230
|
+
* 带租户的获取指定项目(同步)
|
|
231
|
+
* @param tenantId 租户ID
|
|
227
232
|
* @param key 项目键名(不含前缀)
|
|
228
233
|
*/
|
|
229
|
-
|
|
230
|
-
const fullKey = this.getFullKey(key);
|
|
234
|
+
getWithTenant(tenantId, key) {
|
|
235
|
+
const fullKey = this.getFullKey(tenantId, key);
|
|
231
236
|
return _BaseLatticeManager.registry.get(fullKey);
|
|
232
237
|
}
|
|
233
238
|
/**
|
|
234
|
-
*
|
|
239
|
+
* 带租户的获取指定项目(异步,支持从store回退加载)
|
|
240
|
+
* 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
|
|
241
|
+
* @param tenantId 租户ID
|
|
242
|
+
* @param key 项目键名(不含前缀)
|
|
243
|
+
* @returns 项目实例,如果未找到则返回undefined
|
|
244
|
+
*/
|
|
245
|
+
async getOrLoadWithTenant(tenantId, key) {
|
|
246
|
+
const item = this.getWithTenant(tenantId, key);
|
|
247
|
+
if (item !== void 0) {
|
|
248
|
+
return item;
|
|
249
|
+
}
|
|
250
|
+
if (this.loadItemFromStore) {
|
|
251
|
+
const loadedItem = await this.loadItemFromStore(tenantId, key);
|
|
252
|
+
if (loadedItem !== void 0) {
|
|
253
|
+
this.registerWithTenant(tenantId, key, loadedItem);
|
|
254
|
+
return loadedItem;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return void 0;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* 带租户的检查项目是否存在(同步)
|
|
261
|
+
* @param tenantId 租户ID
|
|
262
|
+
* @param key 项目键名(不含前缀)
|
|
263
|
+
*/
|
|
264
|
+
hasWithTenant(tenantId, key) {
|
|
265
|
+
const fullKey = this.getFullKey(tenantId, key);
|
|
266
|
+
return _BaseLatticeManager.registry.has(fullKey);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* 带租户的检查项目是否存在(异步,支持从store回退加载)
|
|
270
|
+
* 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
|
|
271
|
+
* @param tenantId 租户ID
|
|
272
|
+
* @param key 项目键名(不含前缀)
|
|
273
|
+
* @returns 如果存在或能从store加载则返回true
|
|
274
|
+
*/
|
|
275
|
+
async hasOrLoadWithTenant(tenantId, key) {
|
|
276
|
+
if (this.hasWithTenant(tenantId, key)) {
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
if (this.loadItemFromStore) {
|
|
280
|
+
const loadedItem = await this.loadItemFromStore(tenantId, key);
|
|
281
|
+
if (loadedItem !== void 0) {
|
|
282
|
+
this.registerWithTenant(tenantId, key, loadedItem);
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* 带租户的移除项目
|
|
290
|
+
* @param tenantId 租户ID
|
|
291
|
+
* @param key 项目键名(不含前缀)
|
|
292
|
+
*/
|
|
293
|
+
removeWithTenant(tenantId, key) {
|
|
294
|
+
const fullKey = this.getFullKey(tenantId, key);
|
|
295
|
+
return _BaseLatticeManager.registry.delete(fullKey);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* 获取指定租户的所有项目
|
|
299
|
+
* @param tenantId 租户ID
|
|
300
|
+
*/
|
|
301
|
+
getAllByTenant(tenantId) {
|
|
302
|
+
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
303
|
+
const result = [];
|
|
304
|
+
for (const [key, value] of _BaseLatticeManager.registry.entries()) {
|
|
305
|
+
if (key.startsWith(prefix)) {
|
|
306
|
+
result.push(value);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* 清空指定租户的所有项目
|
|
313
|
+
* @param tenantId 租户ID
|
|
314
|
+
*/
|
|
315
|
+
clearByTenant(tenantId) {
|
|
316
|
+
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
317
|
+
const keysToDelete = [];
|
|
318
|
+
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
319
|
+
if (key.startsWith(prefix)) {
|
|
320
|
+
keysToDelete.push(key);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
for (const key of keysToDelete) {
|
|
324
|
+
_BaseLatticeManager.registry.delete(key);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
// ========== 向后兼容的旧API(使用 default 租户) ==========
|
|
328
|
+
/**
|
|
329
|
+
* 注册项目(向后兼容,使用 "default" 租户)
|
|
330
|
+
* @deprecated Use registerWithTenant(tenantId, key, item) instead
|
|
331
|
+
* @param key 项目键名(不含前缀)
|
|
332
|
+
* @param item 项目实例
|
|
333
|
+
*/
|
|
334
|
+
register(key, item) {
|
|
335
|
+
this.registerWithTenant("default", key, item);
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* 获取指定项目(向后兼容,使用 "default" 租户)
|
|
339
|
+
* @deprecated Use getWithTenant(tenantId, key) instead
|
|
340
|
+
* @param key 项目键名(不含前缀)
|
|
341
|
+
*/
|
|
342
|
+
get(key) {
|
|
343
|
+
return this.getWithTenant("default", key);
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* 获取所有当前类型的项目(向后兼容,包含所有租户)
|
|
235
347
|
*/
|
|
236
348
|
getAll() {
|
|
237
|
-
const prefix = `${this.getLatticeType()}
|
|
349
|
+
const prefix = `${this.getLatticeType()}:`;
|
|
238
350
|
const result = [];
|
|
239
351
|
for (const [key, value] of _BaseLatticeManager.registry.entries()) {
|
|
240
352
|
if (key.startsWith(prefix)) {
|
|
@@ -244,26 +356,26 @@ var _BaseLatticeManager = class _BaseLatticeManager {
|
|
|
244
356
|
return result;
|
|
245
357
|
}
|
|
246
358
|
/**
|
|
247
|
-
*
|
|
359
|
+
* 检查项目是否存在(向后兼容,使用 "default" 租户)
|
|
360
|
+
* @deprecated Use hasWithTenant(tenantId, key) instead
|
|
248
361
|
* @param key 项目键名(不含前缀)
|
|
249
362
|
*/
|
|
250
363
|
has(key) {
|
|
251
|
-
|
|
252
|
-
return _BaseLatticeManager.registry.has(fullKey);
|
|
364
|
+
return this.hasWithTenant("default", key);
|
|
253
365
|
}
|
|
254
366
|
/**
|
|
255
|
-
*
|
|
367
|
+
* 移除项目(向后兼容,使用 "default" 租户)
|
|
368
|
+
* @deprecated Use removeWithTenant(tenantId, key) instead
|
|
256
369
|
* @param key 项目键名(不含前缀)
|
|
257
370
|
*/
|
|
258
371
|
remove(key) {
|
|
259
|
-
|
|
260
|
-
return _BaseLatticeManager.registry.delete(fullKey);
|
|
372
|
+
return this.removeWithTenant("default", key);
|
|
261
373
|
}
|
|
262
374
|
/**
|
|
263
|
-
*
|
|
375
|
+
* 清空当前类型的所有项目(向后兼容,包含所有租户)
|
|
264
376
|
*/
|
|
265
377
|
clear() {
|
|
266
|
-
const prefix = `${this.getLatticeType()}
|
|
378
|
+
const prefix = `${this.getLatticeType()}:`;
|
|
267
379
|
const keysToDelete = [];
|
|
268
380
|
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
269
381
|
if (key.startsWith(prefix)) {
|
|
@@ -275,10 +387,10 @@ var _BaseLatticeManager = class _BaseLatticeManager {
|
|
|
275
387
|
}
|
|
276
388
|
}
|
|
277
389
|
/**
|
|
278
|
-
*
|
|
390
|
+
* 获取当前类型的项目数量(向后兼容,包含所有租户)
|
|
279
391
|
*/
|
|
280
392
|
count() {
|
|
281
|
-
const prefix = `${this.getLatticeType()}
|
|
393
|
+
const prefix = `${this.getLatticeType()}:`;
|
|
282
394
|
let count = 0;
|
|
283
395
|
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
284
396
|
if (key.startsWith(prefix)) {
|
|
@@ -288,10 +400,26 @@ var _BaseLatticeManager = class _BaseLatticeManager {
|
|
|
288
400
|
return count;
|
|
289
401
|
}
|
|
290
402
|
/**
|
|
291
|
-
*
|
|
403
|
+
* 获取当前类型的项目键名列表(向后兼容,包含所有租户)
|
|
404
|
+
* 返回格式: {tenantId}:{key}
|
|
292
405
|
*/
|
|
293
406
|
keys() {
|
|
294
|
-
const prefix = `${this.getLatticeType()}
|
|
407
|
+
const prefix = `${this.getLatticeType()}:`;
|
|
408
|
+
const prefixLength = prefix.length;
|
|
409
|
+
const result = [];
|
|
410
|
+
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
411
|
+
if (key.startsWith(prefix)) {
|
|
412
|
+
result.push(key.substring(prefixLength));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* 获取当前类型的项目键名列表(仅指定租户,不含租户前缀)
|
|
419
|
+
* @param tenantId 租户ID
|
|
420
|
+
*/
|
|
421
|
+
keysByTenant(tenantId) {
|
|
422
|
+
const prefix = `${this.getLatticeType()}:${tenantId}:`;
|
|
295
423
|
const prefixLength = prefix.length;
|
|
296
424
|
const result = [];
|
|
297
425
|
for (const key of _BaseLatticeManager.registry.keys()) {
|
|
@@ -950,7 +1078,7 @@ var PostgresDatabase = class {
|
|
|
950
1078
|
var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
951
1079
|
constructor() {
|
|
952
1080
|
this.databases = /* @__PURE__ */ new Map();
|
|
953
|
-
this.
|
|
1081
|
+
this.defaultDatabaseKeys = /* @__PURE__ */ new Map();
|
|
954
1082
|
}
|
|
955
1083
|
/**
|
|
956
1084
|
* Get the singleton instance
|
|
@@ -962,11 +1090,23 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
962
1090
|
return _SqlDatabaseManager.instance;
|
|
963
1091
|
}
|
|
964
1092
|
/**
|
|
965
|
-
*
|
|
966
|
-
|
|
1093
|
+
* Get or create tenant database map
|
|
1094
|
+
*/
|
|
1095
|
+
getTenantDatabases(tenantId) {
|
|
1096
|
+
let tenantDbs = this.databases.get(tenantId);
|
|
1097
|
+
if (!tenantDbs) {
|
|
1098
|
+
tenantDbs = /* @__PURE__ */ new Map();
|
|
1099
|
+
this.databases.set(tenantId, tenantDbs);
|
|
1100
|
+
}
|
|
1101
|
+
return tenantDbs;
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Register a database connection for a tenant
|
|
1105
|
+
* @param tenantId - Tenant identifier
|
|
1106
|
+
* @param key - Unique identifier for the database within the tenant
|
|
967
1107
|
* @param config - Database configuration
|
|
968
1108
|
*/
|
|
969
|
-
registerDatabase(key, config) {
|
|
1109
|
+
registerDatabase(tenantId, key, config) {
|
|
970
1110
|
let database;
|
|
971
1111
|
switch (config.type) {
|
|
972
1112
|
case "postgres":
|
|
@@ -979,74 +1119,115 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
979
1119
|
default:
|
|
980
1120
|
throw new Error(`Unsupported database type: ${config.type}`);
|
|
981
1121
|
}
|
|
982
|
-
this.
|
|
983
|
-
|
|
984
|
-
|
|
1122
|
+
const tenantDbs = this.getTenantDatabases(tenantId);
|
|
1123
|
+
tenantDbs.set(key, database);
|
|
1124
|
+
if (!this.defaultDatabaseKeys.has(tenantId)) {
|
|
1125
|
+
this.defaultDatabaseKeys.set(tenantId, key);
|
|
985
1126
|
}
|
|
986
1127
|
}
|
|
987
1128
|
/**
|
|
988
|
-
* Set the default database
|
|
1129
|
+
* Set the default database for a tenant
|
|
1130
|
+
* @param tenantId - Tenant identifier
|
|
989
1131
|
* @param key - Database key to set as default
|
|
990
1132
|
*/
|
|
991
|
-
setDefaultDatabase(key) {
|
|
992
|
-
|
|
993
|
-
|
|
1133
|
+
setDefaultDatabase(tenantId, key) {
|
|
1134
|
+
const tenantDbs = this.databases.get(tenantId);
|
|
1135
|
+
if (!tenantDbs || !tenantDbs.has(key)) {
|
|
1136
|
+
throw new Error(`Database '${key}' not found for tenant '${tenantId}'`);
|
|
994
1137
|
}
|
|
995
|
-
this.
|
|
1138
|
+
this.defaultDatabaseKeys.set(tenantId, key);
|
|
996
1139
|
}
|
|
997
1140
|
/**
|
|
998
|
-
* Get a database by key
|
|
1141
|
+
* Get a database by key for a specific tenant
|
|
1142
|
+
* @param tenantId - Tenant identifier (required)
|
|
999
1143
|
* @param key - Database key (optional, uses default if not provided)
|
|
1144
|
+
* @returns ISqlDatabase instance
|
|
1145
|
+
* @throws Error if tenant or database not found
|
|
1000
1146
|
*/
|
|
1001
|
-
getDatabase(key) {
|
|
1002
|
-
const
|
|
1147
|
+
getDatabase(tenantId, key) {
|
|
1148
|
+
const tenantDbs = this.databases.get(tenantId);
|
|
1149
|
+
if (!tenantDbs) {
|
|
1150
|
+
throw new Error(`No databases registered for tenant '${tenantId}'`);
|
|
1151
|
+
}
|
|
1152
|
+
const dbKey = key || this.defaultDatabaseKeys.get(tenantId);
|
|
1003
1153
|
if (!dbKey) {
|
|
1004
|
-
throw new Error(
|
|
1154
|
+
throw new Error(`No default database set for tenant '${tenantId}'`);
|
|
1005
1155
|
}
|
|
1006
|
-
const database =
|
|
1156
|
+
const database = tenantDbs.get(dbKey);
|
|
1007
1157
|
if (!database) {
|
|
1008
|
-
throw new Error(`Database '${dbKey}' not found`);
|
|
1158
|
+
throw new Error(`Database '${dbKey}' not found for tenant '${tenantId}'`);
|
|
1009
1159
|
}
|
|
1010
1160
|
return database;
|
|
1011
1161
|
}
|
|
1012
1162
|
/**
|
|
1013
|
-
* Check if a database is registered
|
|
1163
|
+
* Check if a database is registered for a tenant
|
|
1164
|
+
* @param tenantId - Tenant identifier
|
|
1014
1165
|
* @param key - Database key
|
|
1166
|
+
* @returns true if database exists for the tenant
|
|
1015
1167
|
*/
|
|
1016
|
-
hasDatabase(key) {
|
|
1017
|
-
|
|
1168
|
+
hasDatabase(tenantId, key) {
|
|
1169
|
+
const tenantDbs = this.databases.get(tenantId);
|
|
1170
|
+
return tenantDbs ? tenantDbs.has(key) : false;
|
|
1018
1171
|
}
|
|
1019
1172
|
/**
|
|
1020
|
-
* Get all registered database keys
|
|
1173
|
+
* Get all registered database keys for a tenant
|
|
1174
|
+
* @param tenantId - Tenant identifier
|
|
1175
|
+
* @returns Array of database keys for the tenant
|
|
1021
1176
|
*/
|
|
1022
|
-
getDatabaseKeys() {
|
|
1023
|
-
|
|
1177
|
+
getDatabaseKeys(tenantId) {
|
|
1178
|
+
const tenantDbs = this.databases.get(tenantId);
|
|
1179
|
+
return tenantDbs ? Array.from(tenantDbs.keys()) : [];
|
|
1024
1180
|
}
|
|
1025
1181
|
/**
|
|
1026
|
-
* Remove a database connection
|
|
1182
|
+
* Remove a database connection for a tenant
|
|
1183
|
+
* @param tenantId - Tenant identifier
|
|
1027
1184
|
* @param key - Database key
|
|
1028
1185
|
*/
|
|
1029
|
-
async removeDatabase(key) {
|
|
1030
|
-
const
|
|
1186
|
+
async removeDatabase(tenantId, key) {
|
|
1187
|
+
const tenantDbs = this.databases.get(tenantId);
|
|
1188
|
+
if (!tenantDbs) return;
|
|
1189
|
+
const database = tenantDbs.get(key);
|
|
1031
1190
|
if (database) {
|
|
1032
1191
|
await database.disconnect();
|
|
1033
|
-
|
|
1034
|
-
if (this.
|
|
1035
|
-
|
|
1192
|
+
tenantDbs.delete(key);
|
|
1193
|
+
if (this.defaultDatabaseKeys.get(tenantId) === key) {
|
|
1194
|
+
const remainingKeys = Array.from(tenantDbs.keys());
|
|
1195
|
+
if (remainingKeys.length > 0) {
|
|
1196
|
+
this.defaultDatabaseKeys.set(tenantId, remainingKeys[0]);
|
|
1197
|
+
} else {
|
|
1198
|
+
this.defaultDatabaseKeys.delete(tenantId);
|
|
1199
|
+
this.databases.delete(tenantId);
|
|
1200
|
+
}
|
|
1036
1201
|
}
|
|
1037
1202
|
}
|
|
1038
1203
|
}
|
|
1039
1204
|
/**
|
|
1040
|
-
* Disconnect all databases
|
|
1205
|
+
* Disconnect all databases for a tenant
|
|
1206
|
+
* @param tenantId - Tenant identifier (optional, disconnects all if not provided)
|
|
1041
1207
|
*/
|
|
1042
|
-
async disconnectAll() {
|
|
1043
|
-
|
|
1044
|
-
|
|
1208
|
+
async disconnectAll(tenantId) {
|
|
1209
|
+
if (tenantId) {
|
|
1210
|
+
const tenantDbs = this.databases.get(tenantId);
|
|
1211
|
+
if (tenantDbs) {
|
|
1212
|
+
for (const database of tenantDbs.values()) {
|
|
1213
|
+
await database.disconnect();
|
|
1214
|
+
}
|
|
1215
|
+
this.databases.delete(tenantId);
|
|
1216
|
+
this.defaultDatabaseKeys.delete(tenantId);
|
|
1217
|
+
}
|
|
1218
|
+
} else {
|
|
1219
|
+
for (const [tid, tenantDbs] of this.databases) {
|
|
1220
|
+
for (const database of tenantDbs.values()) {
|
|
1221
|
+
await database.disconnect();
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
this.databases.clear();
|
|
1225
|
+
this.defaultDatabaseKeys.clear();
|
|
1045
1226
|
}
|
|
1046
1227
|
}
|
|
1047
1228
|
/**
|
|
1048
1229
|
* Load database configurations from a DatabaseConfigStore
|
|
1049
|
-
* and register them with this manager
|
|
1230
|
+
* and register them with this manager for a specific tenant
|
|
1050
1231
|
*
|
|
1051
1232
|
* @param store - The database configuration store
|
|
1052
1233
|
* @param tenantId - Tenant identifier
|
|
@@ -1054,7 +1235,7 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
1054
1235
|
async loadConfigsFromStore(store, tenantId) {
|
|
1055
1236
|
const configs = await store.getAllConfigs(tenantId);
|
|
1056
1237
|
for (const entry of configs) {
|
|
1057
|
-
this.registerDatabase(entry.key, entry.config);
|
|
1238
|
+
this.registerDatabase(tenantId, entry.key, entry.config);
|
|
1058
1239
|
}
|
|
1059
1240
|
}
|
|
1060
1241
|
/**
|
|
@@ -1066,7 +1247,21 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
|
|
|
1066
1247
|
async loadAllConfigsFromStore(store) {
|
|
1067
1248
|
const configs = await store.getAllConfigsWithoutTenant();
|
|
1068
1249
|
for (const entry of configs) {
|
|
1069
|
-
|
|
1250
|
+
const tenantId = entry.tenantId || "default";
|
|
1251
|
+
this.registerDatabase(tenantId, entry.key, entry.config);
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Clear all databases for a tenant (useful for testing)
|
|
1256
|
+
* @param tenantId - Tenant identifier (optional, clears all if not provided)
|
|
1257
|
+
*/
|
|
1258
|
+
clear(tenantId) {
|
|
1259
|
+
if (tenantId) {
|
|
1260
|
+
this.databases.delete(tenantId);
|
|
1261
|
+
this.defaultDatabaseKeys.delete(tenantId);
|
|
1262
|
+
} else {
|
|
1263
|
+
this.databases.clear();
|
|
1264
|
+
this.defaultDatabaseKeys.clear();
|
|
1070
1265
|
}
|
|
1071
1266
|
}
|
|
1072
1267
|
};
|
|
@@ -1075,8 +1270,16 @@ var sqlDatabaseManager = SqlDatabaseManager.getInstance();
|
|
|
1075
1270
|
// src/tool_lattice/sql/list_tables_sql.ts
|
|
1076
1271
|
var import_zod3 = __toESM(require("zod"));
|
|
1077
1272
|
var import_langchain = require("langchain");
|
|
1273
|
+
|
|
1274
|
+
// src/tool_lattice/sql/utils.ts
|
|
1275
|
+
function getTenantIdFromConfig(exeConfig, getTenantId) {
|
|
1276
|
+
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
1277
|
+
return runConfig.tenantId || (getTenantId ? getTenantId() : "default");
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
// src/tool_lattice/sql/list_tables_sql.ts
|
|
1078
1281
|
var LIST_TABLES_SQL_DESCRIPTION = `List all tables in the connected SQL database. Returns a comma-separated list of table names. Use this tool first to understand what tables are available before querying the database.`;
|
|
1079
|
-
var createListTablesSqlTool = ({ databaseKeys, databaseDescriptions }) => {
|
|
1282
|
+
var createListTablesSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
|
|
1080
1283
|
const availableDbsText = databaseKeys.length > 0 ? `
|
|
1081
1284
|
|
|
1082
1285
|
Available databases:
|
|
@@ -1084,15 +1287,16 @@ ${databaseKeys.map(
|
|
|
1084
1287
|
(key) => `- ${key}${databaseDescriptions?.[key] ? `: ${databaseDescriptions[key]}` : ""}`
|
|
1085
1288
|
).join("\n")}` : "";
|
|
1086
1289
|
return (0, import_langchain.tool)(
|
|
1087
|
-
async ({ databaseKey },
|
|
1290
|
+
async ({ databaseKey }, _exeConfig) => {
|
|
1088
1291
|
try {
|
|
1292
|
+
const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId);
|
|
1089
1293
|
if (!databaseKey) {
|
|
1090
1294
|
return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
|
|
1091
1295
|
}
|
|
1092
1296
|
if (!databaseKeys.includes(databaseKey)) {
|
|
1093
1297
|
return `Error: databaseKey "${databaseKey}" is not in the allowed list: [${databaseKeys.join(", ")}]`;
|
|
1094
1298
|
}
|
|
1095
|
-
const database = sqlDatabaseManager.getDatabase(databaseKey);
|
|
1299
|
+
const database = sqlDatabaseManager.getDatabase(databaseKey, tenantId);
|
|
1096
1300
|
const tables = await database.listTables();
|
|
1097
1301
|
if (tables.length === 0) {
|
|
1098
1302
|
return "No tables found in the database.";
|
|
@@ -1119,7 +1323,7 @@ ${databaseKeys.map(
|
|
|
1119
1323
|
var import_zod4 = __toESM(require("zod"));
|
|
1120
1324
|
var import_langchain2 = require("langchain");
|
|
1121
1325
|
var INFO_SQL_DESCRIPTION = `Get detailed schema information for specified tables, including column names, types, constraints (primary keys, foreign keys), and sample rows. Input should be a comma-separated list of table names.`;
|
|
1122
|
-
var createInfoSqlTool = ({ databaseKeys, databaseDescriptions }) => {
|
|
1326
|
+
var createInfoSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
|
|
1123
1327
|
const availableDbsText = databaseKeys.length > 0 ? `
|
|
1124
1328
|
|
|
1125
1329
|
Available databases:
|
|
@@ -1130,15 +1334,16 @@ ${databaseKeys.map(
|
|
|
1130
1334
|
async ({
|
|
1131
1335
|
tables,
|
|
1132
1336
|
databaseKey
|
|
1133
|
-
},
|
|
1337
|
+
}, _exeConfig) => {
|
|
1134
1338
|
try {
|
|
1339
|
+
const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId);
|
|
1135
1340
|
if (!databaseKey) {
|
|
1136
1341
|
return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
|
|
1137
1342
|
}
|
|
1138
1343
|
if (!databaseKeys.includes(databaseKey)) {
|
|
1139
1344
|
return `Error: databaseKey "${databaseKey}" is not in the allowed list: [${databaseKeys.join(", ")}]`;
|
|
1140
1345
|
}
|
|
1141
|
-
const database = sqlDatabaseManager.getDatabase(databaseKey);
|
|
1346
|
+
const database = sqlDatabaseManager.getDatabase(databaseKey, tenantId);
|
|
1142
1347
|
const tableNames = tables.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
1143
1348
|
if (tableNames.length === 0) {
|
|
1144
1349
|
return "Error: No table names provided. Please provide a comma-separated list of table names.";
|
|
@@ -1250,7 +1455,7 @@ function checkDangerousOperations(query) {
|
|
|
1250
1455
|
}
|
|
1251
1456
|
return warnings;
|
|
1252
1457
|
}
|
|
1253
|
-
var createQueryCheckerSqlTool = ({ databaseKeys, databaseDescriptions }) => {
|
|
1458
|
+
var createQueryCheckerSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
|
|
1254
1459
|
const availableDbsText = databaseKeys.length > 0 ? `
|
|
1255
1460
|
|
|
1256
1461
|
Available databases:
|
|
@@ -1261,8 +1466,9 @@ ${databaseKeys.map(
|
|
|
1261
1466
|
async ({
|
|
1262
1467
|
query,
|
|
1263
1468
|
databaseKey
|
|
1264
|
-
},
|
|
1469
|
+
}, _exeConfig) => {
|
|
1265
1470
|
try {
|
|
1471
|
+
const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId);
|
|
1266
1472
|
const trimmedQuery = query.trim();
|
|
1267
1473
|
if (!trimmedQuery) {
|
|
1268
1474
|
return "Error: Empty query provided. Please provide a SQL query to check.";
|
|
@@ -1294,7 +1500,7 @@ ${trimmedQuery}
|
|
|
1294
1500
|
}
|
|
1295
1501
|
if (databaseKey && databaseKeys.includes(databaseKey)) {
|
|
1296
1502
|
try {
|
|
1297
|
-
const database = sqlDatabaseManager.getDatabase(databaseKey);
|
|
1503
|
+
const database = sqlDatabaseManager.getDatabase(databaseKey, tenantId);
|
|
1298
1504
|
const dbType = database.getDatabaseType();
|
|
1299
1505
|
if (dbType === "postgres") {
|
|
1300
1506
|
try {
|
|
@@ -1371,7 +1577,7 @@ function formatQueryResult(rows, fields) {
|
|
|
1371
1577
|
Total rows: ${rows.length}`);
|
|
1372
1578
|
return lines.join("\n");
|
|
1373
1579
|
}
|
|
1374
|
-
var createQuerySqlTool = ({ databaseKeys, databaseDescriptions }) => {
|
|
1580
|
+
var createQuerySqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
|
|
1375
1581
|
const availableDbsText = databaseKeys.length > 0 ? `
|
|
1376
1582
|
|
|
1377
1583
|
Available databases:
|
|
@@ -1382,8 +1588,9 @@ ${databaseKeys.map(
|
|
|
1382
1588
|
async ({
|
|
1383
1589
|
query,
|
|
1384
1590
|
databaseKey
|
|
1385
|
-
},
|
|
1591
|
+
}, _exeConfig) => {
|
|
1386
1592
|
try {
|
|
1593
|
+
const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId);
|
|
1387
1594
|
if (!databaseKey) {
|
|
1388
1595
|
return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
|
|
1389
1596
|
}
|
|
@@ -1394,7 +1601,7 @@ ${databaseKeys.map(
|
|
|
1394
1601
|
if (!trimmedQuery) {
|
|
1395
1602
|
return "Error: Empty query provided. Please provide a valid SQL query.";
|
|
1396
1603
|
}
|
|
1397
|
-
const database = sqlDatabaseManager.getDatabase(databaseKey);
|
|
1604
|
+
const database = sqlDatabaseManager.getDatabase(databaseKey, tenantId);
|
|
1398
1605
|
const result = await database.executeQuery(trimmedQuery);
|
|
1399
1606
|
return formatQueryResult(result.rows, result.fields);
|
|
1400
1607
|
} catch (error) {
|
|
@@ -1926,7 +2133,7 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
1926
2133
|
constructor() {
|
|
1927
2134
|
this.clients = /* @__PURE__ */ new Map();
|
|
1928
2135
|
this.configs = /* @__PURE__ */ new Map();
|
|
1929
|
-
this.
|
|
2136
|
+
this.defaultServerKeys = /* @__PURE__ */ new Map();
|
|
1930
2137
|
}
|
|
1931
2138
|
/**
|
|
1932
2139
|
* Get the singleton instance
|
|
@@ -1938,11 +2145,34 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
1938
2145
|
return _MetricsServerManager.instance;
|
|
1939
2146
|
}
|
|
1940
2147
|
/**
|
|
1941
|
-
*
|
|
2148
|
+
* Get or create tenant clients map
|
|
2149
|
+
*/
|
|
2150
|
+
getTenantClients(tenantId) {
|
|
2151
|
+
let tenantClients = this.clients.get(tenantId);
|
|
2152
|
+
if (!tenantClients) {
|
|
2153
|
+
tenantClients = /* @__PURE__ */ new Map();
|
|
2154
|
+
this.clients.set(tenantId, tenantClients);
|
|
2155
|
+
}
|
|
2156
|
+
return tenantClients;
|
|
2157
|
+
}
|
|
2158
|
+
/**
|
|
2159
|
+
* Get or create tenant configs map
|
|
2160
|
+
*/
|
|
2161
|
+
getTenantConfigs(tenantId) {
|
|
2162
|
+
let tenantConfigs = this.configs.get(tenantId);
|
|
2163
|
+
if (!tenantConfigs) {
|
|
2164
|
+
tenantConfigs = /* @__PURE__ */ new Map();
|
|
2165
|
+
this.configs.set(tenantId, tenantConfigs);
|
|
2166
|
+
}
|
|
2167
|
+
return tenantConfigs;
|
|
2168
|
+
}
|
|
2169
|
+
/**
|
|
2170
|
+
* Register a metrics server for a tenant
|
|
2171
|
+
* @param tenantId - Tenant identifier
|
|
1942
2172
|
* @param key - Unique identifier for the server
|
|
1943
2173
|
* @param config - Metrics server configuration
|
|
1944
2174
|
*/
|
|
1945
|
-
registerServer(key, config) {
|
|
2175
|
+
registerServer(tenantId, key, config) {
|
|
1946
2176
|
let client;
|
|
1947
2177
|
switch (config.type) {
|
|
1948
2178
|
case "prometheus":
|
|
@@ -1957,82 +2187,136 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
1957
2187
|
default:
|
|
1958
2188
|
throw new Error(`Unsupported metrics server type: ${config.type}`);
|
|
1959
2189
|
}
|
|
1960
|
-
this.
|
|
1961
|
-
this.
|
|
1962
|
-
|
|
1963
|
-
|
|
2190
|
+
const tenantClients = this.getTenantClients(tenantId);
|
|
2191
|
+
const tenantConfigs = this.getTenantConfigs(tenantId);
|
|
2192
|
+
tenantClients.set(key, client);
|
|
2193
|
+
tenantConfigs.set(key, config);
|
|
2194
|
+
if (!this.defaultServerKeys.has(tenantId)) {
|
|
2195
|
+
this.defaultServerKeys.set(tenantId, key);
|
|
1964
2196
|
}
|
|
1965
2197
|
}
|
|
1966
2198
|
/**
|
|
1967
|
-
* Set the default metrics server
|
|
2199
|
+
* Set the default metrics server for a tenant
|
|
2200
|
+
* @param tenantId - Tenant identifier
|
|
1968
2201
|
* @param key - Server key to set as default
|
|
1969
2202
|
*/
|
|
1970
|
-
setDefaultServer(key) {
|
|
1971
|
-
|
|
1972
|
-
|
|
2203
|
+
setDefaultServer(tenantId, key) {
|
|
2204
|
+
const tenantClients = this.clients.get(tenantId);
|
|
2205
|
+
if (!tenantClients || !tenantClients.has(key)) {
|
|
2206
|
+
throw new Error(`Metrics server '${key}' not found for tenant '${tenantId}'`);
|
|
1973
2207
|
}
|
|
1974
|
-
this.
|
|
2208
|
+
this.defaultServerKeys.set(tenantId, key);
|
|
1975
2209
|
}
|
|
1976
2210
|
/**
|
|
1977
|
-
* Get a metrics server client by key
|
|
2211
|
+
* Get a metrics server client by key for a specific tenant
|
|
2212
|
+
* @param tenantId - Tenant identifier
|
|
1978
2213
|
* @param key - Server key (optional, uses default if not provided)
|
|
1979
2214
|
*/
|
|
1980
|
-
getClient(key) {
|
|
1981
|
-
const
|
|
2215
|
+
getClient(tenantId, key) {
|
|
2216
|
+
const tenantClients = this.clients.get(tenantId);
|
|
2217
|
+
if (!tenantClients) {
|
|
2218
|
+
throw new Error(`No metrics servers registered for tenant '${tenantId}'`);
|
|
2219
|
+
}
|
|
2220
|
+
const serverKey = key || this.defaultServerKeys.get(tenantId);
|
|
1982
2221
|
if (!serverKey) {
|
|
1983
|
-
throw new Error(
|
|
2222
|
+
throw new Error(`No default metrics server set for tenant '${tenantId}'`);
|
|
1984
2223
|
}
|
|
1985
|
-
const client =
|
|
2224
|
+
const client = tenantClients.get(serverKey);
|
|
1986
2225
|
if (!client) {
|
|
1987
|
-
throw new Error(`Metrics server '${serverKey}' not found`);
|
|
2226
|
+
throw new Error(`Metrics server '${serverKey}' not found for tenant '${tenantId}'`);
|
|
1988
2227
|
}
|
|
1989
2228
|
return client;
|
|
1990
2229
|
}
|
|
1991
2230
|
/**
|
|
1992
|
-
* Get metrics server configuration by key
|
|
2231
|
+
* Get metrics server configuration by key for a specific tenant
|
|
2232
|
+
* @param tenantId - Tenant identifier
|
|
1993
2233
|
* @param key - Server key (optional, uses default if not provided)
|
|
1994
2234
|
*/
|
|
1995
|
-
getConfig(key) {
|
|
1996
|
-
const
|
|
2235
|
+
getConfig(tenantId, key) {
|
|
2236
|
+
const tenantConfigs = this.configs.get(tenantId);
|
|
2237
|
+
if (!tenantConfigs) {
|
|
2238
|
+
throw new Error(`No metrics servers registered for tenant '${tenantId}'`);
|
|
2239
|
+
}
|
|
2240
|
+
const serverKey = key || this.defaultServerKeys.get(tenantId);
|
|
1997
2241
|
if (!serverKey) {
|
|
1998
|
-
throw new Error(
|
|
2242
|
+
throw new Error(`No default metrics server set for tenant '${tenantId}'`);
|
|
1999
2243
|
}
|
|
2000
|
-
const config =
|
|
2244
|
+
const config = tenantConfigs.get(serverKey);
|
|
2001
2245
|
if (!config) {
|
|
2002
|
-
throw new Error(`Metrics server '${serverKey}' not found`);
|
|
2246
|
+
throw new Error(`Metrics server '${serverKey}' not found for tenant '${tenantId}'`);
|
|
2003
2247
|
}
|
|
2004
2248
|
return config;
|
|
2005
2249
|
}
|
|
2006
2250
|
/**
|
|
2007
|
-
* Check if a metrics server is registered
|
|
2251
|
+
* Check if a metrics server is registered for a tenant
|
|
2252
|
+
* @param tenantId - Tenant identifier
|
|
2008
2253
|
* @param key - Server key
|
|
2009
2254
|
*/
|
|
2010
|
-
hasServer(key) {
|
|
2011
|
-
|
|
2255
|
+
hasServer(tenantId, key) {
|
|
2256
|
+
const tenantClients = this.clients.get(tenantId);
|
|
2257
|
+
return tenantClients ? tenantClients.has(key) : false;
|
|
2012
2258
|
}
|
|
2013
2259
|
/**
|
|
2014
|
-
* Get all registered metrics server keys with their types
|
|
2260
|
+
* Get all registered metrics server keys with their types for a tenant
|
|
2261
|
+
* @param tenantId - Tenant identifier
|
|
2015
2262
|
*/
|
|
2016
|
-
getServerKeys() {
|
|
2017
|
-
|
|
2263
|
+
getServerKeys(tenantId) {
|
|
2264
|
+
const tenantConfigs = this.configs.get(tenantId);
|
|
2265
|
+
if (!tenantConfigs) {
|
|
2266
|
+
return [];
|
|
2267
|
+
}
|
|
2268
|
+
return Array.from(tenantConfigs.entries()).map(([key, config]) => ({
|
|
2018
2269
|
key,
|
|
2019
2270
|
type: config.type
|
|
2020
2271
|
}));
|
|
2021
2272
|
}
|
|
2022
2273
|
/**
|
|
2023
|
-
* Remove a metrics server
|
|
2274
|
+
* Remove a metrics server for a tenant
|
|
2275
|
+
* @param tenantId - Tenant identifier
|
|
2024
2276
|
* @param key - Server key
|
|
2025
2277
|
*/
|
|
2026
|
-
removeServer(key) {
|
|
2027
|
-
this.clients.
|
|
2028
|
-
this.configs.
|
|
2029
|
-
if (
|
|
2030
|
-
|
|
2278
|
+
removeServer(tenantId, key) {
|
|
2279
|
+
const tenantClients = this.clients.get(tenantId);
|
|
2280
|
+
const tenantConfigs = this.configs.get(tenantId);
|
|
2281
|
+
if (tenantClients) {
|
|
2282
|
+
tenantClients.delete(key);
|
|
2283
|
+
if (tenantClients.size === 0) {
|
|
2284
|
+
this.clients.delete(tenantId);
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
if (tenantConfigs) {
|
|
2288
|
+
tenantConfigs.delete(key);
|
|
2289
|
+
if (tenantConfigs.size === 0) {
|
|
2290
|
+
this.configs.delete(tenantId);
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
if (this.defaultServerKeys.get(tenantId) === key) {
|
|
2294
|
+
const remainingKeys = tenantClients ? Array.from(tenantClients.keys()) : [];
|
|
2295
|
+
if (remainingKeys.length > 0) {
|
|
2296
|
+
this.defaultServerKeys.set(tenantId, remainingKeys[0]);
|
|
2297
|
+
} else {
|
|
2298
|
+
this.defaultServerKeys.delete(tenantId);
|
|
2299
|
+
}
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
/**
|
|
2303
|
+
* Clear all metrics servers for a tenant
|
|
2304
|
+
* @param tenantId - Tenant identifier (optional, clears all if not provided)
|
|
2305
|
+
*/
|
|
2306
|
+
clear(tenantId) {
|
|
2307
|
+
if (tenantId) {
|
|
2308
|
+
this.clients.delete(tenantId);
|
|
2309
|
+
this.configs.delete(tenantId);
|
|
2310
|
+
this.defaultServerKeys.delete(tenantId);
|
|
2311
|
+
} else {
|
|
2312
|
+
this.clients.clear();
|
|
2313
|
+
this.configs.clear();
|
|
2314
|
+
this.defaultServerKeys.clear();
|
|
2031
2315
|
}
|
|
2032
2316
|
}
|
|
2033
2317
|
/**
|
|
2034
2318
|
* Load metrics server configurations from a store
|
|
2035
|
-
* and register them with this manager
|
|
2319
|
+
* and register them with this manager for a specific tenant
|
|
2036
2320
|
*
|
|
2037
2321
|
* @param store - The metrics server configuration store
|
|
2038
2322
|
* @param tenantId - Tenant identifier
|
|
@@ -2040,7 +2324,7 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
2040
2324
|
async loadConfigsFromStore(store, tenantId) {
|
|
2041
2325
|
const configs = await store.getAllConfigs(tenantId);
|
|
2042
2326
|
for (const entry of configs) {
|
|
2043
|
-
this.registerServer(entry.key, entry.config);
|
|
2327
|
+
this.registerServer(tenantId, entry.key, entry.config);
|
|
2044
2328
|
}
|
|
2045
2329
|
}
|
|
2046
2330
|
/**
|
|
@@ -2048,11 +2332,13 @@ var MetricsServerManager = class _MetricsServerManager {
|
|
|
2048
2332
|
* across all tenants and register them with this manager
|
|
2049
2333
|
*
|
|
2050
2334
|
* @param store - The metrics server configuration store
|
|
2335
|
+
* @deprecated Use loadConfigsFromStore with specific tenant instead
|
|
2051
2336
|
*/
|
|
2052
2337
|
async loadAllConfigsFromStore(store) {
|
|
2053
2338
|
const configs = await store.getAllConfigsWithoutTenant();
|
|
2054
2339
|
for (const entry of configs) {
|
|
2055
|
-
|
|
2340
|
+
const tenantId = entry.tenantId || "default";
|
|
2341
|
+
this.registerServer(tenantId, entry.key, entry.config);
|
|
2056
2342
|
}
|
|
2057
2343
|
}
|
|
2058
2344
|
};
|
|
@@ -2061,8 +2347,21 @@ var metricsServerManager = MetricsServerManager.getInstance();
|
|
|
2061
2347
|
// src/tool_lattice/metrics/list_metrics_servers.ts
|
|
2062
2348
|
var import_zod7 = __toESM(require("zod"));
|
|
2063
2349
|
var import_langchain5 = require("langchain");
|
|
2350
|
+
|
|
2351
|
+
// src/tool_lattice/metrics/utils.ts
|
|
2352
|
+
function getTenantIdFromConfig2(exeConfig, getTenantId) {
|
|
2353
|
+
const runConfig = exeConfig?.configurable?.runConfig || {};
|
|
2354
|
+
return runConfig.tenantId || (getTenantId ? getTenantId() : "default");
|
|
2355
|
+
}
|
|
2356
|
+
function filterServerKeysByTenant(serverKeys, tenantId, manager = metricsServerManager) {
|
|
2357
|
+
return serverKeys.filter((key) => {
|
|
2358
|
+
return manager.hasServer(tenantId, key);
|
|
2359
|
+
});
|
|
2360
|
+
}
|
|
2361
|
+
|
|
2362
|
+
// src/tool_lattice/metrics/list_metrics_servers.ts
|
|
2064
2363
|
var LIST_METRICS_SERVERS_DESCRIPTION = `List all registered metrics servers. Returns a list of available metrics servers with their keys and types. Use this tool first to understand what metrics servers are available.`;
|
|
2065
|
-
var createListMetricsServersTool = ({ serverKeys, serverDescriptions }) => {
|
|
2364
|
+
var createListMetricsServersTool = ({ serverKeys, serverDescriptions, getTenantId }) => {
|
|
2066
2365
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2067
2366
|
|
|
2068
2367
|
Available metrics servers:
|
|
@@ -2072,7 +2371,8 @@ ${serverKeys.map(
|
|
|
2072
2371
|
return (0, import_langchain5.tool)(
|
|
2073
2372
|
async (_input, _exeConfig) => {
|
|
2074
2373
|
try {
|
|
2075
|
-
const
|
|
2374
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
|
|
2375
|
+
const servers = metricsServerManager.getServerKeys(tenantId);
|
|
2076
2376
|
if (servers.length === 0) {
|
|
2077
2377
|
return "No metrics servers registered.";
|
|
2078
2378
|
}
|
|
@@ -2098,7 +2398,7 @@ ${lines.join("\n")}`;
|
|
|
2098
2398
|
var import_zod8 = __toESM(require("zod"));
|
|
2099
2399
|
var import_langchain6 = require("langchain");
|
|
2100
2400
|
var LIST_METRICS_DATASOURCES_DESCRIPTION = `List all available datasources from all configured metrics servers. Returns a table with Server Key, DataSource ID, and DataSource Name. Use this tool first to discover what datasources are available before querying metrics.`;
|
|
2101
|
-
var createListMetricsDataSourcesTool = ({ serverKeys, serverDescriptions }) => {
|
|
2401
|
+
var createListMetricsDataSourcesTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2102
2402
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2103
2403
|
|
|
2104
2404
|
Configured metrics servers:
|
|
@@ -2108,6 +2408,12 @@ ${serverKeys.map(
|
|
|
2108
2408
|
return (0, import_langchain6.tool)(
|
|
2109
2409
|
async (_input, _exeConfig) => {
|
|
2110
2410
|
try {
|
|
2411
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
|
|
2412
|
+
let effectiveServerKeys = serverKeys;
|
|
2413
|
+
if (connectAll) {
|
|
2414
|
+
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
2415
|
+
}
|
|
2416
|
+
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
2111
2417
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
2112
2418
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
2113
2419
|
if (metricsDataSource) {
|
|
@@ -2122,18 +2428,18 @@ You can directly use other metrics tools (such as query_metrics_list, query_sema
|
|
|
2122
2428
|
|
|
2123
2429
|
To view all available data sources, please clear the current selection or reopen the data source selector.`;
|
|
2124
2430
|
}
|
|
2125
|
-
if (
|
|
2126
|
-
return
|
|
2431
|
+
if (filteredServerKeys.length === 0) {
|
|
2432
|
+
return `No metrics servers available for tenant "${tenantId}".`;
|
|
2127
2433
|
}
|
|
2128
2434
|
const allDataSources = [];
|
|
2129
|
-
for (const serverKey of
|
|
2435
|
+
for (const serverKey of filteredServerKeys) {
|
|
2130
2436
|
try {
|
|
2131
|
-
const config = metricsServerManager.getConfig(serverKey);
|
|
2437
|
+
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
2132
2438
|
if (config.type !== "semantic") {
|
|
2133
2439
|
console.warn(`Server "${serverKey}" is not a semantic metrics server, skipping.`);
|
|
2134
2440
|
continue;
|
|
2135
2441
|
}
|
|
2136
|
-
const client = metricsServerManager.getClient(serverKey);
|
|
2442
|
+
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
2137
2443
|
const dataSources = await client.getDataSources();
|
|
2138
2444
|
const selectedIds = config.selectedDataSources || [];
|
|
2139
2445
|
const filteredDataSources = selectedIds.length > 0 ? dataSources.filter((ds) => selectedIds.includes(String(ds.id))) : dataSources;
|
|
@@ -2149,10 +2455,10 @@ To view all available data sources, please clear the current selection or reopen
|
|
|
2149
2455
|
}
|
|
2150
2456
|
}
|
|
2151
2457
|
if (allDataSources.length === 0) {
|
|
2152
|
-
return `No datasources found in any configured metrics servers.`;
|
|
2458
|
+
return `No datasources found in any configured metrics servers for tenant "${tenantId}".`;
|
|
2153
2459
|
}
|
|
2154
2460
|
const lines = [];
|
|
2155
|
-
lines.push(`Found ${allDataSources.length} datasource(s) from ${
|
|
2461
|
+
lines.push(`Found ${allDataSources.length} datasource(s) from ${filteredServerKeys.length} server(s):
|
|
2156
2462
|
`);
|
|
2157
2463
|
lines.push("| Server Key | DataSource ID | Name |");
|
|
2158
2464
|
lines.push("|------------|---------------|------|");
|
|
@@ -2208,7 +2514,7 @@ Response Fields Reference
|
|
|
2208
2514
|
|
|
2209
2515
|
Next Step
|
|
2210
2516
|
After finding relevant metrics, call query_metric_definition with the metricName to get detailed metadata including time dimensions and supported filters.`;
|
|
2211
|
-
var createQueryMetricsListTool = ({ serverKeys, serverDescriptions }) => {
|
|
2517
|
+
var createQueryMetricsListTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2212
2518
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2213
2519
|
|
|
2214
2520
|
Available metrics servers:
|
|
@@ -2221,20 +2527,26 @@ ${serverKeys.map(
|
|
|
2221
2527
|
datasourceIds
|
|
2222
2528
|
}, _exeConfig) => {
|
|
2223
2529
|
try {
|
|
2530
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
|
|
2531
|
+
let effectiveServerKeys = serverKeys;
|
|
2532
|
+
if (connectAll) {
|
|
2533
|
+
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
2534
|
+
}
|
|
2535
|
+
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
2224
2536
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
2225
2537
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
2226
2538
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
2227
2539
|
if (!serverKey) {
|
|
2228
|
-
return "Error: serverKey parameter is required. Available servers: " +
|
|
2540
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2229
2541
|
}
|
|
2230
|
-
if (!
|
|
2231
|
-
return `Error: serverKey "${serverKey}" is not
|
|
2542
|
+
if (!filteredServerKeys.includes(serverKey)) {
|
|
2543
|
+
return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
|
|
2232
2544
|
}
|
|
2233
|
-
const config = metricsServerManager.getConfig(serverKey);
|
|
2545
|
+
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
2234
2546
|
if (config.type !== "semantic") {
|
|
2235
2547
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
2236
2548
|
}
|
|
2237
|
-
const client = metricsServerManager.getClient(serverKey);
|
|
2549
|
+
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
2238
2550
|
const targetDatasourceIds = datasourceIds && datasourceIds.length > 0 ? datasourceIds : metricsDataSource?.datasourceId ? [metricsDataSource.datasourceId] : client.getSelectedDataSources();
|
|
2239
2551
|
if (targetDatasourceIds.length === 0) {
|
|
2240
2552
|
return `Error: No data sources specified and no default data sources configured for server "${serverKey}".`;
|
|
@@ -2359,7 +2671,7 @@ Rules
|
|
|
2359
2671
|
|
|
2360
2672
|
Next Step
|
|
2361
2673
|
Call query_semantic_metric_data with parameters derived from this definition.`;
|
|
2362
|
-
var createQueryMetricDefinitionTool = ({ serverKeys, serverDescriptions }) => {
|
|
2674
|
+
var createQueryMetricDefinitionTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2363
2675
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2364
2676
|
|
|
2365
2677
|
Available metrics servers:
|
|
@@ -2373,24 +2685,30 @@ ${serverKeys.map(
|
|
|
2373
2685
|
datasourceId: inputDatasourceId
|
|
2374
2686
|
}, _exeConfig) => {
|
|
2375
2687
|
try {
|
|
2688
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
|
|
2689
|
+
let effectiveServerKeys = serverKeys;
|
|
2690
|
+
if (connectAll) {
|
|
2691
|
+
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
2692
|
+
}
|
|
2693
|
+
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
2376
2694
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
2377
2695
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
2378
2696
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
2379
2697
|
const datasourceId = inputDatasourceId || metricsDataSource?.datasourceId;
|
|
2380
2698
|
if (!serverKey) {
|
|
2381
|
-
return "Error: serverKey parameter is required. Available servers: " +
|
|
2699
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2382
2700
|
}
|
|
2383
|
-
if (!
|
|
2384
|
-
return `Error: serverKey "${serverKey}" is not
|
|
2701
|
+
if (!filteredServerKeys.includes(serverKey)) {
|
|
2702
|
+
return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
|
|
2385
2703
|
}
|
|
2386
2704
|
if (!metricName) {
|
|
2387
2705
|
return "Error: metricName parameter is required.";
|
|
2388
2706
|
}
|
|
2389
|
-
const config = metricsServerManager.getConfig(serverKey);
|
|
2707
|
+
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
2390
2708
|
if (config.type !== "semantic") {
|
|
2391
2709
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
2392
2710
|
}
|
|
2393
|
-
const client = metricsServerManager.getClient(serverKey);
|
|
2711
|
+
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
2394
2712
|
const targetDatasourceIds = datasourceId ? [datasourceId] : client.getSelectedDataSources();
|
|
2395
2713
|
if (targetDatasourceIds.length === 0) {
|
|
2396
2714
|
return `Error: No datasourceId specified and no default data sources configured for server "${serverKey}".`;
|
|
@@ -2779,7 +3097,7 @@ Data Source: ${datasourceId}${datasourceName ? ` (${datasourceName})` : ""}`;
|
|
|
2779
3097
|
}
|
|
2780
3098
|
return lines.join("\n");
|
|
2781
3099
|
}
|
|
2782
|
-
var createQuerySemanticMetricDataTool = ({ serverKeys, serverDescriptions }) => {
|
|
3100
|
+
var createQuerySemanticMetricDataTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2783
3101
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2784
3102
|
|
|
2785
3103
|
Available metrics servers:
|
|
@@ -2796,15 +3114,21 @@ ${serverKeys.map(
|
|
|
2796
3114
|
limit
|
|
2797
3115
|
}, _exeConfig) => {
|
|
2798
3116
|
try {
|
|
3117
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
|
|
3118
|
+
let effectiveServerKeys = serverKeys;
|
|
3119
|
+
if (connectAll) {
|
|
3120
|
+
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
3121
|
+
}
|
|
3122
|
+
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
2799
3123
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
2800
3124
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
2801
3125
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
2802
3126
|
const datasourceId = metricsDataSource?.datasourceId || inputDatasourceId;
|
|
2803
3127
|
if (!serverKey) {
|
|
2804
|
-
return "Error: serverKey parameter is required. Available servers: " +
|
|
3128
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2805
3129
|
}
|
|
2806
|
-
if (!
|
|
2807
|
-
return `Error: serverKey "${serverKey}" is not
|
|
3130
|
+
if (!filteredServerKeys.includes(serverKey)) {
|
|
3131
|
+
return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
|
|
2808
3132
|
}
|
|
2809
3133
|
if (!datasourceId) {
|
|
2810
3134
|
return "Error: datasourceId parameter is required.";
|
|
@@ -2812,11 +3136,11 @@ ${serverKeys.map(
|
|
|
2812
3136
|
if (!metrics || metrics.length === 0) {
|
|
2813
3137
|
return "Error: metrics parameter is required (at least one metric name).";
|
|
2814
3138
|
}
|
|
2815
|
-
const config = metricsServerManager.getConfig(serverKey);
|
|
3139
|
+
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
2816
3140
|
if (config.type !== "semantic") {
|
|
2817
3141
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
2818
3142
|
}
|
|
2819
|
-
const client = metricsServerManager.getClient(serverKey);
|
|
3143
|
+
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
2820
3144
|
const semanticFilters = (filters || []).map((f) => ({
|
|
2821
3145
|
dimension: f.dimension,
|
|
2822
3146
|
operator: f.operator,
|
|
@@ -2862,7 +3186,7 @@ ${serverKeys.map(
|
|
|
2862
3186
|
var import_zod12 = __toESM(require("zod"));
|
|
2863
3187
|
var import_langchain10 = require("langchain");
|
|
2864
3188
|
var QUERY_TABLES_LIST_DESCRIPTION = `Query available tables from a semantic metrics server. Returns a list of data tables with their schemas and descriptions. Use this tool to discover what tables are available in the data source.`;
|
|
2865
|
-
var createQueryTablesListTool = ({ serverKeys, serverDescriptions }) => {
|
|
3189
|
+
var createQueryTablesListTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2866
3190
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2867
3191
|
|
|
2868
3192
|
Available metrics servers:
|
|
@@ -2875,20 +3199,26 @@ ${serverKeys.map(
|
|
|
2875
3199
|
datasourceIds
|
|
2876
3200
|
}, _exeConfig) => {
|
|
2877
3201
|
try {
|
|
3202
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
|
|
3203
|
+
let effectiveServerKeys = serverKeys;
|
|
3204
|
+
if (connectAll) {
|
|
3205
|
+
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
3206
|
+
}
|
|
3207
|
+
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
2878
3208
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
2879
3209
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
2880
3210
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
2881
3211
|
if (!serverKey) {
|
|
2882
|
-
return "Error: serverKey parameter is required. Available servers: " +
|
|
3212
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2883
3213
|
}
|
|
2884
|
-
if (!
|
|
2885
|
-
return `Error: serverKey "${serverKey}" is not
|
|
3214
|
+
if (!filteredServerKeys.includes(serverKey)) {
|
|
3215
|
+
return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
|
|
2886
3216
|
}
|
|
2887
|
-
const config = metricsServerManager.getConfig(serverKey);
|
|
3217
|
+
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
2888
3218
|
if (config.type !== "semantic") {
|
|
2889
3219
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
2890
3220
|
}
|
|
2891
|
-
const client = metricsServerManager.getClient(serverKey);
|
|
3221
|
+
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
2892
3222
|
const targetDatasourceIds = datasourceIds && datasourceIds.length > 0 ? datasourceIds : metricsDataSource?.datasourceId ? [metricsDataSource.datasourceId] : client.getSelectedDataSources();
|
|
2893
3223
|
if (targetDatasourceIds.length === 0) {
|
|
2894
3224
|
return `Error: No data sources specified and no default data sources configured for server "${serverKey}".`;
|
|
@@ -2960,7 +3290,7 @@ ${serverKeys.map(
|
|
|
2960
3290
|
var import_zod13 = __toESM(require("zod"));
|
|
2961
3291
|
var import_langchain11 = require("langchain");
|
|
2962
3292
|
var QUERY_TABLE_DEFINITION_DESCRIPTION = `Get detailed definition and schema for a specific table from a semantic metrics server. Returns comprehensive information including column definitions, SQL query, and table relationships.`;
|
|
2963
|
-
var createQueryTableDefinitionTool = ({ serverKeys, serverDescriptions }) => {
|
|
3293
|
+
var createQueryTableDefinitionTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
2964
3294
|
const availableServersText = serverKeys.length > 0 ? `
|
|
2965
3295
|
|
|
2966
3296
|
Available metrics servers:
|
|
@@ -2974,24 +3304,30 @@ ${serverKeys.map(
|
|
|
2974
3304
|
datasourceId: inputDatasourceId
|
|
2975
3305
|
}, _exeConfig) => {
|
|
2976
3306
|
try {
|
|
3307
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
|
|
3308
|
+
let effectiveServerKeys = serverKeys;
|
|
3309
|
+
if (connectAll) {
|
|
3310
|
+
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
3311
|
+
}
|
|
3312
|
+
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
2977
3313
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
2978
3314
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
2979
3315
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
2980
3316
|
const datasourceId = inputDatasourceId || metricsDataSource?.datasourceId;
|
|
2981
3317
|
if (!serverKey) {
|
|
2982
|
-
return "Error: serverKey parameter is required. Available servers: " +
|
|
3318
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2983
3319
|
}
|
|
2984
|
-
if (!
|
|
2985
|
-
return `Error: serverKey "${serverKey}" is not
|
|
3320
|
+
if (!filteredServerKeys.includes(serverKey)) {
|
|
3321
|
+
return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
|
|
2986
3322
|
}
|
|
2987
3323
|
if (!tableName) {
|
|
2988
3324
|
return "Error: tableName parameter is required.";
|
|
2989
3325
|
}
|
|
2990
|
-
const config = metricsServerManager.getConfig(serverKey);
|
|
3326
|
+
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
2991
3327
|
if (config.type !== "semantic") {
|
|
2992
3328
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
2993
3329
|
}
|
|
2994
|
-
const client = metricsServerManager.getClient(serverKey);
|
|
3330
|
+
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
2995
3331
|
const targetDatasourceIds = datasourceId ? [datasourceId] : client.getSelectedDataSources();
|
|
2996
3332
|
if (targetDatasourceIds.length === 0) {
|
|
2997
3333
|
return `Error: No datasourceId specified and no default data sources configured for server "${serverKey}".`;
|
|
@@ -3092,7 +3428,7 @@ Example:
|
|
|
3092
3428
|
},
|
|
3093
3429
|
"limit": 100
|
|
3094
3430
|
}`;
|
|
3095
|
-
var createExecuteSqlQueryTool = ({ serverKeys, serverDescriptions }) => {
|
|
3431
|
+
var createExecuteSqlQueryTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
|
|
3096
3432
|
const availableServersText = serverKeys.length > 0 ? `
|
|
3097
3433
|
|
|
3098
3434
|
Available metrics servers:
|
|
@@ -3108,15 +3444,21 @@ ${serverKeys.map(
|
|
|
3108
3444
|
limit
|
|
3109
3445
|
}, _exeConfig) => {
|
|
3110
3446
|
try {
|
|
3447
|
+
const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
|
|
3448
|
+
let effectiveServerKeys = serverKeys;
|
|
3449
|
+
if (connectAll) {
|
|
3450
|
+
effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
|
|
3451
|
+
}
|
|
3452
|
+
const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
|
|
3111
3453
|
const runConfig = _exeConfig?.configurable?.runConfig || {};
|
|
3112
3454
|
const metricsDataSource = runConfig.metricsDataSource;
|
|
3113
3455
|
const serverKey = metricsDataSource?.serverKey || inputServerKey;
|
|
3114
3456
|
const datasourceId = metricsDataSource?.datasourceId || inputDatasourceId;
|
|
3115
3457
|
if (!serverKey) {
|
|
3116
|
-
return "Error: serverKey parameter is required. Available servers: " +
|
|
3458
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
3117
3459
|
}
|
|
3118
|
-
if (!
|
|
3119
|
-
return `Error: serverKey "${serverKey}" is not
|
|
3460
|
+
if (!filteredServerKeys.includes(serverKey)) {
|
|
3461
|
+
return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
|
|
3120
3462
|
}
|
|
3121
3463
|
if (!datasourceId) {
|
|
3122
3464
|
return "Error: datasourceId parameter is required.";
|
|
@@ -3124,11 +3466,11 @@ ${serverKeys.map(
|
|
|
3124
3466
|
if (!customSql || customSql.trim().length === 0) {
|
|
3125
3467
|
return "Error: customSql parameter is required and cannot be empty.";
|
|
3126
3468
|
}
|
|
3127
|
-
const config = metricsServerManager.getConfig(serverKey);
|
|
3469
|
+
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
3128
3470
|
if (config.type !== "semantic") {
|
|
3129
3471
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
3130
3472
|
}
|
|
3131
|
-
const client = metricsServerManager.getClient(serverKey);
|
|
3473
|
+
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
3132
3474
|
const result = await client.executeSqlQuery({
|
|
3133
3475
|
datasourceId,
|
|
3134
3476
|
customSql,
|
|
@@ -4876,104 +5218,137 @@ var import_langchain43 = require("langchain");
|
|
|
4876
5218
|
// src/store_lattice/InMemoryThreadStore.ts
|
|
4877
5219
|
var InMemoryThreadStore = class {
|
|
4878
5220
|
constructor() {
|
|
4879
|
-
// Map<assistantId, Map<threadId, Thread
|
|
5221
|
+
// Map<tenantId, Map<assistantId, Map<threadId, Thread>>>
|
|
4880
5222
|
this.threads = /* @__PURE__ */ new Map();
|
|
4881
5223
|
}
|
|
4882
5224
|
/**
|
|
4883
|
-
* Get all threads for a specific assistant
|
|
5225
|
+
* Get all threads for a specific tenant and assistant
|
|
4884
5226
|
*/
|
|
4885
|
-
async getThreadsByAssistantId(assistantId) {
|
|
4886
|
-
const
|
|
5227
|
+
async getThreadsByAssistantId(tenantId, assistantId) {
|
|
5228
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5229
|
+
if (!tenantThreads) {
|
|
5230
|
+
return [];
|
|
5231
|
+
}
|
|
5232
|
+
const assistantThreads = tenantThreads.get(assistantId);
|
|
4887
5233
|
if (!assistantThreads) {
|
|
4888
5234
|
return [];
|
|
4889
5235
|
}
|
|
4890
5236
|
return Array.from(assistantThreads.values());
|
|
4891
5237
|
}
|
|
4892
5238
|
/**
|
|
4893
|
-
* Get a thread by ID for a specific
|
|
5239
|
+
* Get a thread by ID for a specific tenant
|
|
4894
5240
|
*/
|
|
4895
|
-
async getThreadById(
|
|
4896
|
-
const
|
|
4897
|
-
if (!
|
|
5241
|
+
async getThreadById(tenantId, threadId) {
|
|
5242
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5243
|
+
if (!tenantThreads) {
|
|
4898
5244
|
return void 0;
|
|
4899
5245
|
}
|
|
4900
|
-
|
|
5246
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5247
|
+
const thread = assistantThreads.get(threadId);
|
|
5248
|
+
if (thread) {
|
|
5249
|
+
return thread;
|
|
5250
|
+
}
|
|
5251
|
+
}
|
|
5252
|
+
return void 0;
|
|
4901
5253
|
}
|
|
4902
5254
|
/**
|
|
4903
|
-
* Create a new thread for
|
|
5255
|
+
* Create a new thread for a tenant and assistant
|
|
4904
5256
|
*/
|
|
4905
|
-
async createThread(assistantId, threadId, data) {
|
|
5257
|
+
async createThread(tenantId, assistantId, threadId, data) {
|
|
4906
5258
|
const now = /* @__PURE__ */ new Date();
|
|
4907
5259
|
const thread = {
|
|
4908
5260
|
id: threadId,
|
|
5261
|
+
tenantId,
|
|
4909
5262
|
assistantId,
|
|
4910
5263
|
metadata: data.metadata || {},
|
|
4911
5264
|
createdAt: now,
|
|
4912
5265
|
updatedAt: now
|
|
4913
5266
|
};
|
|
4914
|
-
if (!this.threads.has(
|
|
4915
|
-
this.threads.set(
|
|
5267
|
+
if (!this.threads.has(tenantId)) {
|
|
5268
|
+
this.threads.set(tenantId, /* @__PURE__ */ new Map());
|
|
5269
|
+
}
|
|
5270
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5271
|
+
if (!tenantThreads.has(assistantId)) {
|
|
5272
|
+
tenantThreads.set(assistantId, /* @__PURE__ */ new Map());
|
|
4916
5273
|
}
|
|
4917
|
-
const assistantThreads =
|
|
5274
|
+
const assistantThreads = tenantThreads.get(assistantId);
|
|
4918
5275
|
assistantThreads.set(threadId, thread);
|
|
4919
5276
|
return thread;
|
|
4920
5277
|
}
|
|
4921
5278
|
/**
|
|
4922
5279
|
* Update an existing thread
|
|
4923
5280
|
*/
|
|
4924
|
-
async updateThread(
|
|
4925
|
-
const
|
|
4926
|
-
if (!
|
|
5281
|
+
async updateThread(tenantId, threadId, updates) {
|
|
5282
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5283
|
+
if (!tenantThreads) {
|
|
4927
5284
|
return null;
|
|
4928
5285
|
}
|
|
4929
|
-
const
|
|
4930
|
-
|
|
4931
|
-
|
|
5286
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5287
|
+
const existing = assistantThreads.get(threadId);
|
|
5288
|
+
if (existing) {
|
|
5289
|
+
const updated = {
|
|
5290
|
+
...existing,
|
|
5291
|
+
metadata: {
|
|
5292
|
+
...existing.metadata,
|
|
5293
|
+
...updates.metadata || {}
|
|
5294
|
+
},
|
|
5295
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
5296
|
+
};
|
|
5297
|
+
assistantThreads.set(threadId, updated);
|
|
5298
|
+
return updated;
|
|
5299
|
+
}
|
|
4932
5300
|
}
|
|
4933
|
-
|
|
4934
|
-
...existing,
|
|
4935
|
-
metadata: {
|
|
4936
|
-
...existing.metadata,
|
|
4937
|
-
...updates.metadata || {}
|
|
4938
|
-
},
|
|
4939
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
4940
|
-
};
|
|
4941
|
-
assistantThreads.set(threadId, updated);
|
|
4942
|
-
return updated;
|
|
5301
|
+
return null;
|
|
4943
5302
|
}
|
|
4944
5303
|
/**
|
|
4945
5304
|
* Delete a thread by ID
|
|
4946
5305
|
*/
|
|
4947
|
-
async deleteThread(
|
|
4948
|
-
const
|
|
4949
|
-
if (!
|
|
5306
|
+
async deleteThread(tenantId, threadId) {
|
|
5307
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5308
|
+
if (!tenantThreads) {
|
|
4950
5309
|
return false;
|
|
4951
5310
|
}
|
|
4952
|
-
|
|
5311
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5312
|
+
if (assistantThreads.has(threadId)) {
|
|
5313
|
+
return assistantThreads.delete(threadId);
|
|
5314
|
+
}
|
|
5315
|
+
}
|
|
5316
|
+
return false;
|
|
4953
5317
|
}
|
|
4954
5318
|
/**
|
|
4955
5319
|
* Check if thread exists
|
|
4956
5320
|
*/
|
|
4957
|
-
async hasThread(
|
|
4958
|
-
const
|
|
4959
|
-
if (!
|
|
5321
|
+
async hasThread(tenantId, threadId) {
|
|
5322
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5323
|
+
if (!tenantThreads) {
|
|
4960
5324
|
return false;
|
|
4961
5325
|
}
|
|
4962
|
-
|
|
5326
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5327
|
+
if (assistantThreads.has(threadId)) {
|
|
5328
|
+
return true;
|
|
5329
|
+
}
|
|
5330
|
+
}
|
|
5331
|
+
return false;
|
|
4963
5332
|
}
|
|
4964
5333
|
/**
|
|
4965
|
-
* Clear all threads (useful for testing)
|
|
5334
|
+
* Clear all threads for a tenant (useful for testing)
|
|
4966
5335
|
*/
|
|
4967
|
-
clear() {
|
|
4968
|
-
|
|
5336
|
+
clear(tenantId) {
|
|
5337
|
+
if (tenantId) {
|
|
5338
|
+
this.threads.delete(tenantId);
|
|
5339
|
+
} else {
|
|
5340
|
+
this.threads.clear();
|
|
5341
|
+
}
|
|
4969
5342
|
}
|
|
4970
5343
|
/**
|
|
4971
5344
|
* Get all threads for all assistants (useful for debugging)
|
|
4972
5345
|
*/
|
|
4973
5346
|
getAllThreads() {
|
|
4974
5347
|
const allThreads = [];
|
|
4975
|
-
for (const
|
|
4976
|
-
|
|
5348
|
+
for (const tenantThreads of this.threads.values()) {
|
|
5349
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5350
|
+
allThreads.push(...Array.from(assistantThreads.values()));
|
|
5351
|
+
}
|
|
4977
5352
|
}
|
|
4978
5353
|
return allThreads;
|
|
4979
5354
|
}
|
|
@@ -4985,38 +5360,50 @@ var InMemoryAssistantStore = class {
|
|
|
4985
5360
|
this.assistants = /* @__PURE__ */ new Map();
|
|
4986
5361
|
}
|
|
4987
5362
|
/**
|
|
4988
|
-
* Get all assistants
|
|
5363
|
+
* Get all assistants for a tenant
|
|
4989
5364
|
*/
|
|
4990
|
-
async getAllAssistants() {
|
|
4991
|
-
|
|
5365
|
+
async getAllAssistants(tenantId) {
|
|
5366
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5367
|
+
if (!tenantAssistants) return [];
|
|
5368
|
+
return Array.from(tenantAssistants.values());
|
|
4992
5369
|
}
|
|
4993
5370
|
/**
|
|
4994
5371
|
* Get assistant by ID
|
|
4995
5372
|
*/
|
|
4996
|
-
async getAssistantById(id) {
|
|
4997
|
-
|
|
5373
|
+
async getAssistantById(tenantId, id) {
|
|
5374
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5375
|
+
if (!tenantAssistants) return null;
|
|
5376
|
+
return tenantAssistants.get(id) || null;
|
|
4998
5377
|
}
|
|
4999
5378
|
/**
|
|
5000
5379
|
* Create a new assistant
|
|
5001
5380
|
*/
|
|
5002
|
-
async createAssistant(id, data) {
|
|
5381
|
+
async createAssistant(tenantId, id, data) {
|
|
5382
|
+
if (!this.assistants.has(tenantId)) {
|
|
5383
|
+
this.assistants.set(tenantId, /* @__PURE__ */ new Map());
|
|
5384
|
+
}
|
|
5003
5385
|
const now = /* @__PURE__ */ new Date();
|
|
5004
5386
|
const assistant = {
|
|
5005
5387
|
id,
|
|
5388
|
+
tenantId,
|
|
5006
5389
|
name: data.name,
|
|
5007
5390
|
description: data.description,
|
|
5008
5391
|
graphDefinition: data.graphDefinition,
|
|
5009
5392
|
createdAt: now,
|
|
5010
5393
|
updatedAt: now
|
|
5011
5394
|
};
|
|
5012
|
-
this.assistants.set(id, assistant);
|
|
5395
|
+
this.assistants.get(tenantId).set(id, assistant);
|
|
5013
5396
|
return assistant;
|
|
5014
5397
|
}
|
|
5015
5398
|
/**
|
|
5016
5399
|
* Update an existing assistant
|
|
5017
5400
|
*/
|
|
5018
|
-
async updateAssistant(id, updates) {
|
|
5019
|
-
const
|
|
5401
|
+
async updateAssistant(tenantId, id, updates) {
|
|
5402
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5403
|
+
if (!tenantAssistants) {
|
|
5404
|
+
return null;
|
|
5405
|
+
}
|
|
5406
|
+
const existing = tenantAssistants.get(id);
|
|
5020
5407
|
if (!existing) {
|
|
5021
5408
|
return null;
|
|
5022
5409
|
}
|
|
@@ -5025,26 +5412,38 @@ var InMemoryAssistantStore = class {
|
|
|
5025
5412
|
...updates,
|
|
5026
5413
|
updatedAt: /* @__PURE__ */ new Date()
|
|
5027
5414
|
};
|
|
5028
|
-
|
|
5415
|
+
tenantAssistants.set(id, updated);
|
|
5029
5416
|
return updated;
|
|
5030
5417
|
}
|
|
5031
5418
|
/**
|
|
5032
5419
|
* Delete an assistant by ID
|
|
5033
5420
|
*/
|
|
5034
|
-
async deleteAssistant(id) {
|
|
5035
|
-
|
|
5421
|
+
async deleteAssistant(tenantId, id) {
|
|
5422
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5423
|
+
if (!tenantAssistants) {
|
|
5424
|
+
return false;
|
|
5425
|
+
}
|
|
5426
|
+
return tenantAssistants.delete(id);
|
|
5036
5427
|
}
|
|
5037
5428
|
/**
|
|
5038
5429
|
* Check if assistant exists
|
|
5039
5430
|
*/
|
|
5040
|
-
async hasAssistant(id) {
|
|
5041
|
-
|
|
5431
|
+
async hasAssistant(tenantId, id) {
|
|
5432
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5433
|
+
if (!tenantAssistants) {
|
|
5434
|
+
return false;
|
|
5435
|
+
}
|
|
5436
|
+
return tenantAssistants.has(id);
|
|
5042
5437
|
}
|
|
5043
5438
|
/**
|
|
5044
|
-
* Clear all assistants (useful for testing)
|
|
5439
|
+
* Clear all assistants for a tenant (useful for testing)
|
|
5045
5440
|
*/
|
|
5046
|
-
clear() {
|
|
5047
|
-
|
|
5441
|
+
clear(tenantId) {
|
|
5442
|
+
if (tenantId) {
|
|
5443
|
+
this.assistants.delete(tenantId);
|
|
5444
|
+
} else {
|
|
5445
|
+
this.assistants.clear();
|
|
5446
|
+
}
|
|
5048
5447
|
}
|
|
5049
5448
|
};
|
|
5050
5449
|
|
|
@@ -5290,6 +5689,8 @@ var FileSystemSkillStore = class {
|
|
|
5290
5689
|
return {
|
|
5291
5690
|
id: name,
|
|
5292
5691
|
// id equals name (name is used for path addressing)
|
|
5692
|
+
tenantId: "default",
|
|
5693
|
+
// FileSystemSkillStore uses default tenant
|
|
5293
5694
|
name: frontmatter.name,
|
|
5294
5695
|
description: frontmatter.description,
|
|
5295
5696
|
license: frontmatter.license,
|
|
@@ -5337,9 +5738,11 @@ ${body}` : `${frontmatter}
|
|
|
5337
5738
|
await fs.writeFile(filePath, content, "utf-8");
|
|
5338
5739
|
}
|
|
5339
5740
|
/**
|
|
5340
|
-
* Get all skills
|
|
5741
|
+
* Get all skills for a tenant
|
|
5742
|
+
* Note: FileSystemSkillStore uses a flat structure. TenantId is accepted for protocol compliance
|
|
5743
|
+
* but all skills are returned regardless of tenant.
|
|
5341
5744
|
*/
|
|
5342
|
-
async getAllSkills() {
|
|
5745
|
+
async getAllSkills(_tenantId) {
|
|
5343
5746
|
await this.ensureDirectoryExists();
|
|
5344
5747
|
try {
|
|
5345
5748
|
const entries = await fs.readdir(this.rootDir, { withFileTypes: true });
|
|
@@ -5376,17 +5779,19 @@ ${body}` : `${frontmatter}
|
|
|
5376
5779
|
}
|
|
5377
5780
|
}
|
|
5378
5781
|
/**
|
|
5379
|
-
* Get skill by ID
|
|
5782
|
+
* Get skill by ID for a tenant
|
|
5380
5783
|
* ID should equal name (name is used for path addressing)
|
|
5784
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5381
5785
|
*/
|
|
5382
|
-
async getSkillById(id) {
|
|
5786
|
+
async getSkillById(_tenantId, id) {
|
|
5383
5787
|
return this.readSkillFile(id);
|
|
5384
5788
|
}
|
|
5385
5789
|
/**
|
|
5386
|
-
* Create a new skill
|
|
5790
|
+
* Create a new skill for a tenant
|
|
5387
5791
|
* id should equal name (name is used for path addressing)
|
|
5792
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5388
5793
|
*/
|
|
5389
|
-
async createSkill(id, data) {
|
|
5794
|
+
async createSkill(_tenantId, id, data) {
|
|
5390
5795
|
await this.ensureDirectoryExists();
|
|
5391
5796
|
validateSkillName(data.name);
|
|
5392
5797
|
if (id !== data.name) {
|
|
@@ -5394,14 +5799,15 @@ ${body}` : `${frontmatter}
|
|
|
5394
5799
|
`Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
|
|
5395
5800
|
);
|
|
5396
5801
|
}
|
|
5397
|
-
const existing = await this.getSkillById(id);
|
|
5802
|
+
const existing = await this.getSkillById(_tenantId, id);
|
|
5398
5803
|
if (existing) {
|
|
5399
|
-
return this.updateSkill(id, data);
|
|
5804
|
+
return this.updateSkill(_tenantId, id, data);
|
|
5400
5805
|
}
|
|
5401
5806
|
const now = /* @__PURE__ */ new Date();
|
|
5402
5807
|
const skill = {
|
|
5403
5808
|
id: data.name,
|
|
5404
5809
|
// id equals name
|
|
5810
|
+
tenantId: _tenantId,
|
|
5405
5811
|
name: data.name,
|
|
5406
5812
|
description: data.description,
|
|
5407
5813
|
license: data.license,
|
|
@@ -5416,9 +5822,10 @@ ${body}` : `${frontmatter}
|
|
|
5416
5822
|
return skill;
|
|
5417
5823
|
}
|
|
5418
5824
|
/**
|
|
5419
|
-
* Update an existing skill
|
|
5825
|
+
* Update an existing skill for a tenant
|
|
5826
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5420
5827
|
*/
|
|
5421
|
-
async updateSkill(id, updates) {
|
|
5828
|
+
async updateSkill(_tenantId, id, updates) {
|
|
5422
5829
|
const skill = await this.readSkillFile(id);
|
|
5423
5830
|
if (!skill) {
|
|
5424
5831
|
return null;
|
|
@@ -5442,6 +5849,7 @@ ${body}` : `${frontmatter}
|
|
|
5442
5849
|
name: updates.name ?? skill.name,
|
|
5443
5850
|
id: updates.name ?? skill.id,
|
|
5444
5851
|
// id equals name
|
|
5852
|
+
tenantId: _tenantId,
|
|
5445
5853
|
description: updates.description ?? skill.description,
|
|
5446
5854
|
license: updates.license ?? skill.license,
|
|
5447
5855
|
compatibility: updates.compatibility ?? skill.compatibility,
|
|
@@ -5454,10 +5862,11 @@ ${body}` : `${frontmatter}
|
|
|
5454
5862
|
return updatedSkill;
|
|
5455
5863
|
}
|
|
5456
5864
|
/**
|
|
5457
|
-
* Delete a skill by ID
|
|
5865
|
+
* Delete a skill by ID for a tenant
|
|
5458
5866
|
* Deletes the entire directory (name is the directory name)
|
|
5867
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5459
5868
|
*/
|
|
5460
|
-
async deleteSkill(id) {
|
|
5869
|
+
async deleteSkill(_tenantId, id) {
|
|
5461
5870
|
await this.ensureDirectoryExists();
|
|
5462
5871
|
const skillDir = this.getSkillDirectoryPath(id);
|
|
5463
5872
|
try {
|
|
@@ -5471,50 +5880,55 @@ ${body}` : `${frontmatter}
|
|
|
5471
5880
|
}
|
|
5472
5881
|
}
|
|
5473
5882
|
/**
|
|
5474
|
-
* Check if skill exists
|
|
5883
|
+
* Check if skill exists for a tenant
|
|
5884
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5475
5885
|
*/
|
|
5476
|
-
async hasSkill(id) {
|
|
5477
|
-
const skill = await this.getSkillById(id);
|
|
5886
|
+
async hasSkill(_tenantId, id) {
|
|
5887
|
+
const skill = await this.getSkillById(_tenantId, id);
|
|
5478
5888
|
return skill !== null;
|
|
5479
5889
|
}
|
|
5480
5890
|
/**
|
|
5481
|
-
* Search skills by metadata
|
|
5891
|
+
* Search skills by metadata within a tenant
|
|
5892
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5482
5893
|
*/
|
|
5483
|
-
async searchByMetadata(metadataKey, metadataValue) {
|
|
5484
|
-
const allSkills = await this.getAllSkills();
|
|
5894
|
+
async searchByMetadata(_tenantId, metadataKey, metadataValue) {
|
|
5895
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5485
5896
|
return allSkills.filter((skill) => {
|
|
5486
5897
|
return skill.metadata && skill.metadata[metadataKey] === metadataValue;
|
|
5487
5898
|
});
|
|
5488
5899
|
}
|
|
5489
5900
|
/**
|
|
5490
|
-
* Filter skills by compatibility
|
|
5901
|
+
* Filter skills by compatibility within a tenant
|
|
5902
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5491
5903
|
*/
|
|
5492
|
-
async filterByCompatibility(compatibility) {
|
|
5493
|
-
const allSkills = await this.getAllSkills();
|
|
5904
|
+
async filterByCompatibility(_tenantId, compatibility) {
|
|
5905
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5494
5906
|
return allSkills.filter((skill) => {
|
|
5495
5907
|
return skill.compatibility === compatibility;
|
|
5496
5908
|
});
|
|
5497
5909
|
}
|
|
5498
5910
|
/**
|
|
5499
|
-
* Filter skills by license
|
|
5911
|
+
* Filter skills by license within a tenant
|
|
5912
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5500
5913
|
*/
|
|
5501
|
-
async filterByLicense(license) {
|
|
5502
|
-
const allSkills = await this.getAllSkills();
|
|
5914
|
+
async filterByLicense(_tenantId, license) {
|
|
5915
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5503
5916
|
return allSkills.filter((skill) => {
|
|
5504
5917
|
return skill.license === license;
|
|
5505
5918
|
});
|
|
5506
5919
|
}
|
|
5507
5920
|
/**
|
|
5508
|
-
* Get sub-skills of a parent skill
|
|
5921
|
+
* Get sub-skills of a parent skill within a tenant
|
|
5922
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5509
5923
|
*/
|
|
5510
|
-
async getSubSkills(parentSkillName) {
|
|
5511
|
-
const parentSkill = await this.getSkillById(parentSkillName);
|
|
5924
|
+
async getSubSkills(_tenantId, parentSkillName) {
|
|
5925
|
+
const parentSkill = await this.getSkillById(_tenantId, parentSkillName);
|
|
5512
5926
|
if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
|
|
5513
5927
|
return [];
|
|
5514
5928
|
}
|
|
5515
5929
|
const subSkills = [];
|
|
5516
5930
|
for (const subSkillName of parentSkill.subSkills) {
|
|
5517
|
-
const subSkill = await this.getSkillById(subSkillName);
|
|
5931
|
+
const subSkill = await this.getSkillById(_tenantId, subSkillName);
|
|
5518
5932
|
if (subSkill) {
|
|
5519
5933
|
subSkills.push(subSkill);
|
|
5520
5934
|
}
|
|
@@ -5523,10 +5937,11 @@ ${body}` : `${frontmatter}
|
|
|
5523
5937
|
}
|
|
5524
5938
|
/**
|
|
5525
5939
|
* List all resources in a skill's resources directory
|
|
5940
|
+
* @param tenantId The tenant identifier (accepted for protocol compliance)
|
|
5526
5941
|
* @param skillName The skill name
|
|
5527
5942
|
* @returns Array of resource paths relative to resources/ directory
|
|
5528
5943
|
*/
|
|
5529
|
-
async listSkillResources(skillName) {
|
|
5944
|
+
async listSkillResources(_tenantId, skillName) {
|
|
5530
5945
|
const skillDir = this.getSkillDirectoryPath(skillName);
|
|
5531
5946
|
const resourcesDir = path3.join(skillDir, "resources");
|
|
5532
5947
|
try {
|
|
@@ -5549,11 +5964,12 @@ ${body}` : `${frontmatter}
|
|
|
5549
5964
|
}
|
|
5550
5965
|
/**
|
|
5551
5966
|
* Load a specific resource from a skill's resources directory
|
|
5967
|
+
* @param tenantId The tenant identifier (accepted for protocol compliance)
|
|
5552
5968
|
* @param skillName The skill name
|
|
5553
5969
|
* @param resourcePath Path to the resource relative to resources/ directory
|
|
5554
5970
|
* @returns The resource content as string
|
|
5555
5971
|
*/
|
|
5556
|
-
async loadSkillResource(skillName, resourcePath) {
|
|
5972
|
+
async loadSkillResource(_tenantId, skillName, resourcePath) {
|
|
5557
5973
|
const skillDir = this.getSkillDirectoryPath(skillName);
|
|
5558
5974
|
const resourcesDir = path3.join(skillDir, "resources");
|
|
5559
5975
|
const fullPath = path3.join(resourcesDir, resourcePath);
|
|
@@ -6290,93 +6706,520 @@ var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager
|
|
|
6290
6706
|
return storeLattice;
|
|
6291
6707
|
}
|
|
6292
6708
|
/**
|
|
6293
|
-
* Get StoreLattice without type checking (for backward compatibility)
|
|
6294
|
-
* @param key Lattice key name
|
|
6295
|
-
* @param type Store type
|
|
6296
|
-
* @returns StoreLattice (type may be unknown)
|
|
6709
|
+
* Get StoreLattice without type checking (for backward compatibility)
|
|
6710
|
+
* @param key Lattice key name
|
|
6711
|
+
* @param type Store type
|
|
6712
|
+
* @returns StoreLattice (type may be unknown)
|
|
6713
|
+
*/
|
|
6714
|
+
getStoreLatticeUnsafe(key, type) {
|
|
6715
|
+
const compositeKey = this.getCompositeKey(key, type);
|
|
6716
|
+
const storeLattice = this.get(compositeKey);
|
|
6717
|
+
if (!storeLattice) {
|
|
6718
|
+
throw new Error(`StoreLattice ${key}:${type} not found`);
|
|
6719
|
+
}
|
|
6720
|
+
return storeLattice;
|
|
6721
|
+
}
|
|
6722
|
+
/**
|
|
6723
|
+
* Get all Lattices
|
|
6724
|
+
*/
|
|
6725
|
+
getAllLattices() {
|
|
6726
|
+
return this.getAll();
|
|
6727
|
+
}
|
|
6728
|
+
/**
|
|
6729
|
+
* Check if Lattice exists
|
|
6730
|
+
* Uses composite key (key + type) to check existence
|
|
6731
|
+
* @param key Lattice key name
|
|
6732
|
+
* @param type Store type
|
|
6733
|
+
*/
|
|
6734
|
+
hasLattice(key, type) {
|
|
6735
|
+
const compositeKey = this.getCompositeKey(key, type);
|
|
6736
|
+
return this.has(compositeKey);
|
|
6737
|
+
}
|
|
6738
|
+
/**
|
|
6739
|
+
* Remove Lattice
|
|
6740
|
+
* Uses composite key (key + type) to remove the store
|
|
6741
|
+
* @param key Lattice key name
|
|
6742
|
+
* @param type Store type
|
|
6743
|
+
*/
|
|
6744
|
+
removeLattice(key, type) {
|
|
6745
|
+
const compositeKey = this.getCompositeKey(key, type);
|
|
6746
|
+
return this.remove(compositeKey);
|
|
6747
|
+
}
|
|
6748
|
+
/**
|
|
6749
|
+
* Clear all Lattices
|
|
6750
|
+
*/
|
|
6751
|
+
clearLattices() {
|
|
6752
|
+
this.clear();
|
|
6753
|
+
}
|
|
6754
|
+
/**
|
|
6755
|
+
* Get Lattice count
|
|
6756
|
+
*/
|
|
6757
|
+
getLatticeCount() {
|
|
6758
|
+
return this.count();
|
|
6759
|
+
}
|
|
6760
|
+
/**
|
|
6761
|
+
* Get Lattice key list
|
|
6762
|
+
*/
|
|
6763
|
+
getLatticeKeys() {
|
|
6764
|
+
return this.keys();
|
|
6765
|
+
}
|
|
6766
|
+
};
|
|
6767
|
+
var storeLatticeManager = StoreLatticeManager.getInstance();
|
|
6768
|
+
var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
|
|
6769
|
+
var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
|
|
6770
|
+
var defaultThreadStore = new InMemoryThreadStore();
|
|
6771
|
+
var defaultAssistantStore = new InMemoryAssistantStore();
|
|
6772
|
+
var defaultSkillStore = new FileSystemSkillStore();
|
|
6773
|
+
var defaultWorkspaceStore = new InMemoryWorkspaceStore();
|
|
6774
|
+
var defaultProjectStore = new InMemoryProjectStore();
|
|
6775
|
+
var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
|
|
6776
|
+
var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
|
|
6777
|
+
var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
|
|
6778
|
+
storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
|
|
6779
|
+
storeLatticeManager.registerLattice(
|
|
6780
|
+
"default",
|
|
6781
|
+
"assistant",
|
|
6782
|
+
defaultAssistantStore
|
|
6783
|
+
);
|
|
6784
|
+
storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
|
|
6785
|
+
storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
|
|
6786
|
+
storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
|
|
6787
|
+
storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
|
|
6788
|
+
storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
|
|
6789
|
+
storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
|
|
6790
|
+
var defaultUserStore = new InMemoryUserStore();
|
|
6791
|
+
var defaultTenantStore = new InMemoryTenantStore();
|
|
6792
|
+
var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
|
|
6793
|
+
storeLatticeManager.registerLattice("default", "user", defaultUserStore);
|
|
6794
|
+
storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
|
|
6795
|
+
storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
|
|
6796
|
+
|
|
6797
|
+
// src/store_lattice/SandboxSkillStore.ts
|
|
6798
|
+
function parseFrontmatter2(content) {
|
|
6799
|
+
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
|
|
6800
|
+
const match = content.match(frontmatterRegex);
|
|
6801
|
+
if (!match) {
|
|
6802
|
+
return { frontmatter: {}, body: content };
|
|
6803
|
+
}
|
|
6804
|
+
const frontmatterText = match[1];
|
|
6805
|
+
const body = match[2] || "";
|
|
6806
|
+
const frontmatter = {};
|
|
6807
|
+
const lines = frontmatterText.split("\n");
|
|
6808
|
+
let currentKey = null;
|
|
6809
|
+
let metadataIndent = 0;
|
|
6810
|
+
for (let i = 0; i < lines.length; i++) {
|
|
6811
|
+
const line = lines[i];
|
|
6812
|
+
const trimmed = line.trim();
|
|
6813
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
6814
|
+
continue;
|
|
6815
|
+
}
|
|
6816
|
+
const indentMatch = line.match(/^(\s*)/);
|
|
6817
|
+
const indent = indentMatch ? indentMatch[1].length : 0;
|
|
6818
|
+
if (currentKey === "metadata" && indent > metadataIndent) {
|
|
6819
|
+
const colonIndex2 = trimmed.indexOf(":");
|
|
6820
|
+
if (colonIndex2 !== -1) {
|
|
6821
|
+
const key2 = trimmed.substring(0, colonIndex2).trim();
|
|
6822
|
+
let value2 = trimmed.substring(colonIndex2 + 1).trim();
|
|
6823
|
+
if (value2.startsWith('"') && value2.endsWith('"') || value2.startsWith("'") && value2.endsWith("'")) {
|
|
6824
|
+
value2 = value2.slice(1, -1);
|
|
6825
|
+
}
|
|
6826
|
+
if (!frontmatter.metadata) {
|
|
6827
|
+
frontmatter.metadata = {};
|
|
6828
|
+
}
|
|
6829
|
+
frontmatter.metadata[key2] = value2;
|
|
6830
|
+
}
|
|
6831
|
+
continue;
|
|
6832
|
+
}
|
|
6833
|
+
if (currentKey === "subSkills" && indent > metadataIndent) {
|
|
6834
|
+
if (trimmed.startsWith("-")) {
|
|
6835
|
+
let value2 = trimmed.substring(1).trim();
|
|
6836
|
+
if (value2.startsWith('"') && value2.endsWith('"') || value2.startsWith("'") && value2.endsWith("'")) {
|
|
6837
|
+
value2 = value2.slice(1, -1);
|
|
6838
|
+
}
|
|
6839
|
+
if (!frontmatter.subSkills) {
|
|
6840
|
+
frontmatter.subSkills = [];
|
|
6841
|
+
}
|
|
6842
|
+
frontmatter.subSkills.push(value2);
|
|
6843
|
+
}
|
|
6844
|
+
continue;
|
|
6845
|
+
}
|
|
6846
|
+
if ((currentKey === "metadata" || currentKey === "subSkills") && indent <= metadataIndent) {
|
|
6847
|
+
currentKey = null;
|
|
6848
|
+
metadataIndent = 0;
|
|
6849
|
+
}
|
|
6850
|
+
const colonIndex = trimmed.indexOf(":");
|
|
6851
|
+
if (colonIndex === -1) {
|
|
6852
|
+
continue;
|
|
6853
|
+
}
|
|
6854
|
+
const key = trimmed.substring(0, colonIndex).trim();
|
|
6855
|
+
let value = trimmed.substring(colonIndex + 1).trim();
|
|
6856
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
6857
|
+
value = value.slice(1, -1);
|
|
6858
|
+
}
|
|
6859
|
+
if (key === "metadata") {
|
|
6860
|
+
if (value === "" || value === "{}") {
|
|
6861
|
+
if (i + 1 < lines.length) {
|
|
6862
|
+
const nextLine = lines[i + 1];
|
|
6863
|
+
const nextIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;
|
|
6864
|
+
if (nextIndent > indent) {
|
|
6865
|
+
currentKey = "metadata";
|
|
6866
|
+
metadataIndent = indent;
|
|
6867
|
+
frontmatter.metadata = {};
|
|
6868
|
+
continue;
|
|
6869
|
+
}
|
|
6870
|
+
}
|
|
6871
|
+
frontmatter[key] = {};
|
|
6872
|
+
} else if (value.startsWith("{")) {
|
|
6873
|
+
try {
|
|
6874
|
+
frontmatter[key] = JSON.parse(value);
|
|
6875
|
+
} catch {
|
|
6876
|
+
frontmatter[key] = {};
|
|
6877
|
+
}
|
|
6878
|
+
} else {
|
|
6879
|
+
frontmatter[key] = {};
|
|
6880
|
+
}
|
|
6881
|
+
} else if (key === "subSkills") {
|
|
6882
|
+
if (value === "" || value === "[]") {
|
|
6883
|
+
if (i + 1 < lines.length) {
|
|
6884
|
+
const nextLine = lines[i + 1];
|
|
6885
|
+
const nextIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;
|
|
6886
|
+
if (nextIndent > indent && nextLine.trim().startsWith("-")) {
|
|
6887
|
+
currentKey = "subSkills";
|
|
6888
|
+
metadataIndent = indent;
|
|
6889
|
+
frontmatter.subSkills = [];
|
|
6890
|
+
continue;
|
|
6891
|
+
}
|
|
6892
|
+
}
|
|
6893
|
+
frontmatter[key] = [];
|
|
6894
|
+
} else if (value.startsWith("[")) {
|
|
6895
|
+
try {
|
|
6896
|
+
frontmatter[key] = JSON.parse(value);
|
|
6897
|
+
} catch {
|
|
6898
|
+
frontmatter[key] = [];
|
|
6899
|
+
}
|
|
6900
|
+
} else {
|
|
6901
|
+
frontmatter[key] = [];
|
|
6902
|
+
}
|
|
6903
|
+
} else {
|
|
6904
|
+
frontmatter[key] = value;
|
|
6905
|
+
}
|
|
6906
|
+
}
|
|
6907
|
+
return { frontmatter, body };
|
|
6908
|
+
}
|
|
6909
|
+
function generateFrontmatter2(data) {
|
|
6910
|
+
const lines = ["---"];
|
|
6911
|
+
lines.push(`name: ${data.name}`);
|
|
6912
|
+
lines.push(`description: ${data.description}`);
|
|
6913
|
+
if (data.license) {
|
|
6914
|
+
lines.push(`license: ${data.license}`);
|
|
6915
|
+
}
|
|
6916
|
+
if (data.compatibility) {
|
|
6917
|
+
lines.push(`compatibility: ${data.compatibility}`);
|
|
6918
|
+
}
|
|
6919
|
+
if (data.metadata && Object.keys(data.metadata).length > 0) {
|
|
6920
|
+
lines.push("metadata:");
|
|
6921
|
+
for (const [key, value] of Object.entries(data.metadata)) {
|
|
6922
|
+
lines.push(` ${key}: ${value}`);
|
|
6923
|
+
}
|
|
6924
|
+
}
|
|
6925
|
+
if (data.subSkills && data.subSkills.length > 0) {
|
|
6926
|
+
lines.push("subSkills:");
|
|
6927
|
+
for (const subSkill of data.subSkills) {
|
|
6928
|
+
lines.push(` - ${subSkill}`);
|
|
6929
|
+
}
|
|
6930
|
+
}
|
|
6931
|
+
lines.push("---");
|
|
6932
|
+
return lines.join("\n");
|
|
6933
|
+
}
|
|
6934
|
+
var SandboxSkillStore = class {
|
|
6935
|
+
constructor(options = {}) {
|
|
6936
|
+
this.sandboxManager = options.sandboxManager;
|
|
6937
|
+
this.basePath = options.basePath || "/home/gem/tenants";
|
|
6938
|
+
}
|
|
6939
|
+
/**
|
|
6940
|
+
* Get sandbox manager for a tenant
|
|
6941
|
+
*/
|
|
6942
|
+
async getSandboxManager() {
|
|
6943
|
+
if (this.sandboxManager) {
|
|
6944
|
+
return this.sandboxManager;
|
|
6945
|
+
}
|
|
6946
|
+
return getSandBoxManager();
|
|
6947
|
+
}
|
|
6948
|
+
/**
|
|
6949
|
+
* Get skill directory path in sandbox
|
|
6950
|
+
*/
|
|
6951
|
+
getSkillDirectoryPath(tenantId, name) {
|
|
6952
|
+
if (name.includes("..") || name.includes("/") || name.includes("\\")) {
|
|
6953
|
+
throw new Error(`Invalid skill name: ${name} (contains invalid characters)`);
|
|
6954
|
+
}
|
|
6955
|
+
return `${this.basePath}/${tenantId}/skills/${name}`;
|
|
6956
|
+
}
|
|
6957
|
+
/**
|
|
6958
|
+
* Get skill file path in sandbox
|
|
6959
|
+
*/
|
|
6960
|
+
getSkillFilePath(tenantId, name) {
|
|
6961
|
+
return `${this.getSkillDirectoryPath(tenantId, name)}/SKILL.md`;
|
|
6962
|
+
}
|
|
6963
|
+
/**
|
|
6964
|
+
* Read skill from sandbox
|
|
6965
|
+
*/
|
|
6966
|
+
async readSkillFile(tenantId, name) {
|
|
6967
|
+
try {
|
|
6968
|
+
const sandboxManager = await this.getSandboxManager();
|
|
6969
|
+
const sandbox = await sandboxManager.createSandbox("global");
|
|
6970
|
+
const filePath = this.getSkillFilePath(tenantId, name);
|
|
6971
|
+
const result = await sandbox.file.readFile({ file: filePath });
|
|
6972
|
+
if (!result.ok) {
|
|
6973
|
+
return null;
|
|
6974
|
+
}
|
|
6975
|
+
let content;
|
|
6976
|
+
if (typeof result.body === "string") {
|
|
6977
|
+
content = result.body;
|
|
6978
|
+
} else if (result.body && typeof result.body === "object") {
|
|
6979
|
+
const body = result.body;
|
|
6980
|
+
content = body.content || body.data?.content || JSON.stringify(body);
|
|
6981
|
+
} else {
|
|
6982
|
+
content = String(result.body);
|
|
6983
|
+
}
|
|
6984
|
+
const { frontmatter, body: skillBody } = parseFrontmatter2(content);
|
|
6985
|
+
if (!frontmatter.name || !frontmatter.description) {
|
|
6986
|
+
console.warn(`Invalid skill file ${name}: missing required fields`);
|
|
6987
|
+
return null;
|
|
6988
|
+
}
|
|
6989
|
+
return {
|
|
6990
|
+
id: name,
|
|
6991
|
+
tenantId,
|
|
6992
|
+
name: frontmatter.name,
|
|
6993
|
+
description: frontmatter.description,
|
|
6994
|
+
license: frontmatter.license,
|
|
6995
|
+
compatibility: frontmatter.compatibility,
|
|
6996
|
+
metadata: frontmatter.metadata || {},
|
|
6997
|
+
content: skillBody.trim() || void 0,
|
|
6998
|
+
subSkills: Array.isArray(frontmatter.subSkills) ? frontmatter.subSkills : void 0,
|
|
6999
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
7000
|
+
// Sandbox doesn't provide file stats easily
|
|
7001
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7002
|
+
};
|
|
7003
|
+
} catch (error) {
|
|
7004
|
+
console.error(`Error reading skill ${name} from sandbox:`, error);
|
|
7005
|
+
return null;
|
|
7006
|
+
}
|
|
7007
|
+
}
|
|
7008
|
+
/**
|
|
7009
|
+
* Write skill to sandbox
|
|
7010
|
+
*/
|
|
7011
|
+
async writeSkillFile(skill) {
|
|
7012
|
+
const sandboxManager = await this.getSandboxManager();
|
|
7013
|
+
const sandbox = await sandboxManager.createSandbox("global");
|
|
7014
|
+
const filePath = this.getSkillFilePath(skill.tenantId, skill.name);
|
|
7015
|
+
const frontmatter = generateFrontmatter2({
|
|
7016
|
+
name: skill.name,
|
|
7017
|
+
description: skill.description,
|
|
7018
|
+
license: skill.license,
|
|
7019
|
+
compatibility: skill.compatibility,
|
|
7020
|
+
metadata: skill.metadata,
|
|
7021
|
+
subSkills: skill.subSkills
|
|
7022
|
+
});
|
|
7023
|
+
const body = skill.content || "";
|
|
7024
|
+
const content = body ? `${frontmatter}
|
|
7025
|
+
${body}` : `${frontmatter}
|
|
7026
|
+
`;
|
|
7027
|
+
const result = await sandbox.file.writeFile({
|
|
7028
|
+
file: filePath,
|
|
7029
|
+
content,
|
|
7030
|
+
encoding: "utf-8",
|
|
7031
|
+
append: false
|
|
7032
|
+
});
|
|
7033
|
+
if (!result.ok) {
|
|
7034
|
+
throw new Error(`Failed to write skill to sandbox: ${JSON.stringify(result.error)}`);
|
|
7035
|
+
}
|
|
7036
|
+
}
|
|
7037
|
+
/**
|
|
7038
|
+
* Get all skills for a tenant
|
|
7039
|
+
*/
|
|
7040
|
+
async getAllSkills(tenantId) {
|
|
7041
|
+
try {
|
|
7042
|
+
const sandboxManager = await this.getSandboxManager();
|
|
7043
|
+
const sandbox = await sandboxManager.createSandbox("global");
|
|
7044
|
+
const skillsDir = `${this.basePath}/${tenantId}/skills`;
|
|
7045
|
+
const result = await sandbox.file.listPath({
|
|
7046
|
+
path: skillsDir,
|
|
7047
|
+
recursive: false,
|
|
7048
|
+
show_hidden: false
|
|
7049
|
+
});
|
|
7050
|
+
if (!result.ok || !result.body) {
|
|
7051
|
+
return [];
|
|
7052
|
+
}
|
|
7053
|
+
const files = result.body?.data?.files || [];
|
|
7054
|
+
const skills = [];
|
|
7055
|
+
for (const entry of files) {
|
|
7056
|
+
if (entry.is_directory) {
|
|
7057
|
+
const pathParts = entry.path.split("/");
|
|
7058
|
+
const skillName = pathParts[pathParts.length - 1];
|
|
7059
|
+
if (!skillName) continue;
|
|
7060
|
+
try {
|
|
7061
|
+
const skill = await this.readSkillFile(tenantId, skillName);
|
|
7062
|
+
if (skill) {
|
|
7063
|
+
skills.push(skill);
|
|
7064
|
+
}
|
|
7065
|
+
} catch (error) {
|
|
7066
|
+
console.error(`Error loading skill "${skillName}":`, error);
|
|
7067
|
+
}
|
|
7068
|
+
}
|
|
7069
|
+
}
|
|
7070
|
+
return skills.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
7071
|
+
} catch (error) {
|
|
7072
|
+
console.error(`Error listing skills for tenant ${tenantId}:`, error);
|
|
7073
|
+
return [];
|
|
7074
|
+
}
|
|
7075
|
+
}
|
|
7076
|
+
/**
|
|
7077
|
+
* Get skill by ID
|
|
7078
|
+
*/
|
|
7079
|
+
async getSkillById(tenantId, id) {
|
|
7080
|
+
return this.readSkillFile(tenantId, id);
|
|
7081
|
+
}
|
|
7082
|
+
/**
|
|
7083
|
+
* Create a new skill
|
|
7084
|
+
*/
|
|
7085
|
+
async createSkill(tenantId, id, data) {
|
|
7086
|
+
validateSkillName(data.name);
|
|
7087
|
+
if (id !== data.name) {
|
|
7088
|
+
throw new Error(
|
|
7089
|
+
`Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
|
|
7090
|
+
);
|
|
7091
|
+
}
|
|
7092
|
+
const existing = await this.getSkillById(tenantId, id);
|
|
7093
|
+
if (existing) {
|
|
7094
|
+
return this.updateSkill(tenantId, id, data);
|
|
7095
|
+
}
|
|
7096
|
+
const now = /* @__PURE__ */ new Date();
|
|
7097
|
+
const skill = {
|
|
7098
|
+
id: data.name,
|
|
7099
|
+
tenantId,
|
|
7100
|
+
name: data.name,
|
|
7101
|
+
description: data.description,
|
|
7102
|
+
license: data.license,
|
|
7103
|
+
compatibility: data.compatibility,
|
|
7104
|
+
metadata: data.metadata || {},
|
|
7105
|
+
content: data.content,
|
|
7106
|
+
subSkills: data.subSkills,
|
|
7107
|
+
createdAt: now,
|
|
7108
|
+
updatedAt: now
|
|
7109
|
+
};
|
|
7110
|
+
await this.writeSkillFile(skill);
|
|
7111
|
+
return skill;
|
|
7112
|
+
}
|
|
7113
|
+
/**
|
|
7114
|
+
* Update an existing skill
|
|
6297
7115
|
*/
|
|
6298
|
-
|
|
6299
|
-
const
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
throw new Error(`StoreLattice ${key}:${type} not found`);
|
|
7116
|
+
async updateSkill(tenantId, id, updates) {
|
|
7117
|
+
const skill = await this.readSkillFile(tenantId, id);
|
|
7118
|
+
if (!skill) {
|
|
7119
|
+
return null;
|
|
6303
7120
|
}
|
|
6304
|
-
|
|
7121
|
+
if (updates.name !== void 0) {
|
|
7122
|
+
validateSkillName(updates.name);
|
|
7123
|
+
if (updates.name !== skill.name) {
|
|
7124
|
+
const newSkill = {
|
|
7125
|
+
...skill,
|
|
7126
|
+
name: updates.name,
|
|
7127
|
+
id: updates.name,
|
|
7128
|
+
description: updates.description ?? skill.description,
|
|
7129
|
+
license: updates.license ?? skill.license,
|
|
7130
|
+
compatibility: updates.compatibility ?? skill.compatibility,
|
|
7131
|
+
metadata: updates.metadata ?? skill.metadata,
|
|
7132
|
+
content: updates.content !== void 0 ? updates.content : skill.content,
|
|
7133
|
+
subSkills: updates.subSkills !== void 0 ? updates.subSkills : skill.subSkills,
|
|
7134
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7135
|
+
};
|
|
7136
|
+
await this.writeSkillFile(newSkill);
|
|
7137
|
+
await this.deleteSkill(tenantId, id);
|
|
7138
|
+
return newSkill;
|
|
7139
|
+
}
|
|
7140
|
+
}
|
|
7141
|
+
const updatedSkill = {
|
|
7142
|
+
...skill,
|
|
7143
|
+
name: updates.name ?? skill.name,
|
|
7144
|
+
description: updates.description ?? skill.description,
|
|
7145
|
+
license: updates.license ?? skill.license,
|
|
7146
|
+
compatibility: updates.compatibility ?? skill.compatibility,
|
|
7147
|
+
metadata: updates.metadata ?? skill.metadata,
|
|
7148
|
+
content: updates.content !== void 0 ? updates.content : skill.content,
|
|
7149
|
+
subSkills: updates.subSkills !== void 0 ? updates.subSkills : skill.subSkills,
|
|
7150
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
7151
|
+
};
|
|
7152
|
+
await this.writeSkillFile(updatedSkill);
|
|
7153
|
+
return updatedSkill;
|
|
6305
7154
|
}
|
|
6306
7155
|
/**
|
|
6307
|
-
*
|
|
7156
|
+
* Delete a skill by ID
|
|
6308
7157
|
*/
|
|
6309
|
-
|
|
6310
|
-
|
|
7158
|
+
async deleteSkill(tenantId, id) {
|
|
7159
|
+
try {
|
|
7160
|
+
const sandboxManager = await this.getSandboxManager();
|
|
7161
|
+
const sandbox = await sandboxManager.createSandbox("global");
|
|
7162
|
+
const filePath = this.getSkillFilePath(tenantId, id);
|
|
7163
|
+
const deleteResult = await sandbox.shell.execCommand({
|
|
7164
|
+
command: `rm -f "${filePath}"`
|
|
7165
|
+
});
|
|
7166
|
+
if (!deleteResult.ok) {
|
|
7167
|
+
return false;
|
|
7168
|
+
}
|
|
7169
|
+
return true;
|
|
7170
|
+
} catch (error) {
|
|
7171
|
+
console.error(`Error deleting skill ${id}:`, error);
|
|
7172
|
+
return false;
|
|
7173
|
+
}
|
|
6311
7174
|
}
|
|
6312
7175
|
/**
|
|
6313
|
-
* Check if
|
|
6314
|
-
* Uses composite key (key + type) to check existence
|
|
6315
|
-
* @param key Lattice key name
|
|
6316
|
-
* @param type Store type
|
|
7176
|
+
* Check if skill exists
|
|
6317
7177
|
*/
|
|
6318
|
-
|
|
6319
|
-
const
|
|
6320
|
-
return
|
|
7178
|
+
async hasSkill(tenantId, id) {
|
|
7179
|
+
const skill = await this.getSkillById(tenantId, id);
|
|
7180
|
+
return skill !== null;
|
|
6321
7181
|
}
|
|
6322
7182
|
/**
|
|
6323
|
-
*
|
|
6324
|
-
* Uses composite key (key + type) to remove the store
|
|
6325
|
-
* @param key Lattice key name
|
|
6326
|
-
* @param type Store type
|
|
7183
|
+
* Search skills by metadata within a tenant
|
|
6327
7184
|
*/
|
|
6328
|
-
|
|
6329
|
-
const
|
|
6330
|
-
return
|
|
7185
|
+
async searchByMetadata(tenantId, metadataKey, metadataValue) {
|
|
7186
|
+
const allSkills = await this.getAllSkills(tenantId);
|
|
7187
|
+
return allSkills.filter(
|
|
7188
|
+
(skill) => skill.metadata && skill.metadata[metadataKey] === metadataValue
|
|
7189
|
+
);
|
|
6331
7190
|
}
|
|
6332
7191
|
/**
|
|
6333
|
-
*
|
|
7192
|
+
* Filter skills by compatibility within a tenant
|
|
6334
7193
|
*/
|
|
6335
|
-
|
|
6336
|
-
this.
|
|
7194
|
+
async filterByCompatibility(tenantId, compatibility) {
|
|
7195
|
+
const allSkills = await this.getAllSkills(tenantId);
|
|
7196
|
+
return allSkills.filter((skill) => skill.compatibility === compatibility);
|
|
6337
7197
|
}
|
|
6338
7198
|
/**
|
|
6339
|
-
*
|
|
7199
|
+
* Filter skills by license within a tenant
|
|
6340
7200
|
*/
|
|
6341
|
-
|
|
6342
|
-
|
|
7201
|
+
async filterByLicense(tenantId, license) {
|
|
7202
|
+
const allSkills = await this.getAllSkills(tenantId);
|
|
7203
|
+
return allSkills.filter((skill) => skill.license === license);
|
|
6343
7204
|
}
|
|
6344
7205
|
/**
|
|
6345
|
-
* Get
|
|
7206
|
+
* Get sub-skills of a parent skill within a tenant
|
|
6346
7207
|
*/
|
|
6347
|
-
|
|
6348
|
-
|
|
7208
|
+
async getSubSkills(tenantId, parentSkillName) {
|
|
7209
|
+
const parentSkill = await this.getSkillById(tenantId, parentSkillName);
|
|
7210
|
+
if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
|
|
7211
|
+
return [];
|
|
7212
|
+
}
|
|
7213
|
+
const subSkills = [];
|
|
7214
|
+
for (const subSkillName of parentSkill.subSkills) {
|
|
7215
|
+
const subSkill = await this.getSkillById(tenantId, subSkillName);
|
|
7216
|
+
if (subSkill) {
|
|
7217
|
+
subSkills.push(subSkill);
|
|
7218
|
+
}
|
|
7219
|
+
}
|
|
7220
|
+
return subSkills;
|
|
6349
7221
|
}
|
|
6350
7222
|
};
|
|
6351
|
-
var storeLatticeManager = StoreLatticeManager.getInstance();
|
|
6352
|
-
var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
|
|
6353
|
-
var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
|
|
6354
|
-
var defaultThreadStore = new InMemoryThreadStore();
|
|
6355
|
-
var defaultAssistantStore = new InMemoryAssistantStore();
|
|
6356
|
-
var defaultSkillStore = new FileSystemSkillStore();
|
|
6357
|
-
var defaultWorkspaceStore = new InMemoryWorkspaceStore();
|
|
6358
|
-
var defaultProjectStore = new InMemoryProjectStore();
|
|
6359
|
-
var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
|
|
6360
|
-
var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
|
|
6361
|
-
var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
|
|
6362
|
-
storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
|
|
6363
|
-
storeLatticeManager.registerLattice(
|
|
6364
|
-
"default",
|
|
6365
|
-
"assistant",
|
|
6366
|
-
defaultAssistantStore
|
|
6367
|
-
);
|
|
6368
|
-
storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
|
|
6369
|
-
storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
|
|
6370
|
-
storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
|
|
6371
|
-
storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
|
|
6372
|
-
storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
|
|
6373
|
-
storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
|
|
6374
|
-
var defaultUserStore = new InMemoryUserStore();
|
|
6375
|
-
var defaultTenantStore = new InMemoryTenantStore();
|
|
6376
|
-
var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
|
|
6377
|
-
storeLatticeManager.registerLattice("default", "user", defaultUserStore);
|
|
6378
|
-
storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
|
|
6379
|
-
storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
|
|
6380
7223
|
|
|
6381
7224
|
// src/tool_lattice/skill/load_skills.ts
|
|
6382
7225
|
var import_zod41 = __toESM(require("zod"));
|
|
@@ -6415,9 +7258,11 @@ var createLoadSkillContentTool = () => {
|
|
|
6415
7258
|
try {
|
|
6416
7259
|
const storeLattice = getStoreLattice("default", "skill");
|
|
6417
7260
|
const skillStore = storeLattice.store;
|
|
6418
|
-
const
|
|
7261
|
+
const runConfig = _exe_config?.configurable?.runConfig || {};
|
|
7262
|
+
const tenantId = runConfig.tenantId || "default";
|
|
7263
|
+
const skill = await skillStore.getSkillById(tenantId, input.skill_name);
|
|
6419
7264
|
if (!skill) {
|
|
6420
|
-
const allSkills = await skillStore.getAllSkills();
|
|
7265
|
+
const allSkills = await skillStore.getAllSkills(tenantId);
|
|
6421
7266
|
const availableSkills = allSkills.map((s) => s.name).join(", ");
|
|
6422
7267
|
return `Skill "${input.skill_name}" not found. Available skills: ${availableSkills}`;
|
|
6423
7268
|
}
|
|
@@ -6449,7 +7294,7 @@ ${content}`;
|
|
|
6449
7294
|
const fsStore = skillStore;
|
|
6450
7295
|
if (fsStore.listSkillResources) {
|
|
6451
7296
|
try {
|
|
6452
|
-
const resources = await fsStore.listSkillResources(input.skill_name);
|
|
7297
|
+
const resources = await fsStore.listSkillResources(tenantId, input.skill_name);
|
|
6453
7298
|
if (resources.length > 0) {
|
|
6454
7299
|
result += "\n\n---\n\n**Resources** (use `load_skill_resource` tool to access):\n";
|
|
6455
7300
|
resources.forEach((resource) => {
|
|
@@ -6483,7 +7328,8 @@ var createLoadSkillResourceTool = () => {
|
|
|
6483
7328
|
return (0, import_langchain42.tool)(
|
|
6484
7329
|
async (input, _exe_config) => {
|
|
6485
7330
|
try {
|
|
6486
|
-
const
|
|
7331
|
+
const tenantId = _exe_config?.configurable?.runConfig?.tenantId || "default";
|
|
7332
|
+
const storeLattice = getStoreLattice(tenantId, "skill");
|
|
6487
7333
|
const skillStore = storeLattice.store;
|
|
6488
7334
|
const fsStore = skillStore;
|
|
6489
7335
|
if (!fsStore.loadSkillResource) {
|
|
@@ -6523,15 +7369,16 @@ function createSkillMiddleware(params = {}) {
|
|
|
6523
7369
|
createLoadSkillContentTool(),
|
|
6524
7370
|
createLoadSkillResourceTool()
|
|
6525
7371
|
],
|
|
6526
|
-
beforeAgent: async () => {
|
|
7372
|
+
beforeAgent: async (state, runtime) => {
|
|
6527
7373
|
try {
|
|
6528
7374
|
const storeLattice = getStoreLattice("default", "skill");
|
|
6529
7375
|
const skillStore = storeLattice?.store;
|
|
7376
|
+
const tenantId = runtime?.context?.tenantId || state?.tenantId || "default";
|
|
6530
7377
|
if (readAll) {
|
|
6531
|
-
latestSkills = await skillStore.getAllSkills();
|
|
7378
|
+
latestSkills = await skillStore.getAllSkills(tenantId);
|
|
6532
7379
|
} else if (skills && skills.length > 0) {
|
|
6533
7380
|
const skillLatticePromises = skills.map(
|
|
6534
|
-
(skillId) => skillStore.getSkillById(skillId)
|
|
7381
|
+
(skillId) => skillStore.getSkillById(tenantId, skillId)
|
|
6535
7382
|
);
|
|
6536
7383
|
const skillLattices = await Promise.all(skillLatticePromises);
|
|
6537
7384
|
latestSkills = skillLattices.filter((skill) => skill !== void 0);
|
|
@@ -7417,19 +8264,20 @@ ${systemPrompt}` : systemPrompt;
|
|
|
7417
8264
|
var import_langchain45 = require("langchain");
|
|
7418
8265
|
function createMetricsMiddleware(params) {
|
|
7419
8266
|
const { serverKeys, serverDescriptions, connectAll } = params;
|
|
7420
|
-
|
|
7421
|
-
if (connectAll) {
|
|
7422
|
-
effectiveServerKeys = metricsServerManager.getServerKeys().map((s) => s.key);
|
|
7423
|
-
}
|
|
7424
|
-
if (!effectiveServerKeys || effectiveServerKeys.length === 0) {
|
|
8267
|
+
if (!serverKeys || serverKeys.length === 0) {
|
|
7425
8268
|
return (0, import_langchain45.createMiddleware)({
|
|
7426
8269
|
name: "metricsMiddleware",
|
|
7427
8270
|
tools: []
|
|
7428
8271
|
});
|
|
7429
8272
|
}
|
|
7430
8273
|
const toolParams = {
|
|
7431
|
-
serverKeys
|
|
7432
|
-
serverDescriptions
|
|
8274
|
+
serverKeys,
|
|
8275
|
+
serverDescriptions,
|
|
8276
|
+
// When connectAll is true, tools will dynamically get all servers for the tenant at runtime
|
|
8277
|
+
connectAll,
|
|
8278
|
+
// getTenantId will be called at runtime by each tool
|
|
8279
|
+
getTenantId: void 0
|
|
8280
|
+
// Tools will extract tenantId from _exeConfig.configurable.runConfig
|
|
7433
8281
|
};
|
|
7434
8282
|
return (0, import_langchain45.createMiddleware)({
|
|
7435
8283
|
name: "metricsMiddleware",
|
|
@@ -7562,7 +8410,7 @@ function createAskUserClarifyMiddleware() {
|
|
|
7562
8410
|
}
|
|
7563
8411
|
|
|
7564
8412
|
// src/agent_lattice/builders/commonMiddleware.ts
|
|
7565
|
-
function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
8413
|
+
async function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
7566
8414
|
const middlewares = [];
|
|
7567
8415
|
const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
|
|
7568
8416
|
if (filesystemConfig?.enabled && filesystemBackend) {
|
|
@@ -7617,14 +8465,16 @@ function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
|
7617
8465
|
|
|
7618
8466
|
// src/agent_lattice/builders/ReActAgentGraphBuilder.ts
|
|
7619
8467
|
var ReActAgentGraphBuilder = class {
|
|
7620
|
-
createFilesystemBackendFactory(middlewareConfigs) {
|
|
8468
|
+
createFilesystemBackendFactory(middlewareConfigs, agentLattice) {
|
|
7621
8469
|
const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
|
|
7622
8470
|
if (!filesystemConfig || !filesystemConfig.enabled) {
|
|
7623
8471
|
return void 0;
|
|
7624
8472
|
}
|
|
7625
8473
|
const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
|
|
7626
|
-
|
|
7627
|
-
|
|
8474
|
+
const agentTenantId = agentLattice.config.tenantId;
|
|
8475
|
+
return async (stateAndStore) => {
|
|
8476
|
+
const { tenantId: runtimeTenantId, workspaceId, projectId } = stateAndStore;
|
|
8477
|
+
const tenantId = runtimeTenantId || agentTenantId;
|
|
7628
8478
|
let sandboxName = "global";
|
|
7629
8479
|
if (isolatedLevel === "agent") {
|
|
7630
8480
|
sandboxName = "agent";
|
|
@@ -7635,14 +8485,22 @@ var ReActAgentGraphBuilder = class {
|
|
|
7635
8485
|
if (!sandboxManager) {
|
|
7636
8486
|
throw new Error("Sandbox manager not found");
|
|
7637
8487
|
}
|
|
8488
|
+
let workingDirectory = "/";
|
|
8489
|
+
if (workspaceId && projectId) {
|
|
8490
|
+
if (tenantId) {
|
|
8491
|
+
workingDirectory = `/tenants/${tenantId}/${workspaceId}/${projectId}`;
|
|
8492
|
+
} else {
|
|
8493
|
+
workingDirectory = `/${workspaceId}/${projectId}`;
|
|
8494
|
+
}
|
|
8495
|
+
}
|
|
7638
8496
|
return new SandboxFilesystem({
|
|
7639
8497
|
sandboxInstance: await sandboxManager.createSandbox(sandboxName),
|
|
7640
|
-
workingDirectory
|
|
8498
|
+
workingDirectory
|
|
7641
8499
|
});
|
|
7642
8500
|
};
|
|
7643
8501
|
}
|
|
7644
|
-
createMiddlewares(middlewareConfigs) {
|
|
7645
|
-
return createCommonMiddlewares(middlewareConfigs);
|
|
8502
|
+
async createMiddlewares(middlewareConfigs) {
|
|
8503
|
+
return await createCommonMiddlewares(middlewareConfigs);
|
|
7646
8504
|
}
|
|
7647
8505
|
/**
|
|
7648
8506
|
* 构建ReAct Agent Graph
|
|
@@ -7651,15 +8509,15 @@ var ReActAgentGraphBuilder = class {
|
|
|
7651
8509
|
* @param params Agent构建参数
|
|
7652
8510
|
* @returns 返回CompiledGraph对象
|
|
7653
8511
|
*/
|
|
7654
|
-
build(agentLattice, params) {
|
|
8512
|
+
async build(agentLattice, params) {
|
|
7655
8513
|
const tools = params.tools.map((t) => {
|
|
7656
8514
|
const tool48 = getToolClient(t.key);
|
|
7657
8515
|
return tool48;
|
|
7658
8516
|
}).filter((tool48) => tool48 !== void 0);
|
|
7659
8517
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
7660
8518
|
const middlewareConfigs = params.middleware || [];
|
|
7661
|
-
const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs);
|
|
7662
|
-
const middlewares = createCommonMiddlewares(middlewareConfigs, filesystemBackend);
|
|
8519
|
+
const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs, agentLattice);
|
|
8520
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs, filesystemBackend);
|
|
7663
8521
|
return (0, import_langchain48.createAgent)({
|
|
7664
8522
|
model: params.model,
|
|
7665
8523
|
tools,
|
|
@@ -8480,14 +9338,18 @@ var StoreBackend = class {
|
|
|
8480
9338
|
/**
|
|
8481
9339
|
* Get the namespace for store operations.
|
|
8482
9340
|
*
|
|
8483
|
-
* If
|
|
8484
|
-
* [assistant_id, "filesystem"]
|
|
9341
|
+
* If both tenant_id and assistant_id are available, return
|
|
9342
|
+
* [tenant_id, assistant_id, "filesystem"] for full tenant + assistant isolation.
|
|
9343
|
+
* If only assistant_id is available, return [assistant_id, "filesystem"].
|
|
8485
9344
|
* Otherwise return ["filesystem"].
|
|
8486
9345
|
*/
|
|
8487
9346
|
getNamespace() {
|
|
8488
9347
|
const namespace = "filesystem";
|
|
9348
|
+
const tenantId = this.stateAndStore.tenantId;
|
|
8489
9349
|
const assistantId = this.stateAndStore.assistantId;
|
|
8490
|
-
if (assistantId) {
|
|
9350
|
+
if (tenantId && assistantId) {
|
|
9351
|
+
return [tenantId, assistantId, namespace];
|
|
9352
|
+
} else if (assistantId) {
|
|
8491
9353
|
return [assistantId, namespace];
|
|
8492
9354
|
}
|
|
8493
9355
|
return [namespace];
|
|
@@ -9914,8 +10776,8 @@ function createFilesystemBackendFactory(middlewareConfigs) {
|
|
|
9914
10776
|
return void 0;
|
|
9915
10777
|
}
|
|
9916
10778
|
const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
|
|
9917
|
-
return async (
|
|
9918
|
-
const { workspaceId, projectId } =
|
|
10779
|
+
return async (stateAndStore) => {
|
|
10780
|
+
const { tenantId, workspaceId, projectId } = stateAndStore;
|
|
9919
10781
|
let sandboxName = "global";
|
|
9920
10782
|
if (isolatedLevel === "agent") {
|
|
9921
10783
|
sandboxName = "agent";
|
|
@@ -9926,9 +10788,17 @@ function createFilesystemBackendFactory(middlewareConfigs) {
|
|
|
9926
10788
|
if (!sandboxManager) {
|
|
9927
10789
|
throw new Error("Sandbox manager not found");
|
|
9928
10790
|
}
|
|
10791
|
+
let workingDirectory = "/";
|
|
10792
|
+
if (workspaceId && projectId) {
|
|
10793
|
+
if (tenantId) {
|
|
10794
|
+
workingDirectory = `/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`;
|
|
10795
|
+
} else {
|
|
10796
|
+
workingDirectory = `/workspaces/${workspaceId}/${projectId}`;
|
|
10797
|
+
}
|
|
10798
|
+
}
|
|
9929
10799
|
return new SandboxFilesystem({
|
|
9930
10800
|
sandboxInstance: await sandboxManager.createSandbox(sandboxName),
|
|
9931
|
-
workingDirectory
|
|
10801
|
+
workingDirectory
|
|
9932
10802
|
});
|
|
9933
10803
|
};
|
|
9934
10804
|
}
|
|
@@ -9938,8 +10808,8 @@ var DeepAgentGraphBuilder = class {
|
|
|
9938
10808
|
/**
|
|
9939
10809
|
* 根据 middleware 配置创建 middlewares
|
|
9940
10810
|
*/
|
|
9941
|
-
createMiddlewares(middlewareConfigs) {
|
|
9942
|
-
return createCommonMiddlewares(middlewareConfigs);
|
|
10811
|
+
async createMiddlewares(middlewareConfigs) {
|
|
10812
|
+
return await createCommonMiddlewares(middlewareConfigs);
|
|
9943
10813
|
}
|
|
9944
10814
|
/**
|
|
9945
10815
|
* 构建Deep Agent Graph
|
|
@@ -9948,12 +10818,12 @@ var DeepAgentGraphBuilder = class {
|
|
|
9948
10818
|
* @param params Agent构建参数
|
|
9949
10819
|
* @returns 返回CompiledGraph对象
|
|
9950
10820
|
*/
|
|
9951
|
-
build(agentLattice, params) {
|
|
10821
|
+
async build(agentLattice, params) {
|
|
9952
10822
|
const tools = params.tools.map((t) => {
|
|
9953
10823
|
const toolClient = getToolClient(t.key);
|
|
9954
10824
|
return toolClient;
|
|
9955
10825
|
}).filter((tool48) => tool48 !== void 0);
|
|
9956
|
-
const subagents = params.subAgents.map((sa) => {
|
|
10826
|
+
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
9957
10827
|
if (sa.client) {
|
|
9958
10828
|
return {
|
|
9959
10829
|
key: sa.config.key,
|
|
@@ -9962,7 +10832,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
9962
10832
|
runnable: sa.client
|
|
9963
10833
|
};
|
|
9964
10834
|
} else {
|
|
9965
|
-
const subagentClient = createAgentClientFromAgentLattice({
|
|
10835
|
+
const subagentClient = await createAgentClientFromAgentLattice({
|
|
9966
10836
|
config: sa.config
|
|
9967
10837
|
});
|
|
9968
10838
|
return {
|
|
@@ -9972,10 +10842,10 @@ var DeepAgentGraphBuilder = class {
|
|
|
9972
10842
|
runnable: subagentClient
|
|
9973
10843
|
};
|
|
9974
10844
|
}
|
|
9975
|
-
});
|
|
10845
|
+
}));
|
|
9976
10846
|
const middlewareConfigs = params.middleware || [];
|
|
9977
10847
|
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
9978
|
-
const middlewares = this.createMiddlewares(middlewareConfigs);
|
|
10848
|
+
const middlewares = await this.createMiddlewares(middlewareConfigs);
|
|
9979
10849
|
const deepAgent = createDeepAgent({
|
|
9980
10850
|
tools,
|
|
9981
10851
|
model: params.model,
|
|
@@ -11551,7 +12421,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
11551
12421
|
* @param params - Build params with resolved tools and model
|
|
11552
12422
|
* @returns AgentClient (the TeamLead ReactAgent)
|
|
11553
12423
|
*/
|
|
11554
|
-
build(agentLattice, params) {
|
|
12424
|
+
async build(agentLattice, params) {
|
|
11555
12425
|
const config = agentLattice.config;
|
|
11556
12426
|
if (!(0, import_protocols.isTeamAgentConfig)(config)) {
|
|
11557
12427
|
throw new Error(
|
|
@@ -11574,7 +12444,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
11574
12444
|
});
|
|
11575
12445
|
const middlewareConfigs = params.middleware || [];
|
|
11576
12446
|
let filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
11577
|
-
const middlewares = createCommonMiddlewares(middlewareConfigs);
|
|
12447
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs);
|
|
11578
12448
|
if (!filesystemBackend) {
|
|
11579
12449
|
filesystemBackend = async (config2) => {
|
|
11580
12450
|
return new StateBackend(config2);
|
|
@@ -11753,6 +12623,31 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11753
12623
|
this.initialized = false;
|
|
11754
12624
|
this.subscribeToAssistantEvents();
|
|
11755
12625
|
}
|
|
12626
|
+
/**
|
|
12627
|
+
* 从store异步加载单个AgentLattice
|
|
12628
|
+
* 实现BaseLatticeManager的可选方法,支持从assistant store加载单个agent
|
|
12629
|
+
* @param tenantId 租户ID
|
|
12630
|
+
* @param key Agent键名
|
|
12631
|
+
* @returns AgentLattice或undefined
|
|
12632
|
+
*/
|
|
12633
|
+
async loadItemFromStore(tenantId, key) {
|
|
12634
|
+
try {
|
|
12635
|
+
const storeLattice = getStoreLattice("default", "assistant");
|
|
12636
|
+
const assistant = await storeLattice.store.getAssistantById(tenantId, key);
|
|
12637
|
+
if (!assistant) {
|
|
12638
|
+
return void 0;
|
|
12639
|
+
}
|
|
12640
|
+
const config = assistantToConfig(assistant);
|
|
12641
|
+
const agentLattice = {
|
|
12642
|
+
config,
|
|
12643
|
+
client: void 0
|
|
12644
|
+
};
|
|
12645
|
+
return agentLattice;
|
|
12646
|
+
} catch (error) {
|
|
12647
|
+
console.error(`Failed to load agent from store [tenant: ${tenantId}, key: ${key}]:`, error);
|
|
12648
|
+
return void 0;
|
|
12649
|
+
}
|
|
12650
|
+
}
|
|
11756
12651
|
/**
|
|
11757
12652
|
* 获取AgentLatticeManager单例实例
|
|
11758
12653
|
*/
|
|
@@ -11762,11 +12657,15 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11762
12657
|
}
|
|
11763
12658
|
return _AgentLatticeManager._instance;
|
|
11764
12659
|
}
|
|
12660
|
+
/**
|
|
12661
|
+
* @deprecated This method loads assistants only for the "default" tenant.
|
|
12662
|
+
* Use initializeStoredAssistantsForTenant(tenantId) for proper tenant isolation.
|
|
12663
|
+
*/
|
|
11765
12664
|
async initializeStoredAssistants() {
|
|
11766
12665
|
if (this.initialized) return;
|
|
11767
12666
|
try {
|
|
11768
12667
|
const storeLattice = getStoreLattice("default", "assistant");
|
|
11769
|
-
const assistants = await storeLattice.store.getAllAssistants();
|
|
12668
|
+
const assistants = await storeLattice.store.getAllAssistants("default");
|
|
11770
12669
|
for (const assistant of assistants) {
|
|
11771
12670
|
if (this.has(assistant.id)) continue;
|
|
11772
12671
|
const config = assistantToConfig(assistant);
|
|
@@ -11779,33 +12678,33 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11779
12678
|
}
|
|
11780
12679
|
subscribeToAssistantEvents() {
|
|
11781
12680
|
event_bus_default.subscribe("assistant:created", (data) => {
|
|
11782
|
-
this.handleAssistantChange(data.id);
|
|
12681
|
+
this.handleAssistantChange(data.id, data.tenantId ?? "default");
|
|
11783
12682
|
});
|
|
11784
12683
|
event_bus_default.subscribe("assistant:updated", (data) => {
|
|
11785
|
-
this.handleAssistantChange(data.id);
|
|
12684
|
+
this.handleAssistantChange(data.id, data.tenantId ?? "default");
|
|
11786
12685
|
});
|
|
11787
12686
|
event_bus_default.subscribe("assistant:deleted", (data) => {
|
|
11788
|
-
this.handleAssistantDelete(data.id);
|
|
12687
|
+
this.handleAssistantDelete(data.id, data.tenantId ?? "default");
|
|
11789
12688
|
});
|
|
11790
12689
|
}
|
|
11791
|
-
async handleAssistantChange(assistantId) {
|
|
12690
|
+
async handleAssistantChange(assistantId, tenantId = "default") {
|
|
11792
12691
|
try {
|
|
11793
12692
|
const storeLattice = getStoreLattice("default", "assistant");
|
|
11794
|
-
const assistant = await storeLattice.store.getAssistantById(assistantId);
|
|
12693
|
+
const assistant = await storeLattice.store.getAssistantById(tenantId, assistantId);
|
|
11795
12694
|
if (assistant) {
|
|
11796
|
-
if (this.
|
|
11797
|
-
this.
|
|
12695
|
+
if (this.hasWithTenant(tenantId, assistantId)) {
|
|
12696
|
+
this.removeWithTenant(tenantId, assistantId);
|
|
11798
12697
|
}
|
|
11799
12698
|
const config = assistantToConfig(assistant);
|
|
11800
|
-
this.
|
|
12699
|
+
this.registerLatticeWithTenant(tenantId, config);
|
|
11801
12700
|
}
|
|
11802
12701
|
} catch (error) {
|
|
11803
|
-
console.error(`Failed to handle assistant change for ${assistantId}:`, error);
|
|
12702
|
+
console.error(`Failed to handle assistant change for ${assistantId} (tenant: ${tenantId}):`, error);
|
|
11804
12703
|
}
|
|
11805
12704
|
}
|
|
11806
|
-
handleAssistantDelete(assistantId) {
|
|
11807
|
-
if (this.
|
|
11808
|
-
this.
|
|
12705
|
+
handleAssistantDelete(assistantId, tenantId = "default") {
|
|
12706
|
+
if (this.hasWithTenant(tenantId, assistantId)) {
|
|
12707
|
+
this.removeWithTenant(tenantId, assistantId);
|
|
11809
12708
|
}
|
|
11810
12709
|
}
|
|
11811
12710
|
/**
|
|
@@ -11814,8 +12713,96 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11814
12713
|
getLatticeType() {
|
|
11815
12714
|
return "agents";
|
|
11816
12715
|
}
|
|
12716
|
+
// ========== 带租户的新API ==========
|
|
12717
|
+
/**
|
|
12718
|
+
* 带租户注册Agent Lattice
|
|
12719
|
+
* @param tenantId 租户ID
|
|
12720
|
+
* @param config Agent配置
|
|
12721
|
+
*/
|
|
12722
|
+
registerLatticeWithTenant(tenantId, config) {
|
|
12723
|
+
const agentLattice = {
|
|
12724
|
+
config: { ...config, tenantId },
|
|
12725
|
+
client: void 0
|
|
12726
|
+
// 客户端将在需要时由initializeClient创建
|
|
12727
|
+
};
|
|
12728
|
+
this.registerWithTenant(tenantId, config.key, agentLattice);
|
|
12729
|
+
}
|
|
12730
|
+
/**
|
|
12731
|
+
* 带租户获取AgentLattice
|
|
12732
|
+
* @param tenantId 租户ID
|
|
12733
|
+
* @param key Lattice键名
|
|
12734
|
+
*/
|
|
12735
|
+
getAgentLatticeWithTenant(tenantId, key) {
|
|
12736
|
+
return this.getWithTenant(tenantId, key);
|
|
12737
|
+
}
|
|
12738
|
+
/**
|
|
12739
|
+
* 带租户检查Lattice是否存在
|
|
12740
|
+
* @param tenantId 租户ID
|
|
12741
|
+
* @param key Lattice键名
|
|
12742
|
+
*/
|
|
12743
|
+
hasAgentLatticeWithTenant(tenantId, key) {
|
|
12744
|
+
return this.hasWithTenant(tenantId, key);
|
|
12745
|
+
}
|
|
12746
|
+
/**
|
|
12747
|
+
* 带租户移除Lattice
|
|
12748
|
+
* @param tenantId 租户ID
|
|
12749
|
+
* @param key Lattice键名
|
|
12750
|
+
*/
|
|
12751
|
+
removeAgentLatticeWithTenant(tenantId, key) {
|
|
12752
|
+
return this.removeWithTenant(tenantId, key);
|
|
12753
|
+
}
|
|
12754
|
+
/**
|
|
12755
|
+
* 获取指定租户的所有Agent Lattice
|
|
12756
|
+
* @param tenantId 租户ID
|
|
12757
|
+
*/
|
|
12758
|
+
getAllAgentLatticesByTenant(tenantId) {
|
|
12759
|
+
return this.getAllByTenant(tenantId);
|
|
12760
|
+
}
|
|
12761
|
+
/**
|
|
12762
|
+
* 清空指定租户的所有Agent Lattice
|
|
12763
|
+
* @param tenantId 租户ID
|
|
12764
|
+
*/
|
|
12765
|
+
clearAgentLatticesByTenant(tenantId) {
|
|
12766
|
+
this.clearByTenant(tenantId);
|
|
12767
|
+
}
|
|
12768
|
+
/**
|
|
12769
|
+
* 带租户获取Agent配置
|
|
12770
|
+
* @param tenantId 租户ID
|
|
12771
|
+
* @param key Lattice键名
|
|
12772
|
+
*/
|
|
12773
|
+
getAgentConfigWithTenant(tenantId, key) {
|
|
12774
|
+
return this.getAgentLatticeWithTenant(tenantId, key)?.config;
|
|
12775
|
+
}
|
|
12776
|
+
/**
|
|
12777
|
+
* 获取指定租户的所有Agent配置
|
|
12778
|
+
* 先从数据库加载该租户的 assistants,然后返回所有配置
|
|
12779
|
+
* @param tenantId 租户ID
|
|
12780
|
+
*/
|
|
12781
|
+
async getAllAgentConfigsByTenant(tenantId) {
|
|
12782
|
+
await this.initializeStoredAssistantsForTenant(tenantId);
|
|
12783
|
+
return this.getAllAgentLatticesByTenant(tenantId).map((lattice) => lattice.config);
|
|
12784
|
+
}
|
|
12785
|
+
/**
|
|
12786
|
+
* 从数据库加载指定租户的存储助手
|
|
12787
|
+
* @param tenantId 租户ID
|
|
12788
|
+
*/
|
|
12789
|
+
async initializeStoredAssistantsForTenant(tenantId) {
|
|
12790
|
+
try {
|
|
12791
|
+
const storeLattice = getStoreLattice("default", "assistant");
|
|
12792
|
+
const assistants = await storeLattice.store.getAllAssistants(tenantId);
|
|
12793
|
+
for (const assistant of assistants) {
|
|
12794
|
+
if (this.hasAgentLatticeWithTenant(tenantId, assistant.id)) continue;
|
|
12795
|
+
const config = assistantToConfig(assistant);
|
|
12796
|
+
this.registerLatticeWithTenant(tenantId, config);
|
|
12797
|
+
}
|
|
12798
|
+
} catch (error) {
|
|
12799
|
+
console.error(`Failed to initialize stored assistants for tenant ${tenantId}:`, error);
|
|
12800
|
+
}
|
|
12801
|
+
}
|
|
12802
|
+
// ========== 向后兼容的旧API(使用 default 租户) ==========
|
|
11817
12803
|
/**
|
|
11818
|
-
* 注册Agent Lattice
|
|
12804
|
+
* 注册Agent Lattice(向后兼容,使用 "default" 租户)
|
|
12805
|
+
* @deprecated Use registerLatticeWithTenant(tenantId, config) instead
|
|
11819
12806
|
* @param config Agent配置
|
|
11820
12807
|
*/
|
|
11821
12808
|
registerLattice(config) {
|
|
@@ -11853,7 +12840,8 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11853
12840
|
return this.remove(key);
|
|
11854
12841
|
}
|
|
11855
12842
|
/**
|
|
11856
|
-
* 获取AgentLattice
|
|
12843
|
+
* 获取AgentLattice(向后兼容,使用 "default" 租户)
|
|
12844
|
+
* @deprecated Use getAgentLatticeWithTenant(tenantId, key) instead
|
|
11857
12845
|
* @param key Lattice键名
|
|
11858
12846
|
*/
|
|
11859
12847
|
getAgentLattice(key) {
|
|
@@ -11866,25 +12854,28 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11866
12854
|
return this.getAll();
|
|
11867
12855
|
}
|
|
11868
12856
|
/**
|
|
11869
|
-
* 检查Lattice
|
|
12857
|
+
* 检查Lattice是否存在(向后兼容,使用 "default" 租户)
|
|
12858
|
+
* @deprecated Use hasAgentLatticeWithTenant(tenantId, key) instead
|
|
11870
12859
|
* @param key Lattice键名
|
|
11871
12860
|
*/
|
|
11872
12861
|
hasLattice(key) {
|
|
11873
12862
|
return this.has(key);
|
|
11874
12863
|
}
|
|
11875
12864
|
/**
|
|
11876
|
-
* 移除Lattice
|
|
12865
|
+
* 移除Lattice(向后兼容,使用 "default" 租户)
|
|
12866
|
+
* @deprecated Use removeAgentLatticeWithTenant(tenantId, key) instead
|
|
11877
12867
|
* @param key Lattice键名
|
|
11878
12868
|
*/
|
|
11879
12869
|
removeLattice(key) {
|
|
11880
12870
|
return this.remove(key);
|
|
11881
12871
|
}
|
|
11882
12872
|
/**
|
|
11883
|
-
* 获取Agent
|
|
12873
|
+
* 获取Agent配置(向后兼容,使用 "default" 租户)
|
|
12874
|
+
* @deprecated Use getAgentConfigWithTenant(tenantId, key) instead
|
|
11884
12875
|
* @param key Lattice键名
|
|
11885
12876
|
*/
|
|
11886
12877
|
getAgentConfig(key) {
|
|
11887
|
-
return this.
|
|
12878
|
+
return this.getAgentLatticeWithTenant("default", key)?.config;
|
|
11888
12879
|
}
|
|
11889
12880
|
/**
|
|
11890
12881
|
* 获取所有Agent配置
|
|
@@ -11905,8 +12896,9 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11905
12896
|
return false;
|
|
11906
12897
|
}
|
|
11907
12898
|
try {
|
|
11908
|
-
|
|
11909
|
-
|
|
12899
|
+
const config = agentLattice.config;
|
|
12900
|
+
if ("schema" in config && config.schema) {
|
|
12901
|
+
config.schema.parse(input);
|
|
11910
12902
|
}
|
|
11911
12903
|
return true;
|
|
11912
12904
|
} catch {
|
|
@@ -11954,9 +12946,10 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11954
12946
|
* @returns 返回Agent构建参数
|
|
11955
12947
|
*/
|
|
11956
12948
|
buildAgentParams(agentLattice, options) {
|
|
12949
|
+
const tenantId = agentLattice.config.tenantId || "default";
|
|
11957
12950
|
const paramsBuilder = new AgentParamsBuilder((key) => {
|
|
11958
|
-
this.initializeClient(key);
|
|
11959
|
-
return this.
|
|
12951
|
+
this.initializeClient(tenantId, key);
|
|
12952
|
+
return this.getAgentLatticeWithTenant(tenantId, key);
|
|
11960
12953
|
});
|
|
11961
12954
|
return paramsBuilder.buildParams(agentLattice, options);
|
|
11962
12955
|
}
|
|
@@ -11967,7 +12960,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11967
12960
|
* @param options Build options
|
|
11968
12961
|
* @returns AgentClient instance
|
|
11969
12962
|
*/
|
|
11970
|
-
createAgentClientFromConfig(agentLattice, options) {
|
|
12963
|
+
async createAgentClientFromConfig(agentLattice, options) {
|
|
11971
12964
|
const resolvedConfig = this.resolveInheritedConfig(agentLattice.config);
|
|
11972
12965
|
const resolvedLattice = {
|
|
11973
12966
|
...agentLattice,
|
|
@@ -11976,26 +12969,50 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11976
12969
|
const factory = AgentGraphBuilderFactory.getInstance();
|
|
11977
12970
|
const builder = factory.getBuilder(resolvedConfig.type);
|
|
11978
12971
|
const params = this.buildAgentParams(resolvedLattice, options);
|
|
11979
|
-
return builder.build(resolvedLattice, params);
|
|
12972
|
+
return await builder.build(resolvedLattice, params);
|
|
11980
12973
|
}
|
|
11981
12974
|
/**
|
|
11982
12975
|
* 初始化Agent客户端
|
|
11983
12976
|
*
|
|
11984
12977
|
* 使用AgentGraphBuilderFactory构建Graph并设置为客户端
|
|
11985
12978
|
*
|
|
12979
|
+
* @param tenantId 租户ID
|
|
11986
12980
|
* @param key Lattice键名
|
|
11987
12981
|
* @param options 构建选项
|
|
11988
12982
|
* @returns 返回CompiledGraph对象
|
|
11989
12983
|
*/
|
|
11990
|
-
initializeClient(key, options) {
|
|
11991
|
-
const agentLattice = this.
|
|
12984
|
+
async initializeClient(tenantId, key, options) {
|
|
12985
|
+
const agentLattice = this.getAgentLatticeWithTenant(tenantId, key);
|
|
12986
|
+
if (!agentLattice) {
|
|
12987
|
+
throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
|
|
12988
|
+
}
|
|
12989
|
+
if (agentLattice.client) {
|
|
12990
|
+
return agentLattice.client;
|
|
12991
|
+
}
|
|
12992
|
+
const graph = await this.createAgentClientFromConfig(agentLattice, options);
|
|
12993
|
+
agentLattice.client = graph;
|
|
12994
|
+
return graph;
|
|
12995
|
+
}
|
|
12996
|
+
/**
|
|
12997
|
+
* 异步初始化Agent客户端(支持从store加载)
|
|
12998
|
+
*
|
|
12999
|
+
* 如果内存中不存在,会尝试从store加载
|
|
13000
|
+
* 使用AgentGraphBuilderFactory构建Graph并设置为客户端
|
|
13001
|
+
*
|
|
13002
|
+
* @param tenantId 租户ID
|
|
13003
|
+
* @param key Lattice键名
|
|
13004
|
+
* @param options 构建选项
|
|
13005
|
+
* @returns 返回CompiledGraph对象
|
|
13006
|
+
*/
|
|
13007
|
+
async initializeClientAsync(tenantId, key, options) {
|
|
13008
|
+
const agentLattice = await this.getOrLoadWithTenant(tenantId, key);
|
|
11992
13009
|
if (!agentLattice) {
|
|
11993
|
-
throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728`);
|
|
13010
|
+
throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
|
|
11994
13011
|
}
|
|
11995
13012
|
if (agentLattice.client) {
|
|
11996
13013
|
return agentLattice.client;
|
|
11997
13014
|
}
|
|
11998
|
-
const graph = this.createAgentClientFromConfig(agentLattice, options);
|
|
13015
|
+
const graph = await this.createAgentClientFromConfig(agentLattice, options);
|
|
11999
13016
|
agentLattice.client = graph;
|
|
12000
13017
|
return graph;
|
|
12001
13018
|
}
|
|
@@ -12004,19 +13021,24 @@ var agentLatticeManager = AgentLatticeManager.getInstance();
|
|
|
12004
13021
|
var registerAgentLattice = (config) => {
|
|
12005
13022
|
agentLatticeManager.registerLattice(config);
|
|
12006
13023
|
};
|
|
12007
|
-
var
|
|
13024
|
+
var registerAgentLatticeWithTenant = (tenantId, config) => {
|
|
13025
|
+
agentLatticeManager.registerLatticeWithTenant(tenantId, config);
|
|
13026
|
+
};
|
|
13027
|
+
var registerAgentLattices = (tenantId, configs) => {
|
|
13028
|
+
if (!tenantId) {
|
|
13029
|
+
throw new Error("tenantId is required");
|
|
13030
|
+
}
|
|
12008
13031
|
configs.forEach((config) => {
|
|
12009
|
-
agentLatticeManager.
|
|
13032
|
+
agentLatticeManager.registerLatticeWithTenant(tenantId, config);
|
|
12010
13033
|
});
|
|
12011
13034
|
};
|
|
12012
|
-
var getAgentLattice = (key) => agentLatticeManager.getAgentLattice(key);
|
|
12013
13035
|
var getAgentConfig = (key) => agentLatticeManager.getAgentConfig(key);
|
|
12014
13036
|
var getAllAgentConfigs = () => agentLatticeManager.getAllAgentConfigs();
|
|
12015
13037
|
var validateAgentInput = (key, input) => agentLatticeManager.validateAgentInput(key, input);
|
|
12016
13038
|
var registerTeammateAgent = (key, client) => agentLatticeManager.registerTeammateAgent(key, client);
|
|
12017
13039
|
var unregisterTeammateAgent = (key) => agentLatticeManager.unregisterTeammateAgent(key);
|
|
12018
|
-
var getAgentClient = (key, options) => agentLatticeManager.initializeClient(key, options);
|
|
12019
|
-
var createAgentClientFromAgentLattice = (agentLattice, options) => agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
|
|
13040
|
+
var getAgentClient = (tenantId, key, options) => agentLatticeManager.initializeClient(tenantId, key, options);
|
|
13041
|
+
var createAgentClientFromAgentLattice = async (agentLattice, options) => await agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
|
|
12020
13042
|
|
|
12021
13043
|
// src/chunk_buffer_lattice/ChunkBuffer.ts
|
|
12022
13044
|
var ChunkBuffer = class {
|
|
@@ -12094,6 +13116,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12094
13116
|
buffer = {
|
|
12095
13117
|
threadId,
|
|
12096
13118
|
chunks$: new import_rxjs.ReplaySubject(this.config.maxChunks),
|
|
13119
|
+
chunks: [],
|
|
12097
13120
|
status: "active" /* ACTIVE */,
|
|
12098
13121
|
createdAt: now,
|
|
12099
13122
|
updatedAt: now,
|
|
@@ -12104,14 +13127,27 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12104
13127
|
if (buffer.status !== "active" /* ACTIVE */) {
|
|
12105
13128
|
buffer.status = "active" /* ACTIVE */;
|
|
12106
13129
|
buffer.chunks$ = new import_rxjs.ReplaySubject(this.config.maxChunks);
|
|
13130
|
+
buffer.chunks = [];
|
|
12107
13131
|
buffer.updatedAt = Date.now();
|
|
12108
13132
|
buffer.expiresAt = Date.now() + this.config.ttl;
|
|
12109
13133
|
}
|
|
12110
13134
|
return buffer;
|
|
12111
13135
|
}
|
|
12112
|
-
async addChunk(threadId,
|
|
13136
|
+
async addChunk(threadId, arg2, arg3) {
|
|
12113
13137
|
const buffer = this.getOrCreateBuffer(threadId);
|
|
12114
|
-
|
|
13138
|
+
let chunk;
|
|
13139
|
+
if (typeof arg2 === "string" && arg3 !== void 0) {
|
|
13140
|
+
chunk = {
|
|
13141
|
+
type: "message_chunk",
|
|
13142
|
+
data: {
|
|
13143
|
+
id: arg2,
|
|
13144
|
+
content: arg3
|
|
13145
|
+
}
|
|
13146
|
+
};
|
|
13147
|
+
} else {
|
|
13148
|
+
chunk = arg2;
|
|
13149
|
+
}
|
|
13150
|
+
buffer.chunks.push(chunk);
|
|
12115
13151
|
buffer.chunks$.next(chunk);
|
|
12116
13152
|
buffer.updatedAt = Date.now();
|
|
12117
13153
|
buffer.expiresAt = Date.now() + this.config.ttl;
|
|
@@ -12143,7 +13179,25 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12143
13179
|
async getThreadBuffer(threadId) {
|
|
12144
13180
|
const buffer = this.getBufferIfValid(threadId);
|
|
12145
13181
|
if (!buffer) return void 0;
|
|
12146
|
-
return
|
|
13182
|
+
return {
|
|
13183
|
+
...buffer,
|
|
13184
|
+
chunks: [...buffer.chunks]
|
|
13185
|
+
};
|
|
13186
|
+
}
|
|
13187
|
+
async getChunks(threadId) {
|
|
13188
|
+
const buffer = this.getBufferIfValid(threadId);
|
|
13189
|
+
if (!buffer) return [];
|
|
13190
|
+
return [...buffer.chunks];
|
|
13191
|
+
}
|
|
13192
|
+
async getAccumulatedContent(threadId) {
|
|
13193
|
+
const buffer = this.getBufferIfValid(threadId);
|
|
13194
|
+
if (!buffer) return "";
|
|
13195
|
+
return buffer.chunks.map((chunk) => chunk.data?.content || "").join("");
|
|
13196
|
+
}
|
|
13197
|
+
async getChunksByMessageId(threadId, messageId) {
|
|
13198
|
+
const buffer = this.getBufferIfValid(threadId);
|
|
13199
|
+
if (!buffer) return [];
|
|
13200
|
+
return buffer.chunks.filter((chunk) => chunk.data?.id === messageId);
|
|
12147
13201
|
}
|
|
12148
13202
|
async clearThread(threadId) {
|
|
12149
13203
|
this.buffers.delete(threadId);
|
|
@@ -12273,6 +13327,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12273
13327
|
let activeCount = 0;
|
|
12274
13328
|
let completedCount = 0;
|
|
12275
13329
|
let abortedCount = 0;
|
|
13330
|
+
let totalChunkCount = 0;
|
|
12276
13331
|
const validBuffers = [];
|
|
12277
13332
|
for (const [threadId, buffer] of this.buffers.entries()) {
|
|
12278
13333
|
if (this.isExpired(buffer)) {
|
|
@@ -12293,12 +13348,14 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12293
13348
|
abortedCount++;
|
|
12294
13349
|
break;
|
|
12295
13350
|
}
|
|
13351
|
+
totalChunkCount += buffer.chunks.length;
|
|
12296
13352
|
}
|
|
12297
13353
|
return {
|
|
12298
13354
|
totalThreads: validBuffers.length,
|
|
12299
13355
|
activeThreads: activeCount,
|
|
12300
13356
|
completedThreads: completedCount,
|
|
12301
13357
|
abortedThreads: abortedCount,
|
|
13358
|
+
totalChunks: totalChunkCount,
|
|
12302
13359
|
config: this.config
|
|
12303
13360
|
};
|
|
12304
13361
|
}
|
|
@@ -12459,6 +13516,9 @@ var MemoryScheduleStorage = class {
|
|
|
12459
13516
|
let result = [];
|
|
12460
13517
|
for (const task of this.tasks.values()) {
|
|
12461
13518
|
let match = true;
|
|
13519
|
+
if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
|
|
13520
|
+
match = false;
|
|
13521
|
+
}
|
|
12462
13522
|
if (filters?.status !== void 0 && task.status !== filters.status) {
|
|
12463
13523
|
match = false;
|
|
12464
13524
|
}
|
|
@@ -12495,6 +13555,9 @@ var MemoryScheduleStorage = class {
|
|
|
12495
13555
|
let count = 0;
|
|
12496
13556
|
for (const task of this.tasks.values()) {
|
|
12497
13557
|
let match = true;
|
|
13558
|
+
if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
|
|
13559
|
+
match = false;
|
|
13560
|
+
}
|
|
12498
13561
|
if (filters?.status !== void 0 && task.status !== filters.status) {
|
|
12499
13562
|
match = false;
|
|
12500
13563
|
}
|
|
@@ -13832,6 +14895,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13832
14895
|
getLatticeType() {
|
|
13833
14896
|
return "skills";
|
|
13834
14897
|
}
|
|
14898
|
+
/**
|
|
14899
|
+
* Default tenant ID for store operations
|
|
14900
|
+
* Note: SkillLatticeManager operates without explicit tenant context.
|
|
14901
|
+
* Store methods require tenantId for protocol compliance.
|
|
14902
|
+
*/
|
|
14903
|
+
getDefaultTenantId() {
|
|
14904
|
+
return "default";
|
|
14905
|
+
}
|
|
13835
14906
|
/**
|
|
13836
14907
|
* Configure store for persistence
|
|
13837
14908
|
* @param storeKey Store key name registered in StoreLatticeManager
|
|
@@ -13872,12 +14943,13 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13872
14943
|
client.store = store;
|
|
13873
14944
|
}
|
|
13874
14945
|
/**
|
|
13875
|
-
* Register a skill Lattice
|
|
14946
|
+
* Register a skill Lattice with tenant
|
|
14947
|
+
* @param tenantId Tenant ID
|
|
13876
14948
|
* @param key Lattice key name
|
|
13877
14949
|
* @param config Skill configuration
|
|
13878
14950
|
* @param client Optional skill client implementation
|
|
13879
14951
|
*/
|
|
13880
|
-
async
|
|
14952
|
+
async registerLatticeWithTenant(tenantId, key, config, client) {
|
|
13881
14953
|
if (!config.name) {
|
|
13882
14954
|
throw new Error("Skill name is required");
|
|
13883
14955
|
}
|
|
@@ -13899,10 +14971,10 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13899
14971
|
config,
|
|
13900
14972
|
client: client ?? null
|
|
13901
14973
|
};
|
|
13902
|
-
this.
|
|
14974
|
+
this.registerWithTenant(tenantId, key, skillLattice);
|
|
13903
14975
|
if (store) {
|
|
13904
14976
|
try {
|
|
13905
|
-
await store.createSkill(key, {
|
|
14977
|
+
await store.createSkill(tenantId, key, {
|
|
13906
14978
|
name: config.name,
|
|
13907
14979
|
description: config.description,
|
|
13908
14980
|
license: config.license,
|
|
@@ -13920,24 +14992,43 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13920
14992
|
}
|
|
13921
14993
|
}
|
|
13922
14994
|
/**
|
|
13923
|
-
*
|
|
14995
|
+
* Register a skill Lattice (backward compatible, uses "default" tenant)
|
|
14996
|
+
* @deprecated Use registerLatticeWithTenant(tenantId, key, config, client) instead
|
|
14997
|
+
* @param key Lattice key name
|
|
14998
|
+
* @param config Skill configuration
|
|
14999
|
+
* @param client Optional skill client implementation
|
|
15000
|
+
*/
|
|
15001
|
+
async registerLattice(key, config, client) {
|
|
15002
|
+
return this.registerLatticeWithTenant(this.getDefaultTenantId(), key, config, client);
|
|
15003
|
+
}
|
|
15004
|
+
/**
|
|
15005
|
+
* Get skill Lattice by key with tenant
|
|
15006
|
+
* @param tenantId Tenant ID
|
|
15007
|
+
* @param key Lattice key name
|
|
15008
|
+
*/
|
|
15009
|
+
getSkillLatticeWithTenant(tenantId, key) {
|
|
15010
|
+
return this.getWithTenant(tenantId, key);
|
|
15011
|
+
}
|
|
15012
|
+
/**
|
|
15013
|
+
* Get skill Lattice by key (backward compatible, uses "default" tenant)
|
|
15014
|
+
* @deprecated Use getSkillLatticeWithTenant(tenantId, key) instead
|
|
13924
15015
|
* @param key Lattice key name
|
|
13925
15016
|
*/
|
|
13926
15017
|
getSkillLattice(key) {
|
|
13927
|
-
return this.
|
|
15018
|
+
return this.getWithTenant(this.getDefaultTenantId(), key);
|
|
13928
15019
|
}
|
|
13929
15020
|
/**
|
|
13930
|
-
* Get all skill Lattices from store
|
|
13931
|
-
*
|
|
15021
|
+
* Get all skill Lattices from store with tenant
|
|
15022
|
+
* @param tenantId Tenant ID
|
|
13932
15023
|
*/
|
|
13933
|
-
async
|
|
15024
|
+
async getAllLatticesWithTenant(tenantId) {
|
|
13934
15025
|
const store = this.getStore();
|
|
13935
15026
|
if (!store) {
|
|
13936
|
-
return this.
|
|
15027
|
+
return this.getAllByTenant(tenantId);
|
|
13937
15028
|
}
|
|
13938
|
-
const skills = await store.getAllSkills();
|
|
15029
|
+
const skills = await store.getAllSkills(tenantId);
|
|
13939
15030
|
return skills.map((skill) => {
|
|
13940
|
-
const memoryLattice = this.
|
|
15031
|
+
const memoryLattice = this.getWithTenant(tenantId, skill.id);
|
|
13941
15032
|
const client = memoryLattice?.client || null;
|
|
13942
15033
|
if (client && store) {
|
|
13943
15034
|
this.injectStoreIntoClient(client, store);
|
|
@@ -13958,23 +15049,40 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13958
15049
|
});
|
|
13959
15050
|
}
|
|
13960
15051
|
/**
|
|
13961
|
-
*
|
|
15052
|
+
* Get all skill Lattices from store (backward compatible, uses "default" tenant)
|
|
15053
|
+
* @deprecated Use getAllLatticesWithTenant(tenantId) instead
|
|
15054
|
+
*/
|
|
15055
|
+
async getAllLattices() {
|
|
15056
|
+
return this.getAllLatticesWithTenant(this.getDefaultTenantId());
|
|
15057
|
+
}
|
|
15058
|
+
/**
|
|
15059
|
+
* Check if Lattice exists with tenant
|
|
15060
|
+
* @param tenantId Tenant ID
|
|
15061
|
+
* @param key Lattice key name
|
|
15062
|
+
*/
|
|
15063
|
+
hasLatticeWithTenant(tenantId, key) {
|
|
15064
|
+
return this.hasWithTenant(tenantId, key);
|
|
15065
|
+
}
|
|
15066
|
+
/**
|
|
15067
|
+
* Check if Lattice exists (backward compatible, uses "default" tenant)
|
|
15068
|
+
* @deprecated Use hasLatticeWithTenant(tenantId, key) instead
|
|
13962
15069
|
* @param key Lattice key name
|
|
13963
15070
|
*/
|
|
13964
15071
|
hasLattice(key) {
|
|
13965
|
-
return this.
|
|
15072
|
+
return this.hasWithTenant(this.getDefaultTenantId(), key);
|
|
13966
15073
|
}
|
|
13967
15074
|
/**
|
|
13968
|
-
* Remove Lattice
|
|
15075
|
+
* Remove Lattice with tenant
|
|
15076
|
+
* @param tenantId Tenant ID
|
|
13969
15077
|
* @param key Lattice key name
|
|
13970
15078
|
*/
|
|
13971
|
-
async
|
|
13972
|
-
const removed = this.
|
|
15079
|
+
async removeLatticeWithTenant(tenantId, key) {
|
|
15080
|
+
const removed = this.removeWithTenant(tenantId, key);
|
|
13973
15081
|
if (removed) {
|
|
13974
15082
|
const store = this.getStore();
|
|
13975
15083
|
if (store) {
|
|
13976
15084
|
try {
|
|
13977
|
-
await store.deleteSkill(key);
|
|
15085
|
+
await store.deleteSkill(tenantId, key);
|
|
13978
15086
|
} catch (error) {
|
|
13979
15087
|
console.warn(
|
|
13980
15088
|
`Failed to remove skill ${key} from store:`,
|
|
@@ -13985,6 +15093,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13985
15093
|
}
|
|
13986
15094
|
return removed;
|
|
13987
15095
|
}
|
|
15096
|
+
/**
|
|
15097
|
+
* Remove Lattice (backward compatible, uses "default" tenant)
|
|
15098
|
+
* @deprecated Use removeLatticeWithTenant(tenantId, key) instead
|
|
15099
|
+
* @param key Lattice key name
|
|
15100
|
+
*/
|
|
15101
|
+
async removeLattice(key) {
|
|
15102
|
+
return this.removeLatticeWithTenant(this.getDefaultTenantId(), key);
|
|
15103
|
+
}
|
|
13988
15104
|
/**
|
|
13989
15105
|
* Clear all Lattices
|
|
13990
15106
|
*/
|
|
@@ -14082,7 +15198,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
14082
15198
|
if (!store) {
|
|
14083
15199
|
throw new Error("No store configured. Call configureStore() first.");
|
|
14084
15200
|
}
|
|
14085
|
-
const skills = await store.getAllSkills();
|
|
15201
|
+
const skills = await store.getAllSkills(this.getDefaultTenantId());
|
|
14086
15202
|
for (const skill of skills) {
|
|
14087
15203
|
const skillLattice = {
|
|
14088
15204
|
key: skill.id,
|
|
@@ -14119,7 +15235,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
14119
15235
|
...updates
|
|
14120
15236
|
};
|
|
14121
15237
|
skillLattice.config = updatedConfig;
|
|
14122
|
-
await store.updateSkill(key, {
|
|
15238
|
+
await store.updateSkill(this.getDefaultTenantId(), key, {
|
|
14123
15239
|
name: updatedConfig.name,
|
|
14124
15240
|
description: updatedConfig.description,
|
|
14125
15241
|
license: updatedConfig.license,
|
|
@@ -14344,6 +15460,7 @@ function clearEncryptionKeyCache() {
|
|
|
14344
15460
|
QueueLatticeManager,
|
|
14345
15461
|
SandboxFilesystem,
|
|
14346
15462
|
SandboxLatticeManager,
|
|
15463
|
+
SandboxSkillStore,
|
|
14347
15464
|
ScheduleLatticeManager,
|
|
14348
15465
|
SemanticMetricsClient,
|
|
14349
15466
|
SkillLatticeManager,
|
|
@@ -14391,7 +15508,6 @@ function clearEncryptionKeyCache() {
|
|
|
14391
15508
|
formatReadResponse,
|
|
14392
15509
|
getAgentClient,
|
|
14393
15510
|
getAgentConfig,
|
|
14394
|
-
getAgentLattice,
|
|
14395
15511
|
getAllAgentConfigs,
|
|
14396
15512
|
getAllToolDefinitions,
|
|
14397
15513
|
getCheckpointSaver,
|
|
@@ -14428,6 +15544,7 @@ function clearEncryptionKeyCache() {
|
|
|
14428
15544
|
performStringReplacement,
|
|
14429
15545
|
queueLatticeManager,
|
|
14430
15546
|
registerAgentLattice,
|
|
15547
|
+
registerAgentLatticeWithTenant,
|
|
14431
15548
|
registerAgentLattices,
|
|
14432
15549
|
registerCheckpointSaver,
|
|
14433
15550
|
registerChunkBuffer,
|