@axiom-lattice/core 2.1.31 → 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 +1530 -412
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1528 -411
- 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,18 +3466,19 @@ ${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,
|
|
3135
3477
|
params,
|
|
3136
|
-
limit: limit ||
|
|
3478
|
+
limit: limit || 100
|
|
3137
3479
|
});
|
|
3138
|
-
|
|
3480
|
+
const rows = result.result?.rows || [];
|
|
3481
|
+
return "query_result:\n" + JSON.stringify(rows, null, 2);
|
|
3139
3482
|
} catch (error) {
|
|
3140
3483
|
return `Error executing SQL query: ${error instanceof Error ? error.message : String(error)}`;
|
|
3141
3484
|
}
|
|
@@ -4875,104 +5218,137 @@ var import_langchain43 = require("langchain");
|
|
|
4875
5218
|
// src/store_lattice/InMemoryThreadStore.ts
|
|
4876
5219
|
var InMemoryThreadStore = class {
|
|
4877
5220
|
constructor() {
|
|
4878
|
-
// Map<assistantId, Map<threadId, Thread
|
|
5221
|
+
// Map<tenantId, Map<assistantId, Map<threadId, Thread>>>
|
|
4879
5222
|
this.threads = /* @__PURE__ */ new Map();
|
|
4880
5223
|
}
|
|
4881
5224
|
/**
|
|
4882
|
-
* Get all threads for a specific assistant
|
|
5225
|
+
* Get all threads for a specific tenant and assistant
|
|
4883
5226
|
*/
|
|
4884
|
-
async getThreadsByAssistantId(assistantId) {
|
|
4885
|
-
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);
|
|
4886
5233
|
if (!assistantThreads) {
|
|
4887
5234
|
return [];
|
|
4888
5235
|
}
|
|
4889
5236
|
return Array.from(assistantThreads.values());
|
|
4890
5237
|
}
|
|
4891
5238
|
/**
|
|
4892
|
-
* Get a thread by ID for a specific
|
|
5239
|
+
* Get a thread by ID for a specific tenant
|
|
4893
5240
|
*/
|
|
4894
|
-
async getThreadById(
|
|
4895
|
-
const
|
|
4896
|
-
if (!
|
|
5241
|
+
async getThreadById(tenantId, threadId) {
|
|
5242
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5243
|
+
if (!tenantThreads) {
|
|
4897
5244
|
return void 0;
|
|
4898
5245
|
}
|
|
4899
|
-
|
|
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;
|
|
4900
5253
|
}
|
|
4901
5254
|
/**
|
|
4902
|
-
* Create a new thread for
|
|
5255
|
+
* Create a new thread for a tenant and assistant
|
|
4903
5256
|
*/
|
|
4904
|
-
async createThread(assistantId, threadId, data) {
|
|
5257
|
+
async createThread(tenantId, assistantId, threadId, data) {
|
|
4905
5258
|
const now = /* @__PURE__ */ new Date();
|
|
4906
5259
|
const thread = {
|
|
4907
5260
|
id: threadId,
|
|
5261
|
+
tenantId,
|
|
4908
5262
|
assistantId,
|
|
4909
5263
|
metadata: data.metadata || {},
|
|
4910
5264
|
createdAt: now,
|
|
4911
5265
|
updatedAt: now
|
|
4912
5266
|
};
|
|
4913
|
-
if (!this.threads.has(
|
|
4914
|
-
this.threads.set(
|
|
5267
|
+
if (!this.threads.has(tenantId)) {
|
|
5268
|
+
this.threads.set(tenantId, /* @__PURE__ */ new Map());
|
|
4915
5269
|
}
|
|
4916
|
-
const
|
|
5270
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5271
|
+
if (!tenantThreads.has(assistantId)) {
|
|
5272
|
+
tenantThreads.set(assistantId, /* @__PURE__ */ new Map());
|
|
5273
|
+
}
|
|
5274
|
+
const assistantThreads = tenantThreads.get(assistantId);
|
|
4917
5275
|
assistantThreads.set(threadId, thread);
|
|
4918
5276
|
return thread;
|
|
4919
5277
|
}
|
|
4920
5278
|
/**
|
|
4921
5279
|
* Update an existing thread
|
|
4922
5280
|
*/
|
|
4923
|
-
async updateThread(
|
|
4924
|
-
const
|
|
4925
|
-
if (!
|
|
5281
|
+
async updateThread(tenantId, threadId, updates) {
|
|
5282
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5283
|
+
if (!tenantThreads) {
|
|
4926
5284
|
return null;
|
|
4927
5285
|
}
|
|
4928
|
-
const
|
|
4929
|
-
|
|
4930
|
-
|
|
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
|
+
}
|
|
4931
5300
|
}
|
|
4932
|
-
|
|
4933
|
-
...existing,
|
|
4934
|
-
metadata: {
|
|
4935
|
-
...existing.metadata,
|
|
4936
|
-
...updates.metadata || {}
|
|
4937
|
-
},
|
|
4938
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
4939
|
-
};
|
|
4940
|
-
assistantThreads.set(threadId, updated);
|
|
4941
|
-
return updated;
|
|
5301
|
+
return null;
|
|
4942
5302
|
}
|
|
4943
5303
|
/**
|
|
4944
5304
|
* Delete a thread by ID
|
|
4945
5305
|
*/
|
|
4946
|
-
async deleteThread(
|
|
4947
|
-
const
|
|
4948
|
-
if (!
|
|
5306
|
+
async deleteThread(tenantId, threadId) {
|
|
5307
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5308
|
+
if (!tenantThreads) {
|
|
4949
5309
|
return false;
|
|
4950
5310
|
}
|
|
4951
|
-
|
|
5311
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5312
|
+
if (assistantThreads.has(threadId)) {
|
|
5313
|
+
return assistantThreads.delete(threadId);
|
|
5314
|
+
}
|
|
5315
|
+
}
|
|
5316
|
+
return false;
|
|
4952
5317
|
}
|
|
4953
5318
|
/**
|
|
4954
5319
|
* Check if thread exists
|
|
4955
5320
|
*/
|
|
4956
|
-
async hasThread(
|
|
4957
|
-
const
|
|
4958
|
-
if (!
|
|
5321
|
+
async hasThread(tenantId, threadId) {
|
|
5322
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5323
|
+
if (!tenantThreads) {
|
|
4959
5324
|
return false;
|
|
4960
5325
|
}
|
|
4961
|
-
|
|
5326
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5327
|
+
if (assistantThreads.has(threadId)) {
|
|
5328
|
+
return true;
|
|
5329
|
+
}
|
|
5330
|
+
}
|
|
5331
|
+
return false;
|
|
4962
5332
|
}
|
|
4963
5333
|
/**
|
|
4964
|
-
* Clear all threads (useful for testing)
|
|
5334
|
+
* Clear all threads for a tenant (useful for testing)
|
|
4965
5335
|
*/
|
|
4966
|
-
clear() {
|
|
4967
|
-
|
|
5336
|
+
clear(tenantId) {
|
|
5337
|
+
if (tenantId) {
|
|
5338
|
+
this.threads.delete(tenantId);
|
|
5339
|
+
} else {
|
|
5340
|
+
this.threads.clear();
|
|
5341
|
+
}
|
|
4968
5342
|
}
|
|
4969
5343
|
/**
|
|
4970
5344
|
* Get all threads for all assistants (useful for debugging)
|
|
4971
5345
|
*/
|
|
4972
5346
|
getAllThreads() {
|
|
4973
5347
|
const allThreads = [];
|
|
4974
|
-
for (const
|
|
4975
|
-
|
|
5348
|
+
for (const tenantThreads of this.threads.values()) {
|
|
5349
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5350
|
+
allThreads.push(...Array.from(assistantThreads.values()));
|
|
5351
|
+
}
|
|
4976
5352
|
}
|
|
4977
5353
|
return allThreads;
|
|
4978
5354
|
}
|
|
@@ -4984,38 +5360,50 @@ var InMemoryAssistantStore = class {
|
|
|
4984
5360
|
this.assistants = /* @__PURE__ */ new Map();
|
|
4985
5361
|
}
|
|
4986
5362
|
/**
|
|
4987
|
-
* Get all assistants
|
|
5363
|
+
* Get all assistants for a tenant
|
|
4988
5364
|
*/
|
|
4989
|
-
async getAllAssistants() {
|
|
4990
|
-
|
|
5365
|
+
async getAllAssistants(tenantId) {
|
|
5366
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5367
|
+
if (!tenantAssistants) return [];
|
|
5368
|
+
return Array.from(tenantAssistants.values());
|
|
4991
5369
|
}
|
|
4992
5370
|
/**
|
|
4993
5371
|
* Get assistant by ID
|
|
4994
5372
|
*/
|
|
4995
|
-
async getAssistantById(id) {
|
|
4996
|
-
|
|
5373
|
+
async getAssistantById(tenantId, id) {
|
|
5374
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5375
|
+
if (!tenantAssistants) return null;
|
|
5376
|
+
return tenantAssistants.get(id) || null;
|
|
4997
5377
|
}
|
|
4998
5378
|
/**
|
|
4999
5379
|
* Create a new assistant
|
|
5000
5380
|
*/
|
|
5001
|
-
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
|
+
}
|
|
5002
5385
|
const now = /* @__PURE__ */ new Date();
|
|
5003
5386
|
const assistant = {
|
|
5004
5387
|
id,
|
|
5388
|
+
tenantId,
|
|
5005
5389
|
name: data.name,
|
|
5006
5390
|
description: data.description,
|
|
5007
5391
|
graphDefinition: data.graphDefinition,
|
|
5008
5392
|
createdAt: now,
|
|
5009
5393
|
updatedAt: now
|
|
5010
5394
|
};
|
|
5011
|
-
this.assistants.set(id, assistant);
|
|
5395
|
+
this.assistants.get(tenantId).set(id, assistant);
|
|
5012
5396
|
return assistant;
|
|
5013
5397
|
}
|
|
5014
5398
|
/**
|
|
5015
5399
|
* Update an existing assistant
|
|
5016
5400
|
*/
|
|
5017
|
-
async updateAssistant(id, updates) {
|
|
5018
|
-
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);
|
|
5019
5407
|
if (!existing) {
|
|
5020
5408
|
return null;
|
|
5021
5409
|
}
|
|
@@ -5024,26 +5412,38 @@ var InMemoryAssistantStore = class {
|
|
|
5024
5412
|
...updates,
|
|
5025
5413
|
updatedAt: /* @__PURE__ */ new Date()
|
|
5026
5414
|
};
|
|
5027
|
-
|
|
5415
|
+
tenantAssistants.set(id, updated);
|
|
5028
5416
|
return updated;
|
|
5029
5417
|
}
|
|
5030
5418
|
/**
|
|
5031
5419
|
* Delete an assistant by ID
|
|
5032
5420
|
*/
|
|
5033
|
-
async deleteAssistant(id) {
|
|
5034
|
-
|
|
5421
|
+
async deleteAssistant(tenantId, id) {
|
|
5422
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5423
|
+
if (!tenantAssistants) {
|
|
5424
|
+
return false;
|
|
5425
|
+
}
|
|
5426
|
+
return tenantAssistants.delete(id);
|
|
5035
5427
|
}
|
|
5036
5428
|
/**
|
|
5037
5429
|
* Check if assistant exists
|
|
5038
5430
|
*/
|
|
5039
|
-
async hasAssistant(id) {
|
|
5040
|
-
|
|
5431
|
+
async hasAssistant(tenantId, id) {
|
|
5432
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5433
|
+
if (!tenantAssistants) {
|
|
5434
|
+
return false;
|
|
5435
|
+
}
|
|
5436
|
+
return tenantAssistants.has(id);
|
|
5041
5437
|
}
|
|
5042
5438
|
/**
|
|
5043
|
-
* Clear all assistants (useful for testing)
|
|
5439
|
+
* Clear all assistants for a tenant (useful for testing)
|
|
5044
5440
|
*/
|
|
5045
|
-
clear() {
|
|
5046
|
-
|
|
5441
|
+
clear(tenantId) {
|
|
5442
|
+
if (tenantId) {
|
|
5443
|
+
this.assistants.delete(tenantId);
|
|
5444
|
+
} else {
|
|
5445
|
+
this.assistants.clear();
|
|
5446
|
+
}
|
|
5047
5447
|
}
|
|
5048
5448
|
};
|
|
5049
5449
|
|
|
@@ -5289,6 +5689,8 @@ var FileSystemSkillStore = class {
|
|
|
5289
5689
|
return {
|
|
5290
5690
|
id: name,
|
|
5291
5691
|
// id equals name (name is used for path addressing)
|
|
5692
|
+
tenantId: "default",
|
|
5693
|
+
// FileSystemSkillStore uses default tenant
|
|
5292
5694
|
name: frontmatter.name,
|
|
5293
5695
|
description: frontmatter.description,
|
|
5294
5696
|
license: frontmatter.license,
|
|
@@ -5336,9 +5738,11 @@ ${body}` : `${frontmatter}
|
|
|
5336
5738
|
await fs.writeFile(filePath, content, "utf-8");
|
|
5337
5739
|
}
|
|
5338
5740
|
/**
|
|
5339
|
-
* 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.
|
|
5340
5744
|
*/
|
|
5341
|
-
async getAllSkills() {
|
|
5745
|
+
async getAllSkills(_tenantId) {
|
|
5342
5746
|
await this.ensureDirectoryExists();
|
|
5343
5747
|
try {
|
|
5344
5748
|
const entries = await fs.readdir(this.rootDir, { withFileTypes: true });
|
|
@@ -5375,17 +5779,19 @@ ${body}` : `${frontmatter}
|
|
|
5375
5779
|
}
|
|
5376
5780
|
}
|
|
5377
5781
|
/**
|
|
5378
|
-
* Get skill by ID
|
|
5782
|
+
* Get skill by ID for a tenant
|
|
5379
5783
|
* ID should equal name (name is used for path addressing)
|
|
5784
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5380
5785
|
*/
|
|
5381
|
-
async getSkillById(id) {
|
|
5786
|
+
async getSkillById(_tenantId, id) {
|
|
5382
5787
|
return this.readSkillFile(id);
|
|
5383
5788
|
}
|
|
5384
5789
|
/**
|
|
5385
|
-
* Create a new skill
|
|
5790
|
+
* Create a new skill for a tenant
|
|
5386
5791
|
* id should equal name (name is used for path addressing)
|
|
5792
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5387
5793
|
*/
|
|
5388
|
-
async createSkill(id, data) {
|
|
5794
|
+
async createSkill(_tenantId, id, data) {
|
|
5389
5795
|
await this.ensureDirectoryExists();
|
|
5390
5796
|
validateSkillName(data.name);
|
|
5391
5797
|
if (id !== data.name) {
|
|
@@ -5393,14 +5799,15 @@ ${body}` : `${frontmatter}
|
|
|
5393
5799
|
`Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
|
|
5394
5800
|
);
|
|
5395
5801
|
}
|
|
5396
|
-
const existing = await this.getSkillById(id);
|
|
5802
|
+
const existing = await this.getSkillById(_tenantId, id);
|
|
5397
5803
|
if (existing) {
|
|
5398
|
-
return this.updateSkill(id, data);
|
|
5804
|
+
return this.updateSkill(_tenantId, id, data);
|
|
5399
5805
|
}
|
|
5400
5806
|
const now = /* @__PURE__ */ new Date();
|
|
5401
5807
|
const skill = {
|
|
5402
5808
|
id: data.name,
|
|
5403
5809
|
// id equals name
|
|
5810
|
+
tenantId: _tenantId,
|
|
5404
5811
|
name: data.name,
|
|
5405
5812
|
description: data.description,
|
|
5406
5813
|
license: data.license,
|
|
@@ -5415,9 +5822,10 @@ ${body}` : `${frontmatter}
|
|
|
5415
5822
|
return skill;
|
|
5416
5823
|
}
|
|
5417
5824
|
/**
|
|
5418
|
-
* 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
|
|
5419
5827
|
*/
|
|
5420
|
-
async updateSkill(id, updates) {
|
|
5828
|
+
async updateSkill(_tenantId, id, updates) {
|
|
5421
5829
|
const skill = await this.readSkillFile(id);
|
|
5422
5830
|
if (!skill) {
|
|
5423
5831
|
return null;
|
|
@@ -5441,6 +5849,7 @@ ${body}` : `${frontmatter}
|
|
|
5441
5849
|
name: updates.name ?? skill.name,
|
|
5442
5850
|
id: updates.name ?? skill.id,
|
|
5443
5851
|
// id equals name
|
|
5852
|
+
tenantId: _tenantId,
|
|
5444
5853
|
description: updates.description ?? skill.description,
|
|
5445
5854
|
license: updates.license ?? skill.license,
|
|
5446
5855
|
compatibility: updates.compatibility ?? skill.compatibility,
|
|
@@ -5453,10 +5862,11 @@ ${body}` : `${frontmatter}
|
|
|
5453
5862
|
return updatedSkill;
|
|
5454
5863
|
}
|
|
5455
5864
|
/**
|
|
5456
|
-
* Delete a skill by ID
|
|
5865
|
+
* Delete a skill by ID for a tenant
|
|
5457
5866
|
* Deletes the entire directory (name is the directory name)
|
|
5867
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5458
5868
|
*/
|
|
5459
|
-
async deleteSkill(id) {
|
|
5869
|
+
async deleteSkill(_tenantId, id) {
|
|
5460
5870
|
await this.ensureDirectoryExists();
|
|
5461
5871
|
const skillDir = this.getSkillDirectoryPath(id);
|
|
5462
5872
|
try {
|
|
@@ -5470,50 +5880,55 @@ ${body}` : `${frontmatter}
|
|
|
5470
5880
|
}
|
|
5471
5881
|
}
|
|
5472
5882
|
/**
|
|
5473
|
-
* 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
|
|
5474
5885
|
*/
|
|
5475
|
-
async hasSkill(id) {
|
|
5476
|
-
const skill = await this.getSkillById(id);
|
|
5886
|
+
async hasSkill(_tenantId, id) {
|
|
5887
|
+
const skill = await this.getSkillById(_tenantId, id);
|
|
5477
5888
|
return skill !== null;
|
|
5478
5889
|
}
|
|
5479
5890
|
/**
|
|
5480
|
-
* 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
|
|
5481
5893
|
*/
|
|
5482
|
-
async searchByMetadata(metadataKey, metadataValue) {
|
|
5483
|
-
const allSkills = await this.getAllSkills();
|
|
5894
|
+
async searchByMetadata(_tenantId, metadataKey, metadataValue) {
|
|
5895
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5484
5896
|
return allSkills.filter((skill) => {
|
|
5485
5897
|
return skill.metadata && skill.metadata[metadataKey] === metadataValue;
|
|
5486
5898
|
});
|
|
5487
5899
|
}
|
|
5488
5900
|
/**
|
|
5489
|
-
* 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
|
|
5490
5903
|
*/
|
|
5491
|
-
async filterByCompatibility(compatibility) {
|
|
5492
|
-
const allSkills = await this.getAllSkills();
|
|
5904
|
+
async filterByCompatibility(_tenantId, compatibility) {
|
|
5905
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5493
5906
|
return allSkills.filter((skill) => {
|
|
5494
5907
|
return skill.compatibility === compatibility;
|
|
5495
5908
|
});
|
|
5496
5909
|
}
|
|
5497
5910
|
/**
|
|
5498
|
-
* 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
|
|
5499
5913
|
*/
|
|
5500
|
-
async filterByLicense(license) {
|
|
5501
|
-
const allSkills = await this.getAllSkills();
|
|
5914
|
+
async filterByLicense(_tenantId, license) {
|
|
5915
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5502
5916
|
return allSkills.filter((skill) => {
|
|
5503
5917
|
return skill.license === license;
|
|
5504
5918
|
});
|
|
5505
5919
|
}
|
|
5506
5920
|
/**
|
|
5507
|
-
* 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
|
|
5508
5923
|
*/
|
|
5509
|
-
async getSubSkills(parentSkillName) {
|
|
5510
|
-
const parentSkill = await this.getSkillById(parentSkillName);
|
|
5924
|
+
async getSubSkills(_tenantId, parentSkillName) {
|
|
5925
|
+
const parentSkill = await this.getSkillById(_tenantId, parentSkillName);
|
|
5511
5926
|
if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
|
|
5512
5927
|
return [];
|
|
5513
5928
|
}
|
|
5514
5929
|
const subSkills = [];
|
|
5515
5930
|
for (const subSkillName of parentSkill.subSkills) {
|
|
5516
|
-
const subSkill = await this.getSkillById(subSkillName);
|
|
5931
|
+
const subSkill = await this.getSkillById(_tenantId, subSkillName);
|
|
5517
5932
|
if (subSkill) {
|
|
5518
5933
|
subSkills.push(subSkill);
|
|
5519
5934
|
}
|
|
@@ -5522,10 +5937,11 @@ ${body}` : `${frontmatter}
|
|
|
5522
5937
|
}
|
|
5523
5938
|
/**
|
|
5524
5939
|
* List all resources in a skill's resources directory
|
|
5940
|
+
* @param tenantId The tenant identifier (accepted for protocol compliance)
|
|
5525
5941
|
* @param skillName The skill name
|
|
5526
5942
|
* @returns Array of resource paths relative to resources/ directory
|
|
5527
5943
|
*/
|
|
5528
|
-
async listSkillResources(skillName) {
|
|
5944
|
+
async listSkillResources(_tenantId, skillName) {
|
|
5529
5945
|
const skillDir = this.getSkillDirectoryPath(skillName);
|
|
5530
5946
|
const resourcesDir = path3.join(skillDir, "resources");
|
|
5531
5947
|
try {
|
|
@@ -5548,11 +5964,12 @@ ${body}` : `${frontmatter}
|
|
|
5548
5964
|
}
|
|
5549
5965
|
/**
|
|
5550
5966
|
* Load a specific resource from a skill's resources directory
|
|
5967
|
+
* @param tenantId The tenant identifier (accepted for protocol compliance)
|
|
5551
5968
|
* @param skillName The skill name
|
|
5552
5969
|
* @param resourcePath Path to the resource relative to resources/ directory
|
|
5553
5970
|
* @returns The resource content as string
|
|
5554
5971
|
*/
|
|
5555
|
-
async loadSkillResource(skillName, resourcePath) {
|
|
5972
|
+
async loadSkillResource(_tenantId, skillName, resourcePath) {
|
|
5556
5973
|
const skillDir = this.getSkillDirectoryPath(skillName);
|
|
5557
5974
|
const resourcesDir = path3.join(skillDir, "resources");
|
|
5558
5975
|
const fullPath = path3.join(resourcesDir, resourcePath);
|
|
@@ -6289,93 +6706,520 @@ var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager
|
|
|
6289
6706
|
return storeLattice;
|
|
6290
6707
|
}
|
|
6291
6708
|
/**
|
|
6292
|
-
* Get StoreLattice without type checking (for backward compatibility)
|
|
6293
|
-
* @param key Lattice key name
|
|
6294
|
-
* @param type Store type
|
|
6295
|
-
* @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
|
|
6296
7115
|
*/
|
|
6297
|
-
|
|
6298
|
-
const
|
|
6299
|
-
|
|
6300
|
-
|
|
6301
|
-
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;
|
|
6302
7120
|
}
|
|
6303
|
-
|
|
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;
|
|
6304
7154
|
}
|
|
6305
7155
|
/**
|
|
6306
|
-
*
|
|
7156
|
+
* Delete a skill by ID
|
|
6307
7157
|
*/
|
|
6308
|
-
|
|
6309
|
-
|
|
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
|
+
}
|
|
6310
7174
|
}
|
|
6311
7175
|
/**
|
|
6312
|
-
* Check if
|
|
6313
|
-
* Uses composite key (key + type) to check existence
|
|
6314
|
-
* @param key Lattice key name
|
|
6315
|
-
* @param type Store type
|
|
7176
|
+
* Check if skill exists
|
|
6316
7177
|
*/
|
|
6317
|
-
|
|
6318
|
-
const
|
|
6319
|
-
return
|
|
7178
|
+
async hasSkill(tenantId, id) {
|
|
7179
|
+
const skill = await this.getSkillById(tenantId, id);
|
|
7180
|
+
return skill !== null;
|
|
6320
7181
|
}
|
|
6321
7182
|
/**
|
|
6322
|
-
*
|
|
6323
|
-
* Uses composite key (key + type) to remove the store
|
|
6324
|
-
* @param key Lattice key name
|
|
6325
|
-
* @param type Store type
|
|
7183
|
+
* Search skills by metadata within a tenant
|
|
6326
7184
|
*/
|
|
6327
|
-
|
|
6328
|
-
const
|
|
6329
|
-
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
|
+
);
|
|
6330
7190
|
}
|
|
6331
7191
|
/**
|
|
6332
|
-
*
|
|
7192
|
+
* Filter skills by compatibility within a tenant
|
|
6333
7193
|
*/
|
|
6334
|
-
|
|
6335
|
-
this.
|
|
7194
|
+
async filterByCompatibility(tenantId, compatibility) {
|
|
7195
|
+
const allSkills = await this.getAllSkills(tenantId);
|
|
7196
|
+
return allSkills.filter((skill) => skill.compatibility === compatibility);
|
|
6336
7197
|
}
|
|
6337
7198
|
/**
|
|
6338
|
-
*
|
|
7199
|
+
* Filter skills by license within a tenant
|
|
6339
7200
|
*/
|
|
6340
|
-
|
|
6341
|
-
|
|
7201
|
+
async filterByLicense(tenantId, license) {
|
|
7202
|
+
const allSkills = await this.getAllSkills(tenantId);
|
|
7203
|
+
return allSkills.filter((skill) => skill.license === license);
|
|
6342
7204
|
}
|
|
6343
7205
|
/**
|
|
6344
|
-
* Get
|
|
7206
|
+
* Get sub-skills of a parent skill within a tenant
|
|
6345
7207
|
*/
|
|
6346
|
-
|
|
6347
|
-
|
|
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;
|
|
6348
7221
|
}
|
|
6349
7222
|
};
|
|
6350
|
-
var storeLatticeManager = StoreLatticeManager.getInstance();
|
|
6351
|
-
var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
|
|
6352
|
-
var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
|
|
6353
|
-
var defaultThreadStore = new InMemoryThreadStore();
|
|
6354
|
-
var defaultAssistantStore = new InMemoryAssistantStore();
|
|
6355
|
-
var defaultSkillStore = new FileSystemSkillStore();
|
|
6356
|
-
var defaultWorkspaceStore = new InMemoryWorkspaceStore();
|
|
6357
|
-
var defaultProjectStore = new InMemoryProjectStore();
|
|
6358
|
-
var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
|
|
6359
|
-
var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
|
|
6360
|
-
var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
|
|
6361
|
-
storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
|
|
6362
|
-
storeLatticeManager.registerLattice(
|
|
6363
|
-
"default",
|
|
6364
|
-
"assistant",
|
|
6365
|
-
defaultAssistantStore
|
|
6366
|
-
);
|
|
6367
|
-
storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
|
|
6368
|
-
storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
|
|
6369
|
-
storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
|
|
6370
|
-
storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
|
|
6371
|
-
storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
|
|
6372
|
-
storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
|
|
6373
|
-
var defaultUserStore = new InMemoryUserStore();
|
|
6374
|
-
var defaultTenantStore = new InMemoryTenantStore();
|
|
6375
|
-
var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
|
|
6376
|
-
storeLatticeManager.registerLattice("default", "user", defaultUserStore);
|
|
6377
|
-
storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
|
|
6378
|
-
storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
|
|
6379
7223
|
|
|
6380
7224
|
// src/tool_lattice/skill/load_skills.ts
|
|
6381
7225
|
var import_zod41 = __toESM(require("zod"));
|
|
@@ -6414,9 +7258,11 @@ var createLoadSkillContentTool = () => {
|
|
|
6414
7258
|
try {
|
|
6415
7259
|
const storeLattice = getStoreLattice("default", "skill");
|
|
6416
7260
|
const skillStore = storeLattice.store;
|
|
6417
|
-
const
|
|
7261
|
+
const runConfig = _exe_config?.configurable?.runConfig || {};
|
|
7262
|
+
const tenantId = runConfig.tenantId || "default";
|
|
7263
|
+
const skill = await skillStore.getSkillById(tenantId, input.skill_name);
|
|
6418
7264
|
if (!skill) {
|
|
6419
|
-
const allSkills = await skillStore.getAllSkills();
|
|
7265
|
+
const allSkills = await skillStore.getAllSkills(tenantId);
|
|
6420
7266
|
const availableSkills = allSkills.map((s) => s.name).join(", ");
|
|
6421
7267
|
return `Skill "${input.skill_name}" not found. Available skills: ${availableSkills}`;
|
|
6422
7268
|
}
|
|
@@ -6448,7 +7294,7 @@ ${content}`;
|
|
|
6448
7294
|
const fsStore = skillStore;
|
|
6449
7295
|
if (fsStore.listSkillResources) {
|
|
6450
7296
|
try {
|
|
6451
|
-
const resources = await fsStore.listSkillResources(input.skill_name);
|
|
7297
|
+
const resources = await fsStore.listSkillResources(tenantId, input.skill_name);
|
|
6452
7298
|
if (resources.length > 0) {
|
|
6453
7299
|
result += "\n\n---\n\n**Resources** (use `load_skill_resource` tool to access):\n";
|
|
6454
7300
|
resources.forEach((resource) => {
|
|
@@ -6482,7 +7328,8 @@ var createLoadSkillResourceTool = () => {
|
|
|
6482
7328
|
return (0, import_langchain42.tool)(
|
|
6483
7329
|
async (input, _exe_config) => {
|
|
6484
7330
|
try {
|
|
6485
|
-
const
|
|
7331
|
+
const tenantId = _exe_config?.configurable?.runConfig?.tenantId || "default";
|
|
7332
|
+
const storeLattice = getStoreLattice(tenantId, "skill");
|
|
6486
7333
|
const skillStore = storeLattice.store;
|
|
6487
7334
|
const fsStore = skillStore;
|
|
6488
7335
|
if (!fsStore.loadSkillResource) {
|
|
@@ -6522,15 +7369,16 @@ function createSkillMiddleware(params = {}) {
|
|
|
6522
7369
|
createLoadSkillContentTool(),
|
|
6523
7370
|
createLoadSkillResourceTool()
|
|
6524
7371
|
],
|
|
6525
|
-
beforeAgent: async () => {
|
|
7372
|
+
beforeAgent: async (state, runtime) => {
|
|
6526
7373
|
try {
|
|
6527
7374
|
const storeLattice = getStoreLattice("default", "skill");
|
|
6528
7375
|
const skillStore = storeLattice?.store;
|
|
7376
|
+
const tenantId = runtime?.context?.tenantId || state?.tenantId || "default";
|
|
6529
7377
|
if (readAll) {
|
|
6530
|
-
latestSkills = await skillStore.getAllSkills();
|
|
7378
|
+
latestSkills = await skillStore.getAllSkills(tenantId);
|
|
6531
7379
|
} else if (skills && skills.length > 0) {
|
|
6532
7380
|
const skillLatticePromises = skills.map(
|
|
6533
|
-
(skillId) => skillStore.getSkillById(skillId)
|
|
7381
|
+
(skillId) => skillStore.getSkillById(tenantId, skillId)
|
|
6534
7382
|
);
|
|
6535
7383
|
const skillLattices = await Promise.all(skillLatticePromises);
|
|
6536
7384
|
latestSkills = skillLattices.filter((skill) => skill !== void 0);
|
|
@@ -7416,19 +8264,20 @@ ${systemPrompt}` : systemPrompt;
|
|
|
7416
8264
|
var import_langchain45 = require("langchain");
|
|
7417
8265
|
function createMetricsMiddleware(params) {
|
|
7418
8266
|
const { serverKeys, serverDescriptions, connectAll } = params;
|
|
7419
|
-
|
|
7420
|
-
if (connectAll) {
|
|
7421
|
-
effectiveServerKeys = metricsServerManager.getServerKeys().map((s) => s.key);
|
|
7422
|
-
}
|
|
7423
|
-
if (!effectiveServerKeys || effectiveServerKeys.length === 0) {
|
|
8267
|
+
if (!serverKeys || serverKeys.length === 0) {
|
|
7424
8268
|
return (0, import_langchain45.createMiddleware)({
|
|
7425
8269
|
name: "metricsMiddleware",
|
|
7426
8270
|
tools: []
|
|
7427
8271
|
});
|
|
7428
8272
|
}
|
|
7429
8273
|
const toolParams = {
|
|
7430
|
-
serverKeys
|
|
7431
|
-
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
|
|
7432
8281
|
};
|
|
7433
8282
|
return (0, import_langchain45.createMiddleware)({
|
|
7434
8283
|
name: "metricsMiddleware",
|
|
@@ -7561,7 +8410,7 @@ function createAskUserClarifyMiddleware() {
|
|
|
7561
8410
|
}
|
|
7562
8411
|
|
|
7563
8412
|
// src/agent_lattice/builders/commonMiddleware.ts
|
|
7564
|
-
function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
8413
|
+
async function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
7565
8414
|
const middlewares = [];
|
|
7566
8415
|
const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
|
|
7567
8416
|
if (filesystemConfig?.enabled && filesystemBackend) {
|
|
@@ -7616,14 +8465,16 @@ function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
|
7616
8465
|
|
|
7617
8466
|
// src/agent_lattice/builders/ReActAgentGraphBuilder.ts
|
|
7618
8467
|
var ReActAgentGraphBuilder = class {
|
|
7619
|
-
createFilesystemBackendFactory(middlewareConfigs) {
|
|
8468
|
+
createFilesystemBackendFactory(middlewareConfigs, agentLattice) {
|
|
7620
8469
|
const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
|
|
7621
8470
|
if (!filesystemConfig || !filesystemConfig.enabled) {
|
|
7622
8471
|
return void 0;
|
|
7623
8472
|
}
|
|
7624
8473
|
const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
|
|
7625
|
-
|
|
7626
|
-
|
|
8474
|
+
const agentTenantId = agentLattice.config.tenantId;
|
|
8475
|
+
return async (stateAndStore) => {
|
|
8476
|
+
const { tenantId: runtimeTenantId, workspaceId, projectId } = stateAndStore;
|
|
8477
|
+
const tenantId = runtimeTenantId || agentTenantId;
|
|
7627
8478
|
let sandboxName = "global";
|
|
7628
8479
|
if (isolatedLevel === "agent") {
|
|
7629
8480
|
sandboxName = "agent";
|
|
@@ -7634,14 +8485,22 @@ var ReActAgentGraphBuilder = class {
|
|
|
7634
8485
|
if (!sandboxManager) {
|
|
7635
8486
|
throw new Error("Sandbox manager not found");
|
|
7636
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
|
+
}
|
|
7637
8496
|
return new SandboxFilesystem({
|
|
7638
8497
|
sandboxInstance: await sandboxManager.createSandbox(sandboxName),
|
|
7639
|
-
workingDirectory
|
|
8498
|
+
workingDirectory
|
|
7640
8499
|
});
|
|
7641
8500
|
};
|
|
7642
8501
|
}
|
|
7643
|
-
createMiddlewares(middlewareConfigs) {
|
|
7644
|
-
return createCommonMiddlewares(middlewareConfigs);
|
|
8502
|
+
async createMiddlewares(middlewareConfigs) {
|
|
8503
|
+
return await createCommonMiddlewares(middlewareConfigs);
|
|
7645
8504
|
}
|
|
7646
8505
|
/**
|
|
7647
8506
|
* 构建ReAct Agent Graph
|
|
@@ -7650,15 +8509,15 @@ var ReActAgentGraphBuilder = class {
|
|
|
7650
8509
|
* @param params Agent构建参数
|
|
7651
8510
|
* @returns 返回CompiledGraph对象
|
|
7652
8511
|
*/
|
|
7653
|
-
build(agentLattice, params) {
|
|
8512
|
+
async build(agentLattice, params) {
|
|
7654
8513
|
const tools = params.tools.map((t) => {
|
|
7655
8514
|
const tool48 = getToolClient(t.key);
|
|
7656
8515
|
return tool48;
|
|
7657
8516
|
}).filter((tool48) => tool48 !== void 0);
|
|
7658
8517
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
7659
8518
|
const middlewareConfigs = params.middleware || [];
|
|
7660
|
-
const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs);
|
|
7661
|
-
const middlewares = createCommonMiddlewares(middlewareConfigs, filesystemBackend);
|
|
8519
|
+
const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs, agentLattice);
|
|
8520
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs, filesystemBackend);
|
|
7662
8521
|
return (0, import_langchain48.createAgent)({
|
|
7663
8522
|
model: params.model,
|
|
7664
8523
|
tools,
|
|
@@ -8479,14 +9338,18 @@ var StoreBackend = class {
|
|
|
8479
9338
|
/**
|
|
8480
9339
|
* Get the namespace for store operations.
|
|
8481
9340
|
*
|
|
8482
|
-
* If
|
|
8483
|
-
* [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"].
|
|
8484
9344
|
* Otherwise return ["filesystem"].
|
|
8485
9345
|
*/
|
|
8486
9346
|
getNamespace() {
|
|
8487
9347
|
const namespace = "filesystem";
|
|
9348
|
+
const tenantId = this.stateAndStore.tenantId;
|
|
8488
9349
|
const assistantId = this.stateAndStore.assistantId;
|
|
8489
|
-
if (assistantId) {
|
|
9350
|
+
if (tenantId && assistantId) {
|
|
9351
|
+
return [tenantId, assistantId, namespace];
|
|
9352
|
+
} else if (assistantId) {
|
|
8490
9353
|
return [assistantId, namespace];
|
|
8491
9354
|
}
|
|
8492
9355
|
return [namespace];
|
|
@@ -9913,8 +10776,8 @@ function createFilesystemBackendFactory(middlewareConfigs) {
|
|
|
9913
10776
|
return void 0;
|
|
9914
10777
|
}
|
|
9915
10778
|
const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
|
|
9916
|
-
return async (
|
|
9917
|
-
const { workspaceId, projectId } =
|
|
10779
|
+
return async (stateAndStore) => {
|
|
10780
|
+
const { tenantId, workspaceId, projectId } = stateAndStore;
|
|
9918
10781
|
let sandboxName = "global";
|
|
9919
10782
|
if (isolatedLevel === "agent") {
|
|
9920
10783
|
sandboxName = "agent";
|
|
@@ -9925,9 +10788,17 @@ function createFilesystemBackendFactory(middlewareConfigs) {
|
|
|
9925
10788
|
if (!sandboxManager) {
|
|
9926
10789
|
throw new Error("Sandbox manager not found");
|
|
9927
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
|
+
}
|
|
9928
10799
|
return new SandboxFilesystem({
|
|
9929
10800
|
sandboxInstance: await sandboxManager.createSandbox(sandboxName),
|
|
9930
|
-
workingDirectory
|
|
10801
|
+
workingDirectory
|
|
9931
10802
|
});
|
|
9932
10803
|
};
|
|
9933
10804
|
}
|
|
@@ -9937,8 +10808,8 @@ var DeepAgentGraphBuilder = class {
|
|
|
9937
10808
|
/**
|
|
9938
10809
|
* 根据 middleware 配置创建 middlewares
|
|
9939
10810
|
*/
|
|
9940
|
-
createMiddlewares(middlewareConfigs) {
|
|
9941
|
-
return createCommonMiddlewares(middlewareConfigs);
|
|
10811
|
+
async createMiddlewares(middlewareConfigs) {
|
|
10812
|
+
return await createCommonMiddlewares(middlewareConfigs);
|
|
9942
10813
|
}
|
|
9943
10814
|
/**
|
|
9944
10815
|
* 构建Deep Agent Graph
|
|
@@ -9947,12 +10818,12 @@ var DeepAgentGraphBuilder = class {
|
|
|
9947
10818
|
* @param params Agent构建参数
|
|
9948
10819
|
* @returns 返回CompiledGraph对象
|
|
9949
10820
|
*/
|
|
9950
|
-
build(agentLattice, params) {
|
|
10821
|
+
async build(agentLattice, params) {
|
|
9951
10822
|
const tools = params.tools.map((t) => {
|
|
9952
10823
|
const toolClient = getToolClient(t.key);
|
|
9953
10824
|
return toolClient;
|
|
9954
10825
|
}).filter((tool48) => tool48 !== void 0);
|
|
9955
|
-
const subagents = params.subAgents.map((sa) => {
|
|
10826
|
+
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
9956
10827
|
if (sa.client) {
|
|
9957
10828
|
return {
|
|
9958
10829
|
key: sa.config.key,
|
|
@@ -9961,7 +10832,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
9961
10832
|
runnable: sa.client
|
|
9962
10833
|
};
|
|
9963
10834
|
} else {
|
|
9964
|
-
const subagentClient = createAgentClientFromAgentLattice({
|
|
10835
|
+
const subagentClient = await createAgentClientFromAgentLattice({
|
|
9965
10836
|
config: sa.config
|
|
9966
10837
|
});
|
|
9967
10838
|
return {
|
|
@@ -9971,10 +10842,10 @@ var DeepAgentGraphBuilder = class {
|
|
|
9971
10842
|
runnable: subagentClient
|
|
9972
10843
|
};
|
|
9973
10844
|
}
|
|
9974
|
-
});
|
|
10845
|
+
}));
|
|
9975
10846
|
const middlewareConfigs = params.middleware || [];
|
|
9976
10847
|
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
9977
|
-
const middlewares = this.createMiddlewares(middlewareConfigs);
|
|
10848
|
+
const middlewares = await this.createMiddlewares(middlewareConfigs);
|
|
9978
10849
|
const deepAgent = createDeepAgent({
|
|
9979
10850
|
tools,
|
|
9980
10851
|
model: params.model,
|
|
@@ -11550,7 +12421,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
11550
12421
|
* @param params - Build params with resolved tools and model
|
|
11551
12422
|
* @returns AgentClient (the TeamLead ReactAgent)
|
|
11552
12423
|
*/
|
|
11553
|
-
build(agentLattice, params) {
|
|
12424
|
+
async build(agentLattice, params) {
|
|
11554
12425
|
const config = agentLattice.config;
|
|
11555
12426
|
if (!(0, import_protocols.isTeamAgentConfig)(config)) {
|
|
11556
12427
|
throw new Error(
|
|
@@ -11573,7 +12444,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
11573
12444
|
});
|
|
11574
12445
|
const middlewareConfigs = params.middleware || [];
|
|
11575
12446
|
let filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
11576
|
-
const middlewares = createCommonMiddlewares(middlewareConfigs);
|
|
12447
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs);
|
|
11577
12448
|
if (!filesystemBackend) {
|
|
11578
12449
|
filesystemBackend = async (config2) => {
|
|
11579
12450
|
return new StateBackend(config2);
|
|
@@ -11752,6 +12623,31 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11752
12623
|
this.initialized = false;
|
|
11753
12624
|
this.subscribeToAssistantEvents();
|
|
11754
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
|
+
}
|
|
11755
12651
|
/**
|
|
11756
12652
|
* 获取AgentLatticeManager单例实例
|
|
11757
12653
|
*/
|
|
@@ -11761,11 +12657,15 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11761
12657
|
}
|
|
11762
12658
|
return _AgentLatticeManager._instance;
|
|
11763
12659
|
}
|
|
12660
|
+
/**
|
|
12661
|
+
* @deprecated This method loads assistants only for the "default" tenant.
|
|
12662
|
+
* Use initializeStoredAssistantsForTenant(tenantId) for proper tenant isolation.
|
|
12663
|
+
*/
|
|
11764
12664
|
async initializeStoredAssistants() {
|
|
11765
12665
|
if (this.initialized) return;
|
|
11766
12666
|
try {
|
|
11767
12667
|
const storeLattice = getStoreLattice("default", "assistant");
|
|
11768
|
-
const assistants = await storeLattice.store.getAllAssistants();
|
|
12668
|
+
const assistants = await storeLattice.store.getAllAssistants("default");
|
|
11769
12669
|
for (const assistant of assistants) {
|
|
11770
12670
|
if (this.has(assistant.id)) continue;
|
|
11771
12671
|
const config = assistantToConfig(assistant);
|
|
@@ -11778,33 +12678,33 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11778
12678
|
}
|
|
11779
12679
|
subscribeToAssistantEvents() {
|
|
11780
12680
|
event_bus_default.subscribe("assistant:created", (data) => {
|
|
11781
|
-
this.handleAssistantChange(data.id);
|
|
12681
|
+
this.handleAssistantChange(data.id, data.tenantId ?? "default");
|
|
11782
12682
|
});
|
|
11783
12683
|
event_bus_default.subscribe("assistant:updated", (data) => {
|
|
11784
|
-
this.handleAssistantChange(data.id);
|
|
12684
|
+
this.handleAssistantChange(data.id, data.tenantId ?? "default");
|
|
11785
12685
|
});
|
|
11786
12686
|
event_bus_default.subscribe("assistant:deleted", (data) => {
|
|
11787
|
-
this.handleAssistantDelete(data.id);
|
|
12687
|
+
this.handleAssistantDelete(data.id, data.tenantId ?? "default");
|
|
11788
12688
|
});
|
|
11789
12689
|
}
|
|
11790
|
-
async handleAssistantChange(assistantId) {
|
|
12690
|
+
async handleAssistantChange(assistantId, tenantId = "default") {
|
|
11791
12691
|
try {
|
|
11792
12692
|
const storeLattice = getStoreLattice("default", "assistant");
|
|
11793
|
-
const assistant = await storeLattice.store.getAssistantById(assistantId);
|
|
12693
|
+
const assistant = await storeLattice.store.getAssistantById(tenantId, assistantId);
|
|
11794
12694
|
if (assistant) {
|
|
11795
|
-
if (this.
|
|
11796
|
-
this.
|
|
12695
|
+
if (this.hasWithTenant(tenantId, assistantId)) {
|
|
12696
|
+
this.removeWithTenant(tenantId, assistantId);
|
|
11797
12697
|
}
|
|
11798
12698
|
const config = assistantToConfig(assistant);
|
|
11799
|
-
this.
|
|
12699
|
+
this.registerLatticeWithTenant(tenantId, config);
|
|
11800
12700
|
}
|
|
11801
12701
|
} catch (error) {
|
|
11802
|
-
console.error(`Failed to handle assistant change for ${assistantId}:`, error);
|
|
12702
|
+
console.error(`Failed to handle assistant change for ${assistantId} (tenant: ${tenantId}):`, error);
|
|
11803
12703
|
}
|
|
11804
12704
|
}
|
|
11805
|
-
handleAssistantDelete(assistantId) {
|
|
11806
|
-
if (this.
|
|
11807
|
-
this.
|
|
12705
|
+
handleAssistantDelete(assistantId, tenantId = "default") {
|
|
12706
|
+
if (this.hasWithTenant(tenantId, assistantId)) {
|
|
12707
|
+
this.removeWithTenant(tenantId, assistantId);
|
|
11808
12708
|
}
|
|
11809
12709
|
}
|
|
11810
12710
|
/**
|
|
@@ -11813,8 +12713,96 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11813
12713
|
getLatticeType() {
|
|
11814
12714
|
return "agents";
|
|
11815
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 租户) ==========
|
|
11816
12803
|
/**
|
|
11817
|
-
* 注册Agent Lattice
|
|
12804
|
+
* 注册Agent Lattice(向后兼容,使用 "default" 租户)
|
|
12805
|
+
* @deprecated Use registerLatticeWithTenant(tenantId, config) instead
|
|
11818
12806
|
* @param config Agent配置
|
|
11819
12807
|
*/
|
|
11820
12808
|
registerLattice(config) {
|
|
@@ -11852,7 +12840,8 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11852
12840
|
return this.remove(key);
|
|
11853
12841
|
}
|
|
11854
12842
|
/**
|
|
11855
|
-
* 获取AgentLattice
|
|
12843
|
+
* 获取AgentLattice(向后兼容,使用 "default" 租户)
|
|
12844
|
+
* @deprecated Use getAgentLatticeWithTenant(tenantId, key) instead
|
|
11856
12845
|
* @param key Lattice键名
|
|
11857
12846
|
*/
|
|
11858
12847
|
getAgentLattice(key) {
|
|
@@ -11865,25 +12854,28 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11865
12854
|
return this.getAll();
|
|
11866
12855
|
}
|
|
11867
12856
|
/**
|
|
11868
|
-
* 检查Lattice
|
|
12857
|
+
* 检查Lattice是否存在(向后兼容,使用 "default" 租户)
|
|
12858
|
+
* @deprecated Use hasAgentLatticeWithTenant(tenantId, key) instead
|
|
11869
12859
|
* @param key Lattice键名
|
|
11870
12860
|
*/
|
|
11871
12861
|
hasLattice(key) {
|
|
11872
12862
|
return this.has(key);
|
|
11873
12863
|
}
|
|
11874
12864
|
/**
|
|
11875
|
-
* 移除Lattice
|
|
12865
|
+
* 移除Lattice(向后兼容,使用 "default" 租户)
|
|
12866
|
+
* @deprecated Use removeAgentLatticeWithTenant(tenantId, key) instead
|
|
11876
12867
|
* @param key Lattice键名
|
|
11877
12868
|
*/
|
|
11878
12869
|
removeLattice(key) {
|
|
11879
12870
|
return this.remove(key);
|
|
11880
12871
|
}
|
|
11881
12872
|
/**
|
|
11882
|
-
* 获取Agent
|
|
12873
|
+
* 获取Agent配置(向后兼容,使用 "default" 租户)
|
|
12874
|
+
* @deprecated Use getAgentConfigWithTenant(tenantId, key) instead
|
|
11883
12875
|
* @param key Lattice键名
|
|
11884
12876
|
*/
|
|
11885
12877
|
getAgentConfig(key) {
|
|
11886
|
-
return this.
|
|
12878
|
+
return this.getAgentLatticeWithTenant("default", key)?.config;
|
|
11887
12879
|
}
|
|
11888
12880
|
/**
|
|
11889
12881
|
* 获取所有Agent配置
|
|
@@ -11904,8 +12896,9 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11904
12896
|
return false;
|
|
11905
12897
|
}
|
|
11906
12898
|
try {
|
|
11907
|
-
|
|
11908
|
-
|
|
12899
|
+
const config = agentLattice.config;
|
|
12900
|
+
if ("schema" in config && config.schema) {
|
|
12901
|
+
config.schema.parse(input);
|
|
11909
12902
|
}
|
|
11910
12903
|
return true;
|
|
11911
12904
|
} catch {
|
|
@@ -11953,9 +12946,10 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11953
12946
|
* @returns 返回Agent构建参数
|
|
11954
12947
|
*/
|
|
11955
12948
|
buildAgentParams(agentLattice, options) {
|
|
12949
|
+
const tenantId = agentLattice.config.tenantId || "default";
|
|
11956
12950
|
const paramsBuilder = new AgentParamsBuilder((key) => {
|
|
11957
|
-
this.initializeClient(key);
|
|
11958
|
-
return this.
|
|
12951
|
+
this.initializeClient(tenantId, key);
|
|
12952
|
+
return this.getAgentLatticeWithTenant(tenantId, key);
|
|
11959
12953
|
});
|
|
11960
12954
|
return paramsBuilder.buildParams(agentLattice, options);
|
|
11961
12955
|
}
|
|
@@ -11966,7 +12960,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11966
12960
|
* @param options Build options
|
|
11967
12961
|
* @returns AgentClient instance
|
|
11968
12962
|
*/
|
|
11969
|
-
createAgentClientFromConfig(agentLattice, options) {
|
|
12963
|
+
async createAgentClientFromConfig(agentLattice, options) {
|
|
11970
12964
|
const resolvedConfig = this.resolveInheritedConfig(agentLattice.config);
|
|
11971
12965
|
const resolvedLattice = {
|
|
11972
12966
|
...agentLattice,
|
|
@@ -11975,26 +12969,50 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11975
12969
|
const factory = AgentGraphBuilderFactory.getInstance();
|
|
11976
12970
|
const builder = factory.getBuilder(resolvedConfig.type);
|
|
11977
12971
|
const params = this.buildAgentParams(resolvedLattice, options);
|
|
11978
|
-
return builder.build(resolvedLattice, params);
|
|
12972
|
+
return await builder.build(resolvedLattice, params);
|
|
11979
12973
|
}
|
|
11980
12974
|
/**
|
|
11981
12975
|
* 初始化Agent客户端
|
|
11982
12976
|
*
|
|
11983
12977
|
* 使用AgentGraphBuilderFactory构建Graph并设置为客户端
|
|
11984
12978
|
*
|
|
12979
|
+
* @param tenantId 租户ID
|
|
11985
12980
|
* @param key Lattice键名
|
|
11986
12981
|
* @param options 构建选项
|
|
11987
12982
|
* @returns 返回CompiledGraph对象
|
|
11988
12983
|
*/
|
|
11989
|
-
initializeClient(key, options) {
|
|
11990
|
-
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);
|
|
11991
13009
|
if (!agentLattice) {
|
|
11992
|
-
throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728`);
|
|
13010
|
+
throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
|
|
11993
13011
|
}
|
|
11994
13012
|
if (agentLattice.client) {
|
|
11995
13013
|
return agentLattice.client;
|
|
11996
13014
|
}
|
|
11997
|
-
const graph = this.createAgentClientFromConfig(agentLattice, options);
|
|
13015
|
+
const graph = await this.createAgentClientFromConfig(agentLattice, options);
|
|
11998
13016
|
agentLattice.client = graph;
|
|
11999
13017
|
return graph;
|
|
12000
13018
|
}
|
|
@@ -12003,19 +13021,24 @@ var agentLatticeManager = AgentLatticeManager.getInstance();
|
|
|
12003
13021
|
var registerAgentLattice = (config) => {
|
|
12004
13022
|
agentLatticeManager.registerLattice(config);
|
|
12005
13023
|
};
|
|
12006
|
-
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
|
+
}
|
|
12007
13031
|
configs.forEach((config) => {
|
|
12008
|
-
agentLatticeManager.
|
|
13032
|
+
agentLatticeManager.registerLatticeWithTenant(tenantId, config);
|
|
12009
13033
|
});
|
|
12010
13034
|
};
|
|
12011
|
-
var getAgentLattice = (key) => agentLatticeManager.getAgentLattice(key);
|
|
12012
13035
|
var getAgentConfig = (key) => agentLatticeManager.getAgentConfig(key);
|
|
12013
13036
|
var getAllAgentConfigs = () => agentLatticeManager.getAllAgentConfigs();
|
|
12014
13037
|
var validateAgentInput = (key, input) => agentLatticeManager.validateAgentInput(key, input);
|
|
12015
13038
|
var registerTeammateAgent = (key, client) => agentLatticeManager.registerTeammateAgent(key, client);
|
|
12016
13039
|
var unregisterTeammateAgent = (key) => agentLatticeManager.unregisterTeammateAgent(key);
|
|
12017
|
-
var getAgentClient = (key, options) => agentLatticeManager.initializeClient(key, options);
|
|
12018
|
-
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);
|
|
12019
13042
|
|
|
12020
13043
|
// src/chunk_buffer_lattice/ChunkBuffer.ts
|
|
12021
13044
|
var ChunkBuffer = class {
|
|
@@ -12093,6 +13116,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12093
13116
|
buffer = {
|
|
12094
13117
|
threadId,
|
|
12095
13118
|
chunks$: new import_rxjs.ReplaySubject(this.config.maxChunks),
|
|
13119
|
+
chunks: [],
|
|
12096
13120
|
status: "active" /* ACTIVE */,
|
|
12097
13121
|
createdAt: now,
|
|
12098
13122
|
updatedAt: now,
|
|
@@ -12103,14 +13127,27 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12103
13127
|
if (buffer.status !== "active" /* ACTIVE */) {
|
|
12104
13128
|
buffer.status = "active" /* ACTIVE */;
|
|
12105
13129
|
buffer.chunks$ = new import_rxjs.ReplaySubject(this.config.maxChunks);
|
|
13130
|
+
buffer.chunks = [];
|
|
12106
13131
|
buffer.updatedAt = Date.now();
|
|
12107
13132
|
buffer.expiresAt = Date.now() + this.config.ttl;
|
|
12108
13133
|
}
|
|
12109
13134
|
return buffer;
|
|
12110
13135
|
}
|
|
12111
|
-
async addChunk(threadId,
|
|
13136
|
+
async addChunk(threadId, arg2, arg3) {
|
|
12112
13137
|
const buffer = this.getOrCreateBuffer(threadId);
|
|
12113
|
-
|
|
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);
|
|
12114
13151
|
buffer.chunks$.next(chunk);
|
|
12115
13152
|
buffer.updatedAt = Date.now();
|
|
12116
13153
|
buffer.expiresAt = Date.now() + this.config.ttl;
|
|
@@ -12142,7 +13179,25 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12142
13179
|
async getThreadBuffer(threadId) {
|
|
12143
13180
|
const buffer = this.getBufferIfValid(threadId);
|
|
12144
13181
|
if (!buffer) return void 0;
|
|
12145
|
-
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);
|
|
12146
13201
|
}
|
|
12147
13202
|
async clearThread(threadId) {
|
|
12148
13203
|
this.buffers.delete(threadId);
|
|
@@ -12272,6 +13327,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12272
13327
|
let activeCount = 0;
|
|
12273
13328
|
let completedCount = 0;
|
|
12274
13329
|
let abortedCount = 0;
|
|
13330
|
+
let totalChunkCount = 0;
|
|
12275
13331
|
const validBuffers = [];
|
|
12276
13332
|
for (const [threadId, buffer] of this.buffers.entries()) {
|
|
12277
13333
|
if (this.isExpired(buffer)) {
|
|
@@ -12292,12 +13348,14 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12292
13348
|
abortedCount++;
|
|
12293
13349
|
break;
|
|
12294
13350
|
}
|
|
13351
|
+
totalChunkCount += buffer.chunks.length;
|
|
12295
13352
|
}
|
|
12296
13353
|
return {
|
|
12297
13354
|
totalThreads: validBuffers.length,
|
|
12298
13355
|
activeThreads: activeCount,
|
|
12299
13356
|
completedThreads: completedCount,
|
|
12300
13357
|
abortedThreads: abortedCount,
|
|
13358
|
+
totalChunks: totalChunkCount,
|
|
12301
13359
|
config: this.config
|
|
12302
13360
|
};
|
|
12303
13361
|
}
|
|
@@ -12458,6 +13516,9 @@ var MemoryScheduleStorage = class {
|
|
|
12458
13516
|
let result = [];
|
|
12459
13517
|
for (const task of this.tasks.values()) {
|
|
12460
13518
|
let match = true;
|
|
13519
|
+
if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
|
|
13520
|
+
match = false;
|
|
13521
|
+
}
|
|
12461
13522
|
if (filters?.status !== void 0 && task.status !== filters.status) {
|
|
12462
13523
|
match = false;
|
|
12463
13524
|
}
|
|
@@ -12494,6 +13555,9 @@ var MemoryScheduleStorage = class {
|
|
|
12494
13555
|
let count = 0;
|
|
12495
13556
|
for (const task of this.tasks.values()) {
|
|
12496
13557
|
let match = true;
|
|
13558
|
+
if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
|
|
13559
|
+
match = false;
|
|
13560
|
+
}
|
|
12497
13561
|
if (filters?.status !== void 0 && task.status !== filters.status) {
|
|
12498
13562
|
match = false;
|
|
12499
13563
|
}
|
|
@@ -13831,6 +14895,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13831
14895
|
getLatticeType() {
|
|
13832
14896
|
return "skills";
|
|
13833
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
|
+
}
|
|
13834
14906
|
/**
|
|
13835
14907
|
* Configure store for persistence
|
|
13836
14908
|
* @param storeKey Store key name registered in StoreLatticeManager
|
|
@@ -13871,12 +14943,13 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13871
14943
|
client.store = store;
|
|
13872
14944
|
}
|
|
13873
14945
|
/**
|
|
13874
|
-
* Register a skill Lattice
|
|
14946
|
+
* Register a skill Lattice with tenant
|
|
14947
|
+
* @param tenantId Tenant ID
|
|
13875
14948
|
* @param key Lattice key name
|
|
13876
14949
|
* @param config Skill configuration
|
|
13877
14950
|
* @param client Optional skill client implementation
|
|
13878
14951
|
*/
|
|
13879
|
-
async
|
|
14952
|
+
async registerLatticeWithTenant(tenantId, key, config, client) {
|
|
13880
14953
|
if (!config.name) {
|
|
13881
14954
|
throw new Error("Skill name is required");
|
|
13882
14955
|
}
|
|
@@ -13898,10 +14971,10 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13898
14971
|
config,
|
|
13899
14972
|
client: client ?? null
|
|
13900
14973
|
};
|
|
13901
|
-
this.
|
|
14974
|
+
this.registerWithTenant(tenantId, key, skillLattice);
|
|
13902
14975
|
if (store) {
|
|
13903
14976
|
try {
|
|
13904
|
-
await store.createSkill(key, {
|
|
14977
|
+
await store.createSkill(tenantId, key, {
|
|
13905
14978
|
name: config.name,
|
|
13906
14979
|
description: config.description,
|
|
13907
14980
|
license: config.license,
|
|
@@ -13919,24 +14992,43 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13919
14992
|
}
|
|
13920
14993
|
}
|
|
13921
14994
|
/**
|
|
13922
|
-
*
|
|
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
|
|
13923
15015
|
* @param key Lattice key name
|
|
13924
15016
|
*/
|
|
13925
15017
|
getSkillLattice(key) {
|
|
13926
|
-
return this.
|
|
15018
|
+
return this.getWithTenant(this.getDefaultTenantId(), key);
|
|
13927
15019
|
}
|
|
13928
15020
|
/**
|
|
13929
|
-
* Get all skill Lattices from store
|
|
13930
|
-
*
|
|
15021
|
+
* Get all skill Lattices from store with tenant
|
|
15022
|
+
* @param tenantId Tenant ID
|
|
13931
15023
|
*/
|
|
13932
|
-
async
|
|
15024
|
+
async getAllLatticesWithTenant(tenantId) {
|
|
13933
15025
|
const store = this.getStore();
|
|
13934
15026
|
if (!store) {
|
|
13935
|
-
return this.
|
|
15027
|
+
return this.getAllByTenant(tenantId);
|
|
13936
15028
|
}
|
|
13937
|
-
const skills = await store.getAllSkills();
|
|
15029
|
+
const skills = await store.getAllSkills(tenantId);
|
|
13938
15030
|
return skills.map((skill) => {
|
|
13939
|
-
const memoryLattice = this.
|
|
15031
|
+
const memoryLattice = this.getWithTenant(tenantId, skill.id);
|
|
13940
15032
|
const client = memoryLattice?.client || null;
|
|
13941
15033
|
if (client && store) {
|
|
13942
15034
|
this.injectStoreIntoClient(client, store);
|
|
@@ -13957,23 +15049,40 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13957
15049
|
});
|
|
13958
15050
|
}
|
|
13959
15051
|
/**
|
|
13960
|
-
*
|
|
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
|
|
13961
15069
|
* @param key Lattice key name
|
|
13962
15070
|
*/
|
|
13963
15071
|
hasLattice(key) {
|
|
13964
|
-
return this.
|
|
15072
|
+
return this.hasWithTenant(this.getDefaultTenantId(), key);
|
|
13965
15073
|
}
|
|
13966
15074
|
/**
|
|
13967
|
-
* Remove Lattice
|
|
15075
|
+
* Remove Lattice with tenant
|
|
15076
|
+
* @param tenantId Tenant ID
|
|
13968
15077
|
* @param key Lattice key name
|
|
13969
15078
|
*/
|
|
13970
|
-
async
|
|
13971
|
-
const removed = this.
|
|
15079
|
+
async removeLatticeWithTenant(tenantId, key) {
|
|
15080
|
+
const removed = this.removeWithTenant(tenantId, key);
|
|
13972
15081
|
if (removed) {
|
|
13973
15082
|
const store = this.getStore();
|
|
13974
15083
|
if (store) {
|
|
13975
15084
|
try {
|
|
13976
|
-
await store.deleteSkill(key);
|
|
15085
|
+
await store.deleteSkill(tenantId, key);
|
|
13977
15086
|
} catch (error) {
|
|
13978
15087
|
console.warn(
|
|
13979
15088
|
`Failed to remove skill ${key} from store:`,
|
|
@@ -13984,6 +15093,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13984
15093
|
}
|
|
13985
15094
|
return removed;
|
|
13986
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
|
+
}
|
|
13987
15104
|
/**
|
|
13988
15105
|
* Clear all Lattices
|
|
13989
15106
|
*/
|
|
@@ -14081,7 +15198,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
14081
15198
|
if (!store) {
|
|
14082
15199
|
throw new Error("No store configured. Call configureStore() first.");
|
|
14083
15200
|
}
|
|
14084
|
-
const skills = await store.getAllSkills();
|
|
15201
|
+
const skills = await store.getAllSkills(this.getDefaultTenantId());
|
|
14085
15202
|
for (const skill of skills) {
|
|
14086
15203
|
const skillLattice = {
|
|
14087
15204
|
key: skill.id,
|
|
@@ -14118,7 +15235,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
14118
15235
|
...updates
|
|
14119
15236
|
};
|
|
14120
15237
|
skillLattice.config = updatedConfig;
|
|
14121
|
-
await store.updateSkill(key, {
|
|
15238
|
+
await store.updateSkill(this.getDefaultTenantId(), key, {
|
|
14122
15239
|
name: updatedConfig.name,
|
|
14123
15240
|
description: updatedConfig.description,
|
|
14124
15241
|
license: updatedConfig.license,
|
|
@@ -14343,6 +15460,7 @@ function clearEncryptionKeyCache() {
|
|
|
14343
15460
|
QueueLatticeManager,
|
|
14344
15461
|
SandboxFilesystem,
|
|
14345
15462
|
SandboxLatticeManager,
|
|
15463
|
+
SandboxSkillStore,
|
|
14346
15464
|
ScheduleLatticeManager,
|
|
14347
15465
|
SemanticMetricsClient,
|
|
14348
15466
|
SkillLatticeManager,
|
|
@@ -14390,7 +15508,6 @@ function clearEncryptionKeyCache() {
|
|
|
14390
15508
|
formatReadResponse,
|
|
14391
15509
|
getAgentClient,
|
|
14392
15510
|
getAgentConfig,
|
|
14393
|
-
getAgentLattice,
|
|
14394
15511
|
getAllAgentConfigs,
|
|
14395
15512
|
getAllToolDefinitions,
|
|
14396
15513
|
getCheckpointSaver,
|
|
@@ -14427,6 +15544,7 @@ function clearEncryptionKeyCache() {
|
|
|
14427
15544
|
performStringReplacement,
|
|
14428
15545
|
queueLatticeManager,
|
|
14429
15546
|
registerAgentLattice,
|
|
15547
|
+
registerAgentLatticeWithTenant,
|
|
14430
15548
|
registerAgentLattices,
|
|
14431
15549
|
registerCheckpointSaver,
|
|
14432
15550
|
registerChunkBuffer,
|