@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.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()}.${key}`;
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
- register(key, item) {
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
- get(key) {
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
- const fullKey = this.getFullKey(key);
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
- const fullKey = this.getFullKey(key);
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.defaultDatabaseKey = null;
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
- * Register a database connection
966
- * @param key - Unique identifier for the database
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.databases.set(key, database);
983
- if (this.defaultDatabaseKey === null) {
984
- this.defaultDatabaseKey = key;
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
- if (!this.databases.has(key)) {
993
- throw new Error(`Database '${key}' not found`);
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.defaultDatabaseKey = key;
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 dbKey = key || this.defaultDatabaseKey;
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("No database registered");
1154
+ throw new Error(`No default database set for tenant '${tenantId}'`);
1005
1155
  }
1006
- const database = this.databases.get(dbKey);
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
- return this.databases.has(key);
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
- return Array.from(this.databases.keys());
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 database = this.databases.get(key);
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
- this.databases.delete(key);
1034
- if (this.defaultDatabaseKey === key) {
1035
- this.defaultDatabaseKey = this.databases.size > 0 ? this.databases.keys().next().value || null : null;
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
- for (const database of this.databases.values()) {
1044
- await database.disconnect();
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
- this.registerDatabase(entry.key, entry.config);
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 }, exe_config) => {
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
- }, exe_config) => {
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
- }, exe_config) => {
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
- }, exe_config) => {
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.defaultServerKey = null;
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
- * Register a metrics server
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.clients.set(key, client);
1961
- this.configs.set(key, config);
1962
- if (this.defaultServerKey === null) {
1963
- this.defaultServerKey = key;
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
- if (!this.clients.has(key)) {
1972
- throw new Error(`Metrics server '${key}' not found`);
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.defaultServerKey = key;
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 serverKey = key || this.defaultServerKey;
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("No metrics server registered");
2222
+ throw new Error(`No default metrics server set for tenant '${tenantId}'`);
1984
2223
  }
1985
- const client = this.clients.get(serverKey);
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 serverKey = key || this.defaultServerKey;
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("No metrics server registered");
2242
+ throw new Error(`No default metrics server set for tenant '${tenantId}'`);
1999
2243
  }
2000
- const config = this.configs.get(serverKey);
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
- return this.clients.has(key);
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
- return Array.from(this.configs.entries()).map(([key, config]) => ({
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.delete(key);
2028
- this.configs.delete(key);
2029
- if (this.defaultServerKey === key) {
2030
- this.defaultServerKey = this.clients.size > 0 ? this.clients.keys().next().value || null : null;
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
- this.registerServer(entry.key, entry.config);
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 servers = metricsServerManager.getServerKeys();
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 (serverKeys.length === 0) {
2126
- return "No metrics servers configured.";
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 serverKeys) {
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 ${serverKeys.length} server(s):
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: " + serverKeys.join(", ");
2540
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2229
2541
  }
2230
- if (!serverKeys.includes(serverKey)) {
2231
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
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: " + serverKeys.join(", ");
2699
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2382
2700
  }
2383
- if (!serverKeys.includes(serverKey)) {
2384
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
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: " + serverKeys.join(", ");
3128
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2805
3129
  }
2806
- if (!serverKeys.includes(serverKey)) {
2807
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
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: " + serverKeys.join(", ");
3212
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2883
3213
  }
2884
- if (!serverKeys.includes(serverKey)) {
2885
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
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: " + serverKeys.join(", ");
3318
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2983
3319
  }
2984
- if (!serverKeys.includes(serverKey)) {
2985
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
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: " + serverKeys.join(", ");
3458
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
3117
3459
  }
3118
- if (!serverKeys.includes(serverKey)) {
3119
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
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 || 1e3
3478
+ limit: limit || 100
3137
3479
  });
3138
- return JSON.stringify(result, null, 2);
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 assistantThreads = this.threads.get(assistantId);
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 assistant
5239
+ * Get a thread by ID for a specific tenant
4893
5240
  */
4894
- async getThreadById(assistantId, threadId) {
4895
- const assistantThreads = this.threads.get(assistantId);
4896
- if (!assistantThreads) {
5241
+ async getThreadById(tenantId, threadId) {
5242
+ const tenantThreads = this.threads.get(tenantId);
5243
+ if (!tenantThreads) {
4897
5244
  return void 0;
4898
5245
  }
4899
- return assistantThreads.get(threadId);
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 an assistant
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(assistantId)) {
4914
- this.threads.set(assistantId, /* @__PURE__ */ new Map());
5267
+ if (!this.threads.has(tenantId)) {
5268
+ this.threads.set(tenantId, /* @__PURE__ */ new Map());
4915
5269
  }
4916
- const assistantThreads = this.threads.get(assistantId);
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(assistantId, threadId, updates) {
4924
- const assistantThreads = this.threads.get(assistantId);
4925
- if (!assistantThreads) {
5281
+ async updateThread(tenantId, threadId, updates) {
5282
+ const tenantThreads = this.threads.get(tenantId);
5283
+ if (!tenantThreads) {
4926
5284
  return null;
4927
5285
  }
4928
- const existing = assistantThreads.get(threadId);
4929
- if (!existing) {
4930
- return null;
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
- const updated = {
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(assistantId, threadId) {
4947
- const assistantThreads = this.threads.get(assistantId);
4948
- if (!assistantThreads) {
5306
+ async deleteThread(tenantId, threadId) {
5307
+ const tenantThreads = this.threads.get(tenantId);
5308
+ if (!tenantThreads) {
4949
5309
  return false;
4950
5310
  }
4951
- return assistantThreads.delete(threadId);
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(assistantId, threadId) {
4957
- const assistantThreads = this.threads.get(assistantId);
4958
- if (!assistantThreads) {
5321
+ async hasThread(tenantId, threadId) {
5322
+ const tenantThreads = this.threads.get(tenantId);
5323
+ if (!tenantThreads) {
4959
5324
  return false;
4960
5325
  }
4961
- return assistantThreads.has(threadId);
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
- this.threads.clear();
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 assistantThreads of this.threads.values()) {
4975
- allThreads.push(...Array.from(assistantThreads.values()));
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
- return Array.from(this.assistants.values());
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
- return this.assistants.get(id) || null;
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 existing = this.assistants.get(id);
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
- this.assistants.set(id, updated);
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
- return this.assistants.delete(id);
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
- return this.assistants.has(id);
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
- this.assistants.clear();
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
- getStoreLatticeUnsafe(key, type) {
6298
- const compositeKey = this.getCompositeKey(key, type);
6299
- const storeLattice = this.get(compositeKey);
6300
- if (!storeLattice) {
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
- return storeLattice;
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
- * Get all Lattices
7156
+ * Delete a skill by ID
6307
7157
  */
6308
- getAllLattices() {
6309
- return this.getAll();
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 Lattice exists
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
- hasLattice(key, type) {
6318
- const compositeKey = this.getCompositeKey(key, type);
6319
- return this.has(compositeKey);
7178
+ async hasSkill(tenantId, id) {
7179
+ const skill = await this.getSkillById(tenantId, id);
7180
+ return skill !== null;
6320
7181
  }
6321
7182
  /**
6322
- * Remove Lattice
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
- removeLattice(key, type) {
6328
- const compositeKey = this.getCompositeKey(key, type);
6329
- return this.remove(compositeKey);
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
- * Clear all Lattices
7192
+ * Filter skills by compatibility within a tenant
6333
7193
  */
6334
- clearLattices() {
6335
- this.clear();
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
- * Get Lattice count
7199
+ * Filter skills by license within a tenant
6339
7200
  */
6340
- getLatticeCount() {
6341
- return this.count();
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 Lattice key list
7206
+ * Get sub-skills of a parent skill within a tenant
6345
7207
  */
6346
- getLatticeKeys() {
6347
- return this.keys();
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 skill = await skillStore.getSkillById(input.skill_name);
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 storeLattice = getStoreLattice("default", "skill");
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
- let effectiveServerKeys = serverKeys;
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: effectiveServerKeys,
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
- return async (config) => {
7626
- const { workspaceId, projectId } = config;
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: workspaceId && projectId ? `/${workspaceId}/${projectId}` : "/"
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 an assistant_id is available in stateAndStore, return
8483
- * [assistant_id, "filesystem"] to provide per-assistant isolation.
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 (config) => {
9917
- const { workspaceId, projectId } = config;
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: workspaceId && projectId ? `/workspaces/${workspaceId}/${projectId}` : "/"
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.has(assistantId)) {
11796
- this.remove(assistantId);
12695
+ if (this.hasWithTenant(tenantId, assistantId)) {
12696
+ this.removeWithTenant(tenantId, assistantId);
11797
12697
  }
11798
12698
  const config = assistantToConfig(assistant);
11799
- this.registerLattice(config);
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.has(assistantId)) {
11807
- this.remove(assistantId);
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.getAgentLattice(key)?.config;
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
- if (agentLattice.config.schema) {
11908
- agentLattice.config.schema.parse(input);
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.getAgentLattice(key);
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.getAgentLattice(key);
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 registerAgentLattices = (configs) => {
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.registerLattice(config);
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, content) {
13136
+ async addChunk(threadId, arg2, arg3) {
12112
13137
  const buffer = this.getOrCreateBuffer(threadId);
12113
- const chunk = content;
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 buffer;
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 registerLattice(key, config, client) {
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.register(key, skillLattice);
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
- * Get skill Lattice by key
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.get(key);
15018
+ return this.getWithTenant(this.getDefaultTenantId(), key);
13927
15019
  }
13928
15020
  /**
13929
- * Get all skill Lattices from store
13930
- * Always reads from the configured store and merges with in-memory clients
15021
+ * Get all skill Lattices from store with tenant
15022
+ * @param tenantId Tenant ID
13931
15023
  */
13932
- async getAllLattices() {
15024
+ async getAllLatticesWithTenant(tenantId) {
13933
15025
  const store = this.getStore();
13934
15026
  if (!store) {
13935
- return this.getAll();
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.get(skill.id);
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
- * Check if Lattice exists
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.has(key);
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 removeLattice(key) {
13971
- const removed = this.remove(key);
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,