@axiom-lattice/core 2.1.32 → 2.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,11 +3466,11 @@ ${serverKeys.map(
3124
3466
  if (!customSql || customSql.trim().length === 0) {
3125
3467
  return "Error: customSql parameter is required and cannot be empty.";
3126
3468
  }
3127
- const config = metricsServerManager.getConfig(serverKey);
3469
+ const config = metricsServerManager.getConfig(tenantId, serverKey);
3128
3470
  if (config.type !== "semantic") {
3129
3471
  return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
3130
3472
  }
3131
- const client = metricsServerManager.getClient(serverKey);
3473
+ const client = metricsServerManager.getClient(tenantId, serverKey);
3132
3474
  const result = await client.executeSqlQuery({
3133
3475
  datasourceId,
3134
3476
  customSql,
@@ -4876,104 +5218,137 @@ var import_langchain43 = require("langchain");
4876
5218
  // src/store_lattice/InMemoryThreadStore.ts
4877
5219
  var InMemoryThreadStore = class {
4878
5220
  constructor() {
4879
- // Map<assistantId, Map<threadId, Thread>>
5221
+ // Map<tenantId, Map<assistantId, Map<threadId, Thread>>>
4880
5222
  this.threads = /* @__PURE__ */ new Map();
4881
5223
  }
4882
5224
  /**
4883
- * Get all threads for a specific assistant
5225
+ * Get all threads for a specific tenant and assistant
4884
5226
  */
4885
- async getThreadsByAssistantId(assistantId) {
4886
- const 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);
4887
5233
  if (!assistantThreads) {
4888
5234
  return [];
4889
5235
  }
4890
5236
  return Array.from(assistantThreads.values());
4891
5237
  }
4892
5238
  /**
4893
- * Get a thread by ID for a specific assistant
5239
+ * Get a thread by ID for a specific tenant
4894
5240
  */
4895
- async getThreadById(assistantId, threadId) {
4896
- const assistantThreads = this.threads.get(assistantId);
4897
- if (!assistantThreads) {
5241
+ async getThreadById(tenantId, threadId) {
5242
+ const tenantThreads = this.threads.get(tenantId);
5243
+ if (!tenantThreads) {
4898
5244
  return void 0;
4899
5245
  }
4900
- 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;
4901
5253
  }
4902
5254
  /**
4903
- * Create a new thread for an assistant
5255
+ * Create a new thread for a tenant and assistant
4904
5256
  */
4905
- async createThread(assistantId, threadId, data) {
5257
+ async createThread(tenantId, assistantId, threadId, data) {
4906
5258
  const now = /* @__PURE__ */ new Date();
4907
5259
  const thread = {
4908
5260
  id: threadId,
5261
+ tenantId,
4909
5262
  assistantId,
4910
5263
  metadata: data.metadata || {},
4911
5264
  createdAt: now,
4912
5265
  updatedAt: now
4913
5266
  };
4914
- if (!this.threads.has(assistantId)) {
4915
- this.threads.set(assistantId, /* @__PURE__ */ new Map());
5267
+ if (!this.threads.has(tenantId)) {
5268
+ this.threads.set(tenantId, /* @__PURE__ */ new Map());
5269
+ }
5270
+ const tenantThreads = this.threads.get(tenantId);
5271
+ if (!tenantThreads.has(assistantId)) {
5272
+ tenantThreads.set(assistantId, /* @__PURE__ */ new Map());
4916
5273
  }
4917
- const assistantThreads = this.threads.get(assistantId);
5274
+ const assistantThreads = tenantThreads.get(assistantId);
4918
5275
  assistantThreads.set(threadId, thread);
4919
5276
  return thread;
4920
5277
  }
4921
5278
  /**
4922
5279
  * Update an existing thread
4923
5280
  */
4924
- async updateThread(assistantId, threadId, updates) {
4925
- const assistantThreads = this.threads.get(assistantId);
4926
- if (!assistantThreads) {
5281
+ async updateThread(tenantId, threadId, updates) {
5282
+ const tenantThreads = this.threads.get(tenantId);
5283
+ if (!tenantThreads) {
4927
5284
  return null;
4928
5285
  }
4929
- const existing = assistantThreads.get(threadId);
4930
- if (!existing) {
4931
- 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
+ }
4932
5300
  }
4933
- const updated = {
4934
- ...existing,
4935
- metadata: {
4936
- ...existing.metadata,
4937
- ...updates.metadata || {}
4938
- },
4939
- updatedAt: /* @__PURE__ */ new Date()
4940
- };
4941
- assistantThreads.set(threadId, updated);
4942
- return updated;
5301
+ return null;
4943
5302
  }
4944
5303
  /**
4945
5304
  * Delete a thread by ID
4946
5305
  */
4947
- async deleteThread(assistantId, threadId) {
4948
- const assistantThreads = this.threads.get(assistantId);
4949
- if (!assistantThreads) {
5306
+ async deleteThread(tenantId, threadId) {
5307
+ const tenantThreads = this.threads.get(tenantId);
5308
+ if (!tenantThreads) {
4950
5309
  return false;
4951
5310
  }
4952
- 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;
4953
5317
  }
4954
5318
  /**
4955
5319
  * Check if thread exists
4956
5320
  */
4957
- async hasThread(assistantId, threadId) {
4958
- const assistantThreads = this.threads.get(assistantId);
4959
- if (!assistantThreads) {
5321
+ async hasThread(tenantId, threadId) {
5322
+ const tenantThreads = this.threads.get(tenantId);
5323
+ if (!tenantThreads) {
4960
5324
  return false;
4961
5325
  }
4962
- return assistantThreads.has(threadId);
5326
+ for (const assistantThreads of tenantThreads.values()) {
5327
+ if (assistantThreads.has(threadId)) {
5328
+ return true;
5329
+ }
5330
+ }
5331
+ return false;
4963
5332
  }
4964
5333
  /**
4965
- * Clear all threads (useful for testing)
5334
+ * Clear all threads for a tenant (useful for testing)
4966
5335
  */
4967
- clear() {
4968
- this.threads.clear();
5336
+ clear(tenantId) {
5337
+ if (tenantId) {
5338
+ this.threads.delete(tenantId);
5339
+ } else {
5340
+ this.threads.clear();
5341
+ }
4969
5342
  }
4970
5343
  /**
4971
5344
  * Get all threads for all assistants (useful for debugging)
4972
5345
  */
4973
5346
  getAllThreads() {
4974
5347
  const allThreads = [];
4975
- for (const assistantThreads of this.threads.values()) {
4976
- 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
+ }
4977
5352
  }
4978
5353
  return allThreads;
4979
5354
  }
@@ -4985,38 +5360,50 @@ var InMemoryAssistantStore = class {
4985
5360
  this.assistants = /* @__PURE__ */ new Map();
4986
5361
  }
4987
5362
  /**
4988
- * Get all assistants
5363
+ * Get all assistants for a tenant
4989
5364
  */
4990
- async getAllAssistants() {
4991
- 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());
4992
5369
  }
4993
5370
  /**
4994
5371
  * Get assistant by ID
4995
5372
  */
4996
- async getAssistantById(id) {
4997
- 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;
4998
5377
  }
4999
5378
  /**
5000
5379
  * Create a new assistant
5001
5380
  */
5002
- async createAssistant(id, data) {
5381
+ async createAssistant(tenantId, id, data) {
5382
+ if (!this.assistants.has(tenantId)) {
5383
+ this.assistants.set(tenantId, /* @__PURE__ */ new Map());
5384
+ }
5003
5385
  const now = /* @__PURE__ */ new Date();
5004
5386
  const assistant = {
5005
5387
  id,
5388
+ tenantId,
5006
5389
  name: data.name,
5007
5390
  description: data.description,
5008
5391
  graphDefinition: data.graphDefinition,
5009
5392
  createdAt: now,
5010
5393
  updatedAt: now
5011
5394
  };
5012
- this.assistants.set(id, assistant);
5395
+ this.assistants.get(tenantId).set(id, assistant);
5013
5396
  return assistant;
5014
5397
  }
5015
5398
  /**
5016
5399
  * Update an existing assistant
5017
5400
  */
5018
- async updateAssistant(id, updates) {
5019
- const 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);
5020
5407
  if (!existing) {
5021
5408
  return null;
5022
5409
  }
@@ -5025,26 +5412,38 @@ var InMemoryAssistantStore = class {
5025
5412
  ...updates,
5026
5413
  updatedAt: /* @__PURE__ */ new Date()
5027
5414
  };
5028
- this.assistants.set(id, updated);
5415
+ tenantAssistants.set(id, updated);
5029
5416
  return updated;
5030
5417
  }
5031
5418
  /**
5032
5419
  * Delete an assistant by ID
5033
5420
  */
5034
- async deleteAssistant(id) {
5035
- 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);
5036
5427
  }
5037
5428
  /**
5038
5429
  * Check if assistant exists
5039
5430
  */
5040
- async hasAssistant(id) {
5041
- 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);
5042
5437
  }
5043
5438
  /**
5044
- * Clear all assistants (useful for testing)
5439
+ * Clear all assistants for a tenant (useful for testing)
5045
5440
  */
5046
- clear() {
5047
- this.assistants.clear();
5441
+ clear(tenantId) {
5442
+ if (tenantId) {
5443
+ this.assistants.delete(tenantId);
5444
+ } else {
5445
+ this.assistants.clear();
5446
+ }
5048
5447
  }
5049
5448
  };
5050
5449
 
@@ -5290,6 +5689,8 @@ var FileSystemSkillStore = class {
5290
5689
  return {
5291
5690
  id: name,
5292
5691
  // id equals name (name is used for path addressing)
5692
+ tenantId: "default",
5693
+ // FileSystemSkillStore uses default tenant
5293
5694
  name: frontmatter.name,
5294
5695
  description: frontmatter.description,
5295
5696
  license: frontmatter.license,
@@ -5337,9 +5738,11 @@ ${body}` : `${frontmatter}
5337
5738
  await fs.writeFile(filePath, content, "utf-8");
5338
5739
  }
5339
5740
  /**
5340
- * Get all skills
5741
+ * Get all skills for a tenant
5742
+ * Note: FileSystemSkillStore uses a flat structure. TenantId is accepted for protocol compliance
5743
+ * but all skills are returned regardless of tenant.
5341
5744
  */
5342
- async getAllSkills() {
5745
+ async getAllSkills(_tenantId) {
5343
5746
  await this.ensureDirectoryExists();
5344
5747
  try {
5345
5748
  const entries = await fs.readdir(this.rootDir, { withFileTypes: true });
@@ -5376,17 +5779,19 @@ ${body}` : `${frontmatter}
5376
5779
  }
5377
5780
  }
5378
5781
  /**
5379
- * Get skill by ID
5782
+ * Get skill by ID for a tenant
5380
5783
  * ID should equal name (name is used for path addressing)
5784
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5381
5785
  */
5382
- async getSkillById(id) {
5786
+ async getSkillById(_tenantId, id) {
5383
5787
  return this.readSkillFile(id);
5384
5788
  }
5385
5789
  /**
5386
- * Create a new skill
5790
+ * Create a new skill for a tenant
5387
5791
  * id should equal name (name is used for path addressing)
5792
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5388
5793
  */
5389
- async createSkill(id, data) {
5794
+ async createSkill(_tenantId, id, data) {
5390
5795
  await this.ensureDirectoryExists();
5391
5796
  validateSkillName(data.name);
5392
5797
  if (id !== data.name) {
@@ -5394,14 +5799,15 @@ ${body}` : `${frontmatter}
5394
5799
  `Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
5395
5800
  );
5396
5801
  }
5397
- const existing = await this.getSkillById(id);
5802
+ const existing = await this.getSkillById(_tenantId, id);
5398
5803
  if (existing) {
5399
- return this.updateSkill(id, data);
5804
+ return this.updateSkill(_tenantId, id, data);
5400
5805
  }
5401
5806
  const now = /* @__PURE__ */ new Date();
5402
5807
  const skill = {
5403
5808
  id: data.name,
5404
5809
  // id equals name
5810
+ tenantId: _tenantId,
5405
5811
  name: data.name,
5406
5812
  description: data.description,
5407
5813
  license: data.license,
@@ -5416,9 +5822,10 @@ ${body}` : `${frontmatter}
5416
5822
  return skill;
5417
5823
  }
5418
5824
  /**
5419
- * Update an existing skill
5825
+ * Update an existing skill for a tenant
5826
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5420
5827
  */
5421
- async updateSkill(id, updates) {
5828
+ async updateSkill(_tenantId, id, updates) {
5422
5829
  const skill = await this.readSkillFile(id);
5423
5830
  if (!skill) {
5424
5831
  return null;
@@ -5442,6 +5849,7 @@ ${body}` : `${frontmatter}
5442
5849
  name: updates.name ?? skill.name,
5443
5850
  id: updates.name ?? skill.id,
5444
5851
  // id equals name
5852
+ tenantId: _tenantId,
5445
5853
  description: updates.description ?? skill.description,
5446
5854
  license: updates.license ?? skill.license,
5447
5855
  compatibility: updates.compatibility ?? skill.compatibility,
@@ -5454,10 +5862,11 @@ ${body}` : `${frontmatter}
5454
5862
  return updatedSkill;
5455
5863
  }
5456
5864
  /**
5457
- * Delete a skill by ID
5865
+ * Delete a skill by ID for a tenant
5458
5866
  * Deletes the entire directory (name is the directory name)
5867
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5459
5868
  */
5460
- async deleteSkill(id) {
5869
+ async deleteSkill(_tenantId, id) {
5461
5870
  await this.ensureDirectoryExists();
5462
5871
  const skillDir = this.getSkillDirectoryPath(id);
5463
5872
  try {
@@ -5471,50 +5880,55 @@ ${body}` : `${frontmatter}
5471
5880
  }
5472
5881
  }
5473
5882
  /**
5474
- * Check if skill exists
5883
+ * Check if skill exists for a tenant
5884
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5475
5885
  */
5476
- async hasSkill(id) {
5477
- const skill = await this.getSkillById(id);
5886
+ async hasSkill(_tenantId, id) {
5887
+ const skill = await this.getSkillById(_tenantId, id);
5478
5888
  return skill !== null;
5479
5889
  }
5480
5890
  /**
5481
- * Search skills by metadata
5891
+ * Search skills by metadata within a tenant
5892
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5482
5893
  */
5483
- async searchByMetadata(metadataKey, metadataValue) {
5484
- const allSkills = await this.getAllSkills();
5894
+ async searchByMetadata(_tenantId, metadataKey, metadataValue) {
5895
+ const allSkills = await this.getAllSkills(_tenantId);
5485
5896
  return allSkills.filter((skill) => {
5486
5897
  return skill.metadata && skill.metadata[metadataKey] === metadataValue;
5487
5898
  });
5488
5899
  }
5489
5900
  /**
5490
- * Filter skills by compatibility
5901
+ * Filter skills by compatibility within a tenant
5902
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5491
5903
  */
5492
- async filterByCompatibility(compatibility) {
5493
- const allSkills = await this.getAllSkills();
5904
+ async filterByCompatibility(_tenantId, compatibility) {
5905
+ const allSkills = await this.getAllSkills(_tenantId);
5494
5906
  return allSkills.filter((skill) => {
5495
5907
  return skill.compatibility === compatibility;
5496
5908
  });
5497
5909
  }
5498
5910
  /**
5499
- * Filter skills by license
5911
+ * Filter skills by license within a tenant
5912
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5500
5913
  */
5501
- async filterByLicense(license) {
5502
- const allSkills = await this.getAllSkills();
5914
+ async filterByLicense(_tenantId, license) {
5915
+ const allSkills = await this.getAllSkills(_tenantId);
5503
5916
  return allSkills.filter((skill) => {
5504
5917
  return skill.license === license;
5505
5918
  });
5506
5919
  }
5507
5920
  /**
5508
- * Get sub-skills of a parent skill
5921
+ * Get sub-skills of a parent skill within a tenant
5922
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5509
5923
  */
5510
- async getSubSkills(parentSkillName) {
5511
- const parentSkill = await this.getSkillById(parentSkillName);
5924
+ async getSubSkills(_tenantId, parentSkillName) {
5925
+ const parentSkill = await this.getSkillById(_tenantId, parentSkillName);
5512
5926
  if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
5513
5927
  return [];
5514
5928
  }
5515
5929
  const subSkills = [];
5516
5930
  for (const subSkillName of parentSkill.subSkills) {
5517
- const subSkill = await this.getSkillById(subSkillName);
5931
+ const subSkill = await this.getSkillById(_tenantId, subSkillName);
5518
5932
  if (subSkill) {
5519
5933
  subSkills.push(subSkill);
5520
5934
  }
@@ -5523,10 +5937,11 @@ ${body}` : `${frontmatter}
5523
5937
  }
5524
5938
  /**
5525
5939
  * List all resources in a skill's resources directory
5940
+ * @param tenantId The tenant identifier (accepted for protocol compliance)
5526
5941
  * @param skillName The skill name
5527
5942
  * @returns Array of resource paths relative to resources/ directory
5528
5943
  */
5529
- async listSkillResources(skillName) {
5944
+ async listSkillResources(_tenantId, skillName) {
5530
5945
  const skillDir = this.getSkillDirectoryPath(skillName);
5531
5946
  const resourcesDir = path3.join(skillDir, "resources");
5532
5947
  try {
@@ -5549,11 +5964,12 @@ ${body}` : `${frontmatter}
5549
5964
  }
5550
5965
  /**
5551
5966
  * Load a specific resource from a skill's resources directory
5967
+ * @param tenantId The tenant identifier (accepted for protocol compliance)
5552
5968
  * @param skillName The skill name
5553
5969
  * @param resourcePath Path to the resource relative to resources/ directory
5554
5970
  * @returns The resource content as string
5555
5971
  */
5556
- async loadSkillResource(skillName, resourcePath) {
5972
+ async loadSkillResource(_tenantId, skillName, resourcePath) {
5557
5973
  const skillDir = this.getSkillDirectoryPath(skillName);
5558
5974
  const resourcesDir = path3.join(skillDir, "resources");
5559
5975
  const fullPath = path3.join(resourcesDir, resourcePath);
@@ -6290,93 +6706,520 @@ var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager
6290
6706
  return storeLattice;
6291
6707
  }
6292
6708
  /**
6293
- * Get StoreLattice without type checking (for backward compatibility)
6294
- * @param key Lattice key name
6295
- * @param type Store type
6296
- * @returns StoreLattice (type may be unknown)
6709
+ * Get StoreLattice without type checking (for backward compatibility)
6710
+ * @param key Lattice key name
6711
+ * @param type Store type
6712
+ * @returns StoreLattice (type may be unknown)
6713
+ */
6714
+ getStoreLatticeUnsafe(key, type) {
6715
+ const compositeKey = this.getCompositeKey(key, type);
6716
+ const storeLattice = this.get(compositeKey);
6717
+ if (!storeLattice) {
6718
+ throw new Error(`StoreLattice ${key}:${type} not found`);
6719
+ }
6720
+ return storeLattice;
6721
+ }
6722
+ /**
6723
+ * Get all Lattices
6724
+ */
6725
+ getAllLattices() {
6726
+ return this.getAll();
6727
+ }
6728
+ /**
6729
+ * Check if Lattice exists
6730
+ * Uses composite key (key + type) to check existence
6731
+ * @param key Lattice key name
6732
+ * @param type Store type
6733
+ */
6734
+ hasLattice(key, type) {
6735
+ const compositeKey = this.getCompositeKey(key, type);
6736
+ return this.has(compositeKey);
6737
+ }
6738
+ /**
6739
+ * Remove Lattice
6740
+ * Uses composite key (key + type) to remove the store
6741
+ * @param key Lattice key name
6742
+ * @param type Store type
6743
+ */
6744
+ removeLattice(key, type) {
6745
+ const compositeKey = this.getCompositeKey(key, type);
6746
+ return this.remove(compositeKey);
6747
+ }
6748
+ /**
6749
+ * Clear all Lattices
6750
+ */
6751
+ clearLattices() {
6752
+ this.clear();
6753
+ }
6754
+ /**
6755
+ * Get Lattice count
6756
+ */
6757
+ getLatticeCount() {
6758
+ return this.count();
6759
+ }
6760
+ /**
6761
+ * Get Lattice key list
6762
+ */
6763
+ getLatticeKeys() {
6764
+ return this.keys();
6765
+ }
6766
+ };
6767
+ var storeLatticeManager = StoreLatticeManager.getInstance();
6768
+ var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
6769
+ var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
6770
+ var defaultThreadStore = new InMemoryThreadStore();
6771
+ var defaultAssistantStore = new InMemoryAssistantStore();
6772
+ var defaultSkillStore = new FileSystemSkillStore();
6773
+ var defaultWorkspaceStore = new InMemoryWorkspaceStore();
6774
+ var defaultProjectStore = new InMemoryProjectStore();
6775
+ var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
6776
+ var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
6777
+ var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
6778
+ storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
6779
+ storeLatticeManager.registerLattice(
6780
+ "default",
6781
+ "assistant",
6782
+ defaultAssistantStore
6783
+ );
6784
+ storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
6785
+ storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
6786
+ storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
6787
+ storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
6788
+ storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
6789
+ storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
6790
+ var defaultUserStore = new InMemoryUserStore();
6791
+ var defaultTenantStore = new InMemoryTenantStore();
6792
+ var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
6793
+ storeLatticeManager.registerLattice("default", "user", defaultUserStore);
6794
+ storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
6795
+ storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
6796
+
6797
+ // src/store_lattice/SandboxSkillStore.ts
6798
+ function parseFrontmatter2(content) {
6799
+ const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
6800
+ const match = content.match(frontmatterRegex);
6801
+ if (!match) {
6802
+ return { frontmatter: {}, body: content };
6803
+ }
6804
+ const frontmatterText = match[1];
6805
+ const body = match[2] || "";
6806
+ const frontmatter = {};
6807
+ const lines = frontmatterText.split("\n");
6808
+ let currentKey = null;
6809
+ let metadataIndent = 0;
6810
+ for (let i = 0; i < lines.length; i++) {
6811
+ const line = lines[i];
6812
+ const trimmed = line.trim();
6813
+ if (!trimmed || trimmed.startsWith("#")) {
6814
+ continue;
6815
+ }
6816
+ const indentMatch = line.match(/^(\s*)/);
6817
+ const indent = indentMatch ? indentMatch[1].length : 0;
6818
+ if (currentKey === "metadata" && indent > metadataIndent) {
6819
+ const colonIndex2 = trimmed.indexOf(":");
6820
+ if (colonIndex2 !== -1) {
6821
+ const key2 = trimmed.substring(0, colonIndex2).trim();
6822
+ let value2 = trimmed.substring(colonIndex2 + 1).trim();
6823
+ if (value2.startsWith('"') && value2.endsWith('"') || value2.startsWith("'") && value2.endsWith("'")) {
6824
+ value2 = value2.slice(1, -1);
6825
+ }
6826
+ if (!frontmatter.metadata) {
6827
+ frontmatter.metadata = {};
6828
+ }
6829
+ frontmatter.metadata[key2] = value2;
6830
+ }
6831
+ continue;
6832
+ }
6833
+ if (currentKey === "subSkills" && indent > metadataIndent) {
6834
+ if (trimmed.startsWith("-")) {
6835
+ let value2 = trimmed.substring(1).trim();
6836
+ if (value2.startsWith('"') && value2.endsWith('"') || value2.startsWith("'") && value2.endsWith("'")) {
6837
+ value2 = value2.slice(1, -1);
6838
+ }
6839
+ if (!frontmatter.subSkills) {
6840
+ frontmatter.subSkills = [];
6841
+ }
6842
+ frontmatter.subSkills.push(value2);
6843
+ }
6844
+ continue;
6845
+ }
6846
+ if ((currentKey === "metadata" || currentKey === "subSkills") && indent <= metadataIndent) {
6847
+ currentKey = null;
6848
+ metadataIndent = 0;
6849
+ }
6850
+ const colonIndex = trimmed.indexOf(":");
6851
+ if (colonIndex === -1) {
6852
+ continue;
6853
+ }
6854
+ const key = trimmed.substring(0, colonIndex).trim();
6855
+ let value = trimmed.substring(colonIndex + 1).trim();
6856
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
6857
+ value = value.slice(1, -1);
6858
+ }
6859
+ if (key === "metadata") {
6860
+ if (value === "" || value === "{}") {
6861
+ if (i + 1 < lines.length) {
6862
+ const nextLine = lines[i + 1];
6863
+ const nextIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;
6864
+ if (nextIndent > indent) {
6865
+ currentKey = "metadata";
6866
+ metadataIndent = indent;
6867
+ frontmatter.metadata = {};
6868
+ continue;
6869
+ }
6870
+ }
6871
+ frontmatter[key] = {};
6872
+ } else if (value.startsWith("{")) {
6873
+ try {
6874
+ frontmatter[key] = JSON.parse(value);
6875
+ } catch {
6876
+ frontmatter[key] = {};
6877
+ }
6878
+ } else {
6879
+ frontmatter[key] = {};
6880
+ }
6881
+ } else if (key === "subSkills") {
6882
+ if (value === "" || value === "[]") {
6883
+ if (i + 1 < lines.length) {
6884
+ const nextLine = lines[i + 1];
6885
+ const nextIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;
6886
+ if (nextIndent > indent && nextLine.trim().startsWith("-")) {
6887
+ currentKey = "subSkills";
6888
+ metadataIndent = indent;
6889
+ frontmatter.subSkills = [];
6890
+ continue;
6891
+ }
6892
+ }
6893
+ frontmatter[key] = [];
6894
+ } else if (value.startsWith("[")) {
6895
+ try {
6896
+ frontmatter[key] = JSON.parse(value);
6897
+ } catch {
6898
+ frontmatter[key] = [];
6899
+ }
6900
+ } else {
6901
+ frontmatter[key] = [];
6902
+ }
6903
+ } else {
6904
+ frontmatter[key] = value;
6905
+ }
6906
+ }
6907
+ return { frontmatter, body };
6908
+ }
6909
+ function generateFrontmatter2(data) {
6910
+ const lines = ["---"];
6911
+ lines.push(`name: ${data.name}`);
6912
+ lines.push(`description: ${data.description}`);
6913
+ if (data.license) {
6914
+ lines.push(`license: ${data.license}`);
6915
+ }
6916
+ if (data.compatibility) {
6917
+ lines.push(`compatibility: ${data.compatibility}`);
6918
+ }
6919
+ if (data.metadata && Object.keys(data.metadata).length > 0) {
6920
+ lines.push("metadata:");
6921
+ for (const [key, value] of Object.entries(data.metadata)) {
6922
+ lines.push(` ${key}: ${value}`);
6923
+ }
6924
+ }
6925
+ if (data.subSkills && data.subSkills.length > 0) {
6926
+ lines.push("subSkills:");
6927
+ for (const subSkill of data.subSkills) {
6928
+ lines.push(` - ${subSkill}`);
6929
+ }
6930
+ }
6931
+ lines.push("---");
6932
+ return lines.join("\n");
6933
+ }
6934
+ var SandboxSkillStore = class {
6935
+ constructor(options = {}) {
6936
+ this.sandboxManager = options.sandboxManager;
6937
+ this.basePath = options.basePath || "/home/gem/tenants";
6938
+ }
6939
+ /**
6940
+ * Get sandbox manager for a tenant
6941
+ */
6942
+ async getSandboxManager() {
6943
+ if (this.sandboxManager) {
6944
+ return this.sandboxManager;
6945
+ }
6946
+ return getSandBoxManager();
6947
+ }
6948
+ /**
6949
+ * Get skill directory path in sandbox
6950
+ */
6951
+ getSkillDirectoryPath(tenantId, name) {
6952
+ if (name.includes("..") || name.includes("/") || name.includes("\\")) {
6953
+ throw new Error(`Invalid skill name: ${name} (contains invalid characters)`);
6954
+ }
6955
+ return `${this.basePath}/${tenantId}/skills/${name}`;
6956
+ }
6957
+ /**
6958
+ * Get skill file path in sandbox
6959
+ */
6960
+ getSkillFilePath(tenantId, name) {
6961
+ return `${this.getSkillDirectoryPath(tenantId, name)}/SKILL.md`;
6962
+ }
6963
+ /**
6964
+ * Read skill from sandbox
6965
+ */
6966
+ async readSkillFile(tenantId, name) {
6967
+ try {
6968
+ const sandboxManager = await this.getSandboxManager();
6969
+ const sandbox = await sandboxManager.createSandbox("global");
6970
+ const filePath = this.getSkillFilePath(tenantId, name);
6971
+ const result = await sandbox.file.readFile({ file: filePath });
6972
+ if (!result.ok) {
6973
+ return null;
6974
+ }
6975
+ let content;
6976
+ if (typeof result.body === "string") {
6977
+ content = result.body;
6978
+ } else if (result.body && typeof result.body === "object") {
6979
+ const body = result.body;
6980
+ content = body.content || body.data?.content || JSON.stringify(body);
6981
+ } else {
6982
+ content = String(result.body);
6983
+ }
6984
+ const { frontmatter, body: skillBody } = parseFrontmatter2(content);
6985
+ if (!frontmatter.name || !frontmatter.description) {
6986
+ console.warn(`Invalid skill file ${name}: missing required fields`);
6987
+ return null;
6988
+ }
6989
+ return {
6990
+ id: name,
6991
+ tenantId,
6992
+ name: frontmatter.name,
6993
+ description: frontmatter.description,
6994
+ license: frontmatter.license,
6995
+ compatibility: frontmatter.compatibility,
6996
+ metadata: frontmatter.metadata || {},
6997
+ content: skillBody.trim() || void 0,
6998
+ subSkills: Array.isArray(frontmatter.subSkills) ? frontmatter.subSkills : void 0,
6999
+ createdAt: /* @__PURE__ */ new Date(),
7000
+ // Sandbox doesn't provide file stats easily
7001
+ updatedAt: /* @__PURE__ */ new Date()
7002
+ };
7003
+ } catch (error) {
7004
+ console.error(`Error reading skill ${name} from sandbox:`, error);
7005
+ return null;
7006
+ }
7007
+ }
7008
+ /**
7009
+ * Write skill to sandbox
7010
+ */
7011
+ async writeSkillFile(skill) {
7012
+ const sandboxManager = await this.getSandboxManager();
7013
+ const sandbox = await sandboxManager.createSandbox("global");
7014
+ const filePath = this.getSkillFilePath(skill.tenantId, skill.name);
7015
+ const frontmatter = generateFrontmatter2({
7016
+ name: skill.name,
7017
+ description: skill.description,
7018
+ license: skill.license,
7019
+ compatibility: skill.compatibility,
7020
+ metadata: skill.metadata,
7021
+ subSkills: skill.subSkills
7022
+ });
7023
+ const body = skill.content || "";
7024
+ const content = body ? `${frontmatter}
7025
+ ${body}` : `${frontmatter}
7026
+ `;
7027
+ const result = await sandbox.file.writeFile({
7028
+ file: filePath,
7029
+ content,
7030
+ encoding: "utf-8",
7031
+ append: false
7032
+ });
7033
+ if (!result.ok) {
7034
+ throw new Error(`Failed to write skill to sandbox: ${JSON.stringify(result.error)}`);
7035
+ }
7036
+ }
7037
+ /**
7038
+ * Get all skills for a tenant
7039
+ */
7040
+ async getAllSkills(tenantId) {
7041
+ try {
7042
+ const sandboxManager = await this.getSandboxManager();
7043
+ const sandbox = await sandboxManager.createSandbox("global");
7044
+ const skillsDir = `${this.basePath}/${tenantId}/skills`;
7045
+ const result = await sandbox.file.listPath({
7046
+ path: skillsDir,
7047
+ recursive: false,
7048
+ show_hidden: false
7049
+ });
7050
+ if (!result.ok || !result.body) {
7051
+ return [];
7052
+ }
7053
+ const files = result.body?.data?.files || [];
7054
+ const skills = [];
7055
+ for (const entry of files) {
7056
+ if (entry.is_directory) {
7057
+ const pathParts = entry.path.split("/");
7058
+ const skillName = pathParts[pathParts.length - 1];
7059
+ if (!skillName) continue;
7060
+ try {
7061
+ const skill = await this.readSkillFile(tenantId, skillName);
7062
+ if (skill) {
7063
+ skills.push(skill);
7064
+ }
7065
+ } catch (error) {
7066
+ console.error(`Error loading skill "${skillName}":`, error);
7067
+ }
7068
+ }
7069
+ }
7070
+ return skills.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
7071
+ } catch (error) {
7072
+ console.error(`Error listing skills for tenant ${tenantId}:`, error);
7073
+ return [];
7074
+ }
7075
+ }
7076
+ /**
7077
+ * Get skill by ID
7078
+ */
7079
+ async getSkillById(tenantId, id) {
7080
+ return this.readSkillFile(tenantId, id);
7081
+ }
7082
+ /**
7083
+ * Create a new skill
7084
+ */
7085
+ async createSkill(tenantId, id, data) {
7086
+ validateSkillName(data.name);
7087
+ if (id !== data.name) {
7088
+ throw new Error(
7089
+ `Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
7090
+ );
7091
+ }
7092
+ const existing = await this.getSkillById(tenantId, id);
7093
+ if (existing) {
7094
+ return this.updateSkill(tenantId, id, data);
7095
+ }
7096
+ const now = /* @__PURE__ */ new Date();
7097
+ const skill = {
7098
+ id: data.name,
7099
+ tenantId,
7100
+ name: data.name,
7101
+ description: data.description,
7102
+ license: data.license,
7103
+ compatibility: data.compatibility,
7104
+ metadata: data.metadata || {},
7105
+ content: data.content,
7106
+ subSkills: data.subSkills,
7107
+ createdAt: now,
7108
+ updatedAt: now
7109
+ };
7110
+ await this.writeSkillFile(skill);
7111
+ return skill;
7112
+ }
7113
+ /**
7114
+ * Update an existing skill
6297
7115
  */
6298
- getStoreLatticeUnsafe(key, type) {
6299
- const compositeKey = this.getCompositeKey(key, type);
6300
- const storeLattice = this.get(compositeKey);
6301
- if (!storeLattice) {
6302
- throw new Error(`StoreLattice ${key}:${type} not found`);
7116
+ async updateSkill(tenantId, id, updates) {
7117
+ const skill = await this.readSkillFile(tenantId, id);
7118
+ if (!skill) {
7119
+ return null;
6303
7120
  }
6304
- 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;
6305
7154
  }
6306
7155
  /**
6307
- * Get all Lattices
7156
+ * Delete a skill by ID
6308
7157
  */
6309
- getAllLattices() {
6310
- 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
+ }
6311
7174
  }
6312
7175
  /**
6313
- * Check if Lattice exists
6314
- * Uses composite key (key + type) to check existence
6315
- * @param key Lattice key name
6316
- * @param type Store type
7176
+ * Check if skill exists
6317
7177
  */
6318
- hasLattice(key, type) {
6319
- const compositeKey = this.getCompositeKey(key, type);
6320
- return this.has(compositeKey);
7178
+ async hasSkill(tenantId, id) {
7179
+ const skill = await this.getSkillById(tenantId, id);
7180
+ return skill !== null;
6321
7181
  }
6322
7182
  /**
6323
- * Remove Lattice
6324
- * Uses composite key (key + type) to remove the store
6325
- * @param key Lattice key name
6326
- * @param type Store type
7183
+ * Search skills by metadata within a tenant
6327
7184
  */
6328
- removeLattice(key, type) {
6329
- const compositeKey = this.getCompositeKey(key, type);
6330
- 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
+ );
6331
7190
  }
6332
7191
  /**
6333
- * Clear all Lattices
7192
+ * Filter skills by compatibility within a tenant
6334
7193
  */
6335
- clearLattices() {
6336
- this.clear();
7194
+ async filterByCompatibility(tenantId, compatibility) {
7195
+ const allSkills = await this.getAllSkills(tenantId);
7196
+ return allSkills.filter((skill) => skill.compatibility === compatibility);
6337
7197
  }
6338
7198
  /**
6339
- * Get Lattice count
7199
+ * Filter skills by license within a tenant
6340
7200
  */
6341
- getLatticeCount() {
6342
- return this.count();
7201
+ async filterByLicense(tenantId, license) {
7202
+ const allSkills = await this.getAllSkills(tenantId);
7203
+ return allSkills.filter((skill) => skill.license === license);
6343
7204
  }
6344
7205
  /**
6345
- * Get Lattice key list
7206
+ * Get sub-skills of a parent skill within a tenant
6346
7207
  */
6347
- getLatticeKeys() {
6348
- 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;
6349
7221
  }
6350
7222
  };
6351
- var storeLatticeManager = StoreLatticeManager.getInstance();
6352
- var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
6353
- var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
6354
- var defaultThreadStore = new InMemoryThreadStore();
6355
- var defaultAssistantStore = new InMemoryAssistantStore();
6356
- var defaultSkillStore = new FileSystemSkillStore();
6357
- var defaultWorkspaceStore = new InMemoryWorkspaceStore();
6358
- var defaultProjectStore = new InMemoryProjectStore();
6359
- var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
6360
- var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
6361
- var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
6362
- storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
6363
- storeLatticeManager.registerLattice(
6364
- "default",
6365
- "assistant",
6366
- defaultAssistantStore
6367
- );
6368
- storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
6369
- storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
6370
- storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
6371
- storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
6372
- storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
6373
- storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
6374
- var defaultUserStore = new InMemoryUserStore();
6375
- var defaultTenantStore = new InMemoryTenantStore();
6376
- var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
6377
- storeLatticeManager.registerLattice("default", "user", defaultUserStore);
6378
- storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
6379
- storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
6380
7223
 
6381
7224
  // src/tool_lattice/skill/load_skills.ts
6382
7225
  var import_zod41 = __toESM(require("zod"));
@@ -6415,9 +7258,11 @@ var createLoadSkillContentTool = () => {
6415
7258
  try {
6416
7259
  const storeLattice = getStoreLattice("default", "skill");
6417
7260
  const skillStore = storeLattice.store;
6418
- const 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);
6419
7264
  if (!skill) {
6420
- const allSkills = await skillStore.getAllSkills();
7265
+ const allSkills = await skillStore.getAllSkills(tenantId);
6421
7266
  const availableSkills = allSkills.map((s) => s.name).join(", ");
6422
7267
  return `Skill "${input.skill_name}" not found. Available skills: ${availableSkills}`;
6423
7268
  }
@@ -6449,7 +7294,7 @@ ${content}`;
6449
7294
  const fsStore = skillStore;
6450
7295
  if (fsStore.listSkillResources) {
6451
7296
  try {
6452
- const resources = await fsStore.listSkillResources(input.skill_name);
7297
+ const resources = await fsStore.listSkillResources(tenantId, input.skill_name);
6453
7298
  if (resources.length > 0) {
6454
7299
  result += "\n\n---\n\n**Resources** (use `load_skill_resource` tool to access):\n";
6455
7300
  resources.forEach((resource) => {
@@ -6483,7 +7328,8 @@ var createLoadSkillResourceTool = () => {
6483
7328
  return (0, import_langchain42.tool)(
6484
7329
  async (input, _exe_config) => {
6485
7330
  try {
6486
- const storeLattice = getStoreLattice("default", "skill");
7331
+ const tenantId = _exe_config?.configurable?.runConfig?.tenantId || "default";
7332
+ const storeLattice = getStoreLattice(tenantId, "skill");
6487
7333
  const skillStore = storeLattice.store;
6488
7334
  const fsStore = skillStore;
6489
7335
  if (!fsStore.loadSkillResource) {
@@ -6523,15 +7369,16 @@ function createSkillMiddleware(params = {}) {
6523
7369
  createLoadSkillContentTool(),
6524
7370
  createLoadSkillResourceTool()
6525
7371
  ],
6526
- beforeAgent: async () => {
7372
+ beforeAgent: async (state, runtime) => {
6527
7373
  try {
6528
7374
  const storeLattice = getStoreLattice("default", "skill");
6529
7375
  const skillStore = storeLattice?.store;
7376
+ const tenantId = runtime?.context?.tenantId || state?.tenantId || "default";
6530
7377
  if (readAll) {
6531
- latestSkills = await skillStore.getAllSkills();
7378
+ latestSkills = await skillStore.getAllSkills(tenantId);
6532
7379
  } else if (skills && skills.length > 0) {
6533
7380
  const skillLatticePromises = skills.map(
6534
- (skillId) => skillStore.getSkillById(skillId)
7381
+ (skillId) => skillStore.getSkillById(tenantId, skillId)
6535
7382
  );
6536
7383
  const skillLattices = await Promise.all(skillLatticePromises);
6537
7384
  latestSkills = skillLattices.filter((skill) => skill !== void 0);
@@ -7417,19 +8264,20 @@ ${systemPrompt}` : systemPrompt;
7417
8264
  var import_langchain45 = require("langchain");
7418
8265
  function createMetricsMiddleware(params) {
7419
8266
  const { serverKeys, serverDescriptions, connectAll } = params;
7420
- let effectiveServerKeys = serverKeys;
7421
- if (connectAll) {
7422
- effectiveServerKeys = metricsServerManager.getServerKeys().map((s) => s.key);
7423
- }
7424
- if (!effectiveServerKeys || effectiveServerKeys.length === 0) {
8267
+ if (!serverKeys || serverKeys.length === 0) {
7425
8268
  return (0, import_langchain45.createMiddleware)({
7426
8269
  name: "metricsMiddleware",
7427
8270
  tools: []
7428
8271
  });
7429
8272
  }
7430
8273
  const toolParams = {
7431
- serverKeys: effectiveServerKeys,
7432
- serverDescriptions
8274
+ serverKeys,
8275
+ serverDescriptions,
8276
+ // When connectAll is true, tools will dynamically get all servers for the tenant at runtime
8277
+ connectAll,
8278
+ // getTenantId will be called at runtime by each tool
8279
+ getTenantId: void 0
8280
+ // Tools will extract tenantId from _exeConfig.configurable.runConfig
7433
8281
  };
7434
8282
  return (0, import_langchain45.createMiddleware)({
7435
8283
  name: "metricsMiddleware",
@@ -7562,7 +8410,7 @@ function createAskUserClarifyMiddleware() {
7562
8410
  }
7563
8411
 
7564
8412
  // src/agent_lattice/builders/commonMiddleware.ts
7565
- function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
8413
+ async function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
7566
8414
  const middlewares = [];
7567
8415
  const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
7568
8416
  if (filesystemConfig?.enabled && filesystemBackend) {
@@ -7617,14 +8465,16 @@ function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
7617
8465
 
7618
8466
  // src/agent_lattice/builders/ReActAgentGraphBuilder.ts
7619
8467
  var ReActAgentGraphBuilder = class {
7620
- createFilesystemBackendFactory(middlewareConfigs) {
8468
+ createFilesystemBackendFactory(middlewareConfigs, agentLattice) {
7621
8469
  const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
7622
8470
  if (!filesystemConfig || !filesystemConfig.enabled) {
7623
8471
  return void 0;
7624
8472
  }
7625
8473
  const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
7626
- return async (config) => {
7627
- 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;
7628
8478
  let sandboxName = "global";
7629
8479
  if (isolatedLevel === "agent") {
7630
8480
  sandboxName = "agent";
@@ -7635,14 +8485,22 @@ var ReActAgentGraphBuilder = class {
7635
8485
  if (!sandboxManager) {
7636
8486
  throw new Error("Sandbox manager not found");
7637
8487
  }
8488
+ let workingDirectory = "/";
8489
+ if (workspaceId && projectId) {
8490
+ if (tenantId) {
8491
+ workingDirectory = `/tenants/${tenantId}/${workspaceId}/${projectId}`;
8492
+ } else {
8493
+ workingDirectory = `/${workspaceId}/${projectId}`;
8494
+ }
8495
+ }
7638
8496
  return new SandboxFilesystem({
7639
8497
  sandboxInstance: await sandboxManager.createSandbox(sandboxName),
7640
- workingDirectory: workspaceId && projectId ? `/${workspaceId}/${projectId}` : "/"
8498
+ workingDirectory
7641
8499
  });
7642
8500
  };
7643
8501
  }
7644
- createMiddlewares(middlewareConfigs) {
7645
- return createCommonMiddlewares(middlewareConfigs);
8502
+ async createMiddlewares(middlewareConfigs) {
8503
+ return await createCommonMiddlewares(middlewareConfigs);
7646
8504
  }
7647
8505
  /**
7648
8506
  * 构建ReAct Agent Graph
@@ -7651,15 +8509,15 @@ var ReActAgentGraphBuilder = class {
7651
8509
  * @param params Agent构建参数
7652
8510
  * @returns 返回CompiledGraph对象
7653
8511
  */
7654
- build(agentLattice, params) {
8512
+ async build(agentLattice, params) {
7655
8513
  const tools = params.tools.map((t) => {
7656
8514
  const tool48 = getToolClient(t.key);
7657
8515
  return tool48;
7658
8516
  }).filter((tool48) => tool48 !== void 0);
7659
8517
  const stateSchema2 = createReactAgentSchema(params.stateSchema);
7660
8518
  const middlewareConfigs = params.middleware || [];
7661
- const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs);
7662
- const middlewares = createCommonMiddlewares(middlewareConfigs, filesystemBackend);
8519
+ const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs, agentLattice);
8520
+ const middlewares = await createCommonMiddlewares(middlewareConfigs, filesystemBackend);
7663
8521
  return (0, import_langchain48.createAgent)({
7664
8522
  model: params.model,
7665
8523
  tools,
@@ -8480,14 +9338,18 @@ var StoreBackend = class {
8480
9338
  /**
8481
9339
  * Get the namespace for store operations.
8482
9340
  *
8483
- * If an assistant_id is available in stateAndStore, return
8484
- * [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"].
8485
9344
  * Otherwise return ["filesystem"].
8486
9345
  */
8487
9346
  getNamespace() {
8488
9347
  const namespace = "filesystem";
9348
+ const tenantId = this.stateAndStore.tenantId;
8489
9349
  const assistantId = this.stateAndStore.assistantId;
8490
- if (assistantId) {
9350
+ if (tenantId && assistantId) {
9351
+ return [tenantId, assistantId, namespace];
9352
+ } else if (assistantId) {
8491
9353
  return [assistantId, namespace];
8492
9354
  }
8493
9355
  return [namespace];
@@ -9914,8 +10776,8 @@ function createFilesystemBackendFactory(middlewareConfigs) {
9914
10776
  return void 0;
9915
10777
  }
9916
10778
  const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
9917
- return async (config) => {
9918
- const { workspaceId, projectId } = config;
10779
+ return async (stateAndStore) => {
10780
+ const { tenantId, workspaceId, projectId } = stateAndStore;
9919
10781
  let sandboxName = "global";
9920
10782
  if (isolatedLevel === "agent") {
9921
10783
  sandboxName = "agent";
@@ -9926,9 +10788,17 @@ function createFilesystemBackendFactory(middlewareConfigs) {
9926
10788
  if (!sandboxManager) {
9927
10789
  throw new Error("Sandbox manager not found");
9928
10790
  }
10791
+ let workingDirectory = "/";
10792
+ if (workspaceId && projectId) {
10793
+ if (tenantId) {
10794
+ workingDirectory = `/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`;
10795
+ } else {
10796
+ workingDirectory = `/workspaces/${workspaceId}/${projectId}`;
10797
+ }
10798
+ }
9929
10799
  return new SandboxFilesystem({
9930
10800
  sandboxInstance: await sandboxManager.createSandbox(sandboxName),
9931
- workingDirectory: workspaceId && projectId ? `/workspaces/${workspaceId}/${projectId}` : "/"
10801
+ workingDirectory
9932
10802
  });
9933
10803
  };
9934
10804
  }
@@ -9938,8 +10808,8 @@ var DeepAgentGraphBuilder = class {
9938
10808
  /**
9939
10809
  * 根据 middleware 配置创建 middlewares
9940
10810
  */
9941
- createMiddlewares(middlewareConfigs) {
9942
- return createCommonMiddlewares(middlewareConfigs);
10811
+ async createMiddlewares(middlewareConfigs) {
10812
+ return await createCommonMiddlewares(middlewareConfigs);
9943
10813
  }
9944
10814
  /**
9945
10815
  * 构建Deep Agent Graph
@@ -9948,12 +10818,12 @@ var DeepAgentGraphBuilder = class {
9948
10818
  * @param params Agent构建参数
9949
10819
  * @returns 返回CompiledGraph对象
9950
10820
  */
9951
- build(agentLattice, params) {
10821
+ async build(agentLattice, params) {
9952
10822
  const tools = params.tools.map((t) => {
9953
10823
  const toolClient = getToolClient(t.key);
9954
10824
  return toolClient;
9955
10825
  }).filter((tool48) => tool48 !== void 0);
9956
- const subagents = params.subAgents.map((sa) => {
10826
+ const subagents = await Promise.all(params.subAgents.map(async (sa) => {
9957
10827
  if (sa.client) {
9958
10828
  return {
9959
10829
  key: sa.config.key,
@@ -9962,7 +10832,7 @@ var DeepAgentGraphBuilder = class {
9962
10832
  runnable: sa.client
9963
10833
  };
9964
10834
  } else {
9965
- const subagentClient = createAgentClientFromAgentLattice({
10835
+ const subagentClient = await createAgentClientFromAgentLattice({
9966
10836
  config: sa.config
9967
10837
  });
9968
10838
  return {
@@ -9972,10 +10842,10 @@ var DeepAgentGraphBuilder = class {
9972
10842
  runnable: subagentClient
9973
10843
  };
9974
10844
  }
9975
- });
10845
+ }));
9976
10846
  const middlewareConfigs = params.middleware || [];
9977
10847
  const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
9978
- const middlewares = this.createMiddlewares(middlewareConfigs);
10848
+ const middlewares = await this.createMiddlewares(middlewareConfigs);
9979
10849
  const deepAgent = createDeepAgent({
9980
10850
  tools,
9981
10851
  model: params.model,
@@ -11551,7 +12421,7 @@ var TeamAgentGraphBuilder = class {
11551
12421
  * @param params - Build params with resolved tools and model
11552
12422
  * @returns AgentClient (the TeamLead ReactAgent)
11553
12423
  */
11554
- build(agentLattice, params) {
12424
+ async build(agentLattice, params) {
11555
12425
  const config = agentLattice.config;
11556
12426
  if (!(0, import_protocols.isTeamAgentConfig)(config)) {
11557
12427
  throw new Error(
@@ -11574,7 +12444,7 @@ var TeamAgentGraphBuilder = class {
11574
12444
  });
11575
12445
  const middlewareConfigs = params.middleware || [];
11576
12446
  let filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
11577
- const middlewares = createCommonMiddlewares(middlewareConfigs);
12447
+ const middlewares = await createCommonMiddlewares(middlewareConfigs);
11578
12448
  if (!filesystemBackend) {
11579
12449
  filesystemBackend = async (config2) => {
11580
12450
  return new StateBackend(config2);
@@ -11753,6 +12623,31 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11753
12623
  this.initialized = false;
11754
12624
  this.subscribeToAssistantEvents();
11755
12625
  }
12626
+ /**
12627
+ * 从store异步加载单个AgentLattice
12628
+ * 实现BaseLatticeManager的可选方法,支持从assistant store加载单个agent
12629
+ * @param tenantId 租户ID
12630
+ * @param key Agent键名
12631
+ * @returns AgentLattice或undefined
12632
+ */
12633
+ async loadItemFromStore(tenantId, key) {
12634
+ try {
12635
+ const storeLattice = getStoreLattice("default", "assistant");
12636
+ const assistant = await storeLattice.store.getAssistantById(tenantId, key);
12637
+ if (!assistant) {
12638
+ return void 0;
12639
+ }
12640
+ const config = assistantToConfig(assistant);
12641
+ const agentLattice = {
12642
+ config,
12643
+ client: void 0
12644
+ };
12645
+ return agentLattice;
12646
+ } catch (error) {
12647
+ console.error(`Failed to load agent from store [tenant: ${tenantId}, key: ${key}]:`, error);
12648
+ return void 0;
12649
+ }
12650
+ }
11756
12651
  /**
11757
12652
  * 获取AgentLatticeManager单例实例
11758
12653
  */
@@ -11762,11 +12657,15 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11762
12657
  }
11763
12658
  return _AgentLatticeManager._instance;
11764
12659
  }
12660
+ /**
12661
+ * @deprecated This method loads assistants only for the "default" tenant.
12662
+ * Use initializeStoredAssistantsForTenant(tenantId) for proper tenant isolation.
12663
+ */
11765
12664
  async initializeStoredAssistants() {
11766
12665
  if (this.initialized) return;
11767
12666
  try {
11768
12667
  const storeLattice = getStoreLattice("default", "assistant");
11769
- const assistants = await storeLattice.store.getAllAssistants();
12668
+ const assistants = await storeLattice.store.getAllAssistants("default");
11770
12669
  for (const assistant of assistants) {
11771
12670
  if (this.has(assistant.id)) continue;
11772
12671
  const config = assistantToConfig(assistant);
@@ -11779,33 +12678,33 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11779
12678
  }
11780
12679
  subscribeToAssistantEvents() {
11781
12680
  event_bus_default.subscribe("assistant:created", (data) => {
11782
- this.handleAssistantChange(data.id);
12681
+ this.handleAssistantChange(data.id, data.tenantId ?? "default");
11783
12682
  });
11784
12683
  event_bus_default.subscribe("assistant:updated", (data) => {
11785
- this.handleAssistantChange(data.id);
12684
+ this.handleAssistantChange(data.id, data.tenantId ?? "default");
11786
12685
  });
11787
12686
  event_bus_default.subscribe("assistant:deleted", (data) => {
11788
- this.handleAssistantDelete(data.id);
12687
+ this.handleAssistantDelete(data.id, data.tenantId ?? "default");
11789
12688
  });
11790
12689
  }
11791
- async handleAssistantChange(assistantId) {
12690
+ async handleAssistantChange(assistantId, tenantId = "default") {
11792
12691
  try {
11793
12692
  const storeLattice = getStoreLattice("default", "assistant");
11794
- const assistant = await storeLattice.store.getAssistantById(assistantId);
12693
+ const assistant = await storeLattice.store.getAssistantById(tenantId, assistantId);
11795
12694
  if (assistant) {
11796
- if (this.has(assistantId)) {
11797
- this.remove(assistantId);
12695
+ if (this.hasWithTenant(tenantId, assistantId)) {
12696
+ this.removeWithTenant(tenantId, assistantId);
11798
12697
  }
11799
12698
  const config = assistantToConfig(assistant);
11800
- this.registerLattice(config);
12699
+ this.registerLatticeWithTenant(tenantId, config);
11801
12700
  }
11802
12701
  } catch (error) {
11803
- console.error(`Failed to handle assistant change for ${assistantId}:`, error);
12702
+ console.error(`Failed to handle assistant change for ${assistantId} (tenant: ${tenantId}):`, error);
11804
12703
  }
11805
12704
  }
11806
- handleAssistantDelete(assistantId) {
11807
- if (this.has(assistantId)) {
11808
- this.remove(assistantId);
12705
+ handleAssistantDelete(assistantId, tenantId = "default") {
12706
+ if (this.hasWithTenant(tenantId, assistantId)) {
12707
+ this.removeWithTenant(tenantId, assistantId);
11809
12708
  }
11810
12709
  }
11811
12710
  /**
@@ -11814,8 +12713,96 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11814
12713
  getLatticeType() {
11815
12714
  return "agents";
11816
12715
  }
12716
+ // ========== 带租户的新API ==========
12717
+ /**
12718
+ * 带租户注册Agent Lattice
12719
+ * @param tenantId 租户ID
12720
+ * @param config Agent配置
12721
+ */
12722
+ registerLatticeWithTenant(tenantId, config) {
12723
+ const agentLattice = {
12724
+ config: { ...config, tenantId },
12725
+ client: void 0
12726
+ // 客户端将在需要时由initializeClient创建
12727
+ };
12728
+ this.registerWithTenant(tenantId, config.key, agentLattice);
12729
+ }
12730
+ /**
12731
+ * 带租户获取AgentLattice
12732
+ * @param tenantId 租户ID
12733
+ * @param key Lattice键名
12734
+ */
12735
+ getAgentLatticeWithTenant(tenantId, key) {
12736
+ return this.getWithTenant(tenantId, key);
12737
+ }
12738
+ /**
12739
+ * 带租户检查Lattice是否存在
12740
+ * @param tenantId 租户ID
12741
+ * @param key Lattice键名
12742
+ */
12743
+ hasAgentLatticeWithTenant(tenantId, key) {
12744
+ return this.hasWithTenant(tenantId, key);
12745
+ }
12746
+ /**
12747
+ * 带租户移除Lattice
12748
+ * @param tenantId 租户ID
12749
+ * @param key Lattice键名
12750
+ */
12751
+ removeAgentLatticeWithTenant(tenantId, key) {
12752
+ return this.removeWithTenant(tenantId, key);
12753
+ }
12754
+ /**
12755
+ * 获取指定租户的所有Agent Lattice
12756
+ * @param tenantId 租户ID
12757
+ */
12758
+ getAllAgentLatticesByTenant(tenantId) {
12759
+ return this.getAllByTenant(tenantId);
12760
+ }
12761
+ /**
12762
+ * 清空指定租户的所有Agent Lattice
12763
+ * @param tenantId 租户ID
12764
+ */
12765
+ clearAgentLatticesByTenant(tenantId) {
12766
+ this.clearByTenant(tenantId);
12767
+ }
12768
+ /**
12769
+ * 带租户获取Agent配置
12770
+ * @param tenantId 租户ID
12771
+ * @param key Lattice键名
12772
+ */
12773
+ getAgentConfigWithTenant(tenantId, key) {
12774
+ return this.getAgentLatticeWithTenant(tenantId, key)?.config;
12775
+ }
12776
+ /**
12777
+ * 获取指定租户的所有Agent配置
12778
+ * 先从数据库加载该租户的 assistants,然后返回所有配置
12779
+ * @param tenantId 租户ID
12780
+ */
12781
+ async getAllAgentConfigsByTenant(tenantId) {
12782
+ await this.initializeStoredAssistantsForTenant(tenantId);
12783
+ return this.getAllAgentLatticesByTenant(tenantId).map((lattice) => lattice.config);
12784
+ }
12785
+ /**
12786
+ * 从数据库加载指定租户的存储助手
12787
+ * @param tenantId 租户ID
12788
+ */
12789
+ async initializeStoredAssistantsForTenant(tenantId) {
12790
+ try {
12791
+ const storeLattice = getStoreLattice("default", "assistant");
12792
+ const assistants = await storeLattice.store.getAllAssistants(tenantId);
12793
+ for (const assistant of assistants) {
12794
+ if (this.hasAgentLatticeWithTenant(tenantId, assistant.id)) continue;
12795
+ const config = assistantToConfig(assistant);
12796
+ this.registerLatticeWithTenant(tenantId, config);
12797
+ }
12798
+ } catch (error) {
12799
+ console.error(`Failed to initialize stored assistants for tenant ${tenantId}:`, error);
12800
+ }
12801
+ }
12802
+ // ========== 向后兼容的旧API(使用 default 租户) ==========
11817
12803
  /**
11818
- * 注册Agent Lattice
12804
+ * 注册Agent Lattice(向后兼容,使用 "default" 租户)
12805
+ * @deprecated Use registerLatticeWithTenant(tenantId, config) instead
11819
12806
  * @param config Agent配置
11820
12807
  */
11821
12808
  registerLattice(config) {
@@ -11853,7 +12840,8 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11853
12840
  return this.remove(key);
11854
12841
  }
11855
12842
  /**
11856
- * 获取AgentLattice
12843
+ * 获取AgentLattice(向后兼容,使用 "default" 租户)
12844
+ * @deprecated Use getAgentLatticeWithTenant(tenantId, key) instead
11857
12845
  * @param key Lattice键名
11858
12846
  */
11859
12847
  getAgentLattice(key) {
@@ -11866,25 +12854,28 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11866
12854
  return this.getAll();
11867
12855
  }
11868
12856
  /**
11869
- * 检查Lattice是否存在
12857
+ * 检查Lattice是否存在(向后兼容,使用 "default" 租户)
12858
+ * @deprecated Use hasAgentLatticeWithTenant(tenantId, key) instead
11870
12859
  * @param key Lattice键名
11871
12860
  */
11872
12861
  hasLattice(key) {
11873
12862
  return this.has(key);
11874
12863
  }
11875
12864
  /**
11876
- * 移除Lattice
12865
+ * 移除Lattice(向后兼容,使用 "default" 租户)
12866
+ * @deprecated Use removeAgentLatticeWithTenant(tenantId, key) instead
11877
12867
  * @param key Lattice键名
11878
12868
  */
11879
12869
  removeLattice(key) {
11880
12870
  return this.remove(key);
11881
12871
  }
11882
12872
  /**
11883
- * 获取Agent配置
12873
+ * 获取Agent配置(向后兼容,使用 "default" 租户)
12874
+ * @deprecated Use getAgentConfigWithTenant(tenantId, key) instead
11884
12875
  * @param key Lattice键名
11885
12876
  */
11886
12877
  getAgentConfig(key) {
11887
- return this.getAgentLattice(key)?.config;
12878
+ return this.getAgentLatticeWithTenant("default", key)?.config;
11888
12879
  }
11889
12880
  /**
11890
12881
  * 获取所有Agent配置
@@ -11905,8 +12896,9 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11905
12896
  return false;
11906
12897
  }
11907
12898
  try {
11908
- if (agentLattice.config.schema) {
11909
- agentLattice.config.schema.parse(input);
12899
+ const config = agentLattice.config;
12900
+ if ("schema" in config && config.schema) {
12901
+ config.schema.parse(input);
11910
12902
  }
11911
12903
  return true;
11912
12904
  } catch {
@@ -11954,9 +12946,10 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11954
12946
  * @returns 返回Agent构建参数
11955
12947
  */
11956
12948
  buildAgentParams(agentLattice, options) {
12949
+ const tenantId = agentLattice.config.tenantId || "default";
11957
12950
  const paramsBuilder = new AgentParamsBuilder((key) => {
11958
- this.initializeClient(key);
11959
- return this.getAgentLattice(key);
12951
+ this.initializeClient(tenantId, key);
12952
+ return this.getAgentLatticeWithTenant(tenantId, key);
11960
12953
  });
11961
12954
  return paramsBuilder.buildParams(agentLattice, options);
11962
12955
  }
@@ -11967,7 +12960,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11967
12960
  * @param options Build options
11968
12961
  * @returns AgentClient instance
11969
12962
  */
11970
- createAgentClientFromConfig(agentLattice, options) {
12963
+ async createAgentClientFromConfig(agentLattice, options) {
11971
12964
  const resolvedConfig = this.resolveInheritedConfig(agentLattice.config);
11972
12965
  const resolvedLattice = {
11973
12966
  ...agentLattice,
@@ -11976,26 +12969,50 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11976
12969
  const factory = AgentGraphBuilderFactory.getInstance();
11977
12970
  const builder = factory.getBuilder(resolvedConfig.type);
11978
12971
  const params = this.buildAgentParams(resolvedLattice, options);
11979
- return builder.build(resolvedLattice, params);
12972
+ return await builder.build(resolvedLattice, params);
11980
12973
  }
11981
12974
  /**
11982
12975
  * 初始化Agent客户端
11983
12976
  *
11984
12977
  * 使用AgentGraphBuilderFactory构建Graph并设置为客户端
11985
12978
  *
12979
+ * @param tenantId 租户ID
11986
12980
  * @param key Lattice键名
11987
12981
  * @param options 构建选项
11988
12982
  * @returns 返回CompiledGraph对象
11989
12983
  */
11990
- initializeClient(key, options) {
11991
- const agentLattice = this.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);
11992
13009
  if (!agentLattice) {
11993
- throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728`);
13010
+ throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
11994
13011
  }
11995
13012
  if (agentLattice.client) {
11996
13013
  return agentLattice.client;
11997
13014
  }
11998
- const graph = this.createAgentClientFromConfig(agentLattice, options);
13015
+ const graph = await this.createAgentClientFromConfig(agentLattice, options);
11999
13016
  agentLattice.client = graph;
12000
13017
  return graph;
12001
13018
  }
@@ -12004,19 +13021,24 @@ var agentLatticeManager = AgentLatticeManager.getInstance();
12004
13021
  var registerAgentLattice = (config) => {
12005
13022
  agentLatticeManager.registerLattice(config);
12006
13023
  };
12007
- var 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
+ }
12008
13031
  configs.forEach((config) => {
12009
- agentLatticeManager.registerLattice(config);
13032
+ agentLatticeManager.registerLatticeWithTenant(tenantId, config);
12010
13033
  });
12011
13034
  };
12012
- var getAgentLattice = (key) => agentLatticeManager.getAgentLattice(key);
12013
13035
  var getAgentConfig = (key) => agentLatticeManager.getAgentConfig(key);
12014
13036
  var getAllAgentConfigs = () => agentLatticeManager.getAllAgentConfigs();
12015
13037
  var validateAgentInput = (key, input) => agentLatticeManager.validateAgentInput(key, input);
12016
13038
  var registerTeammateAgent = (key, client) => agentLatticeManager.registerTeammateAgent(key, client);
12017
13039
  var unregisterTeammateAgent = (key) => agentLatticeManager.unregisterTeammateAgent(key);
12018
- var getAgentClient = (key, options) => agentLatticeManager.initializeClient(key, options);
12019
- var createAgentClientFromAgentLattice = (agentLattice, options) => agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
13040
+ var getAgentClient = (tenantId, key, options) => agentLatticeManager.initializeClient(tenantId, key, options);
13041
+ var createAgentClientFromAgentLattice = async (agentLattice, options) => await agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
12020
13042
 
12021
13043
  // src/chunk_buffer_lattice/ChunkBuffer.ts
12022
13044
  var ChunkBuffer = class {
@@ -12094,6 +13116,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12094
13116
  buffer = {
12095
13117
  threadId,
12096
13118
  chunks$: new import_rxjs.ReplaySubject(this.config.maxChunks),
13119
+ chunks: [],
12097
13120
  status: "active" /* ACTIVE */,
12098
13121
  createdAt: now,
12099
13122
  updatedAt: now,
@@ -12104,14 +13127,27 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12104
13127
  if (buffer.status !== "active" /* ACTIVE */) {
12105
13128
  buffer.status = "active" /* ACTIVE */;
12106
13129
  buffer.chunks$ = new import_rxjs.ReplaySubject(this.config.maxChunks);
13130
+ buffer.chunks = [];
12107
13131
  buffer.updatedAt = Date.now();
12108
13132
  buffer.expiresAt = Date.now() + this.config.ttl;
12109
13133
  }
12110
13134
  return buffer;
12111
13135
  }
12112
- async addChunk(threadId, content) {
13136
+ async addChunk(threadId, arg2, arg3) {
12113
13137
  const buffer = this.getOrCreateBuffer(threadId);
12114
- 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);
12115
13151
  buffer.chunks$.next(chunk);
12116
13152
  buffer.updatedAt = Date.now();
12117
13153
  buffer.expiresAt = Date.now() + this.config.ttl;
@@ -12143,7 +13179,25 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12143
13179
  async getThreadBuffer(threadId) {
12144
13180
  const buffer = this.getBufferIfValid(threadId);
12145
13181
  if (!buffer) return void 0;
12146
- return 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);
12147
13201
  }
12148
13202
  async clearThread(threadId) {
12149
13203
  this.buffers.delete(threadId);
@@ -12273,6 +13327,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12273
13327
  let activeCount = 0;
12274
13328
  let completedCount = 0;
12275
13329
  let abortedCount = 0;
13330
+ let totalChunkCount = 0;
12276
13331
  const validBuffers = [];
12277
13332
  for (const [threadId, buffer] of this.buffers.entries()) {
12278
13333
  if (this.isExpired(buffer)) {
@@ -12293,12 +13348,14 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12293
13348
  abortedCount++;
12294
13349
  break;
12295
13350
  }
13351
+ totalChunkCount += buffer.chunks.length;
12296
13352
  }
12297
13353
  return {
12298
13354
  totalThreads: validBuffers.length,
12299
13355
  activeThreads: activeCount,
12300
13356
  completedThreads: completedCount,
12301
13357
  abortedThreads: abortedCount,
13358
+ totalChunks: totalChunkCount,
12302
13359
  config: this.config
12303
13360
  };
12304
13361
  }
@@ -12459,6 +13516,9 @@ var MemoryScheduleStorage = class {
12459
13516
  let result = [];
12460
13517
  for (const task of this.tasks.values()) {
12461
13518
  let match = true;
13519
+ if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
13520
+ match = false;
13521
+ }
12462
13522
  if (filters?.status !== void 0 && task.status !== filters.status) {
12463
13523
  match = false;
12464
13524
  }
@@ -12495,6 +13555,9 @@ var MemoryScheduleStorage = class {
12495
13555
  let count = 0;
12496
13556
  for (const task of this.tasks.values()) {
12497
13557
  let match = true;
13558
+ if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
13559
+ match = false;
13560
+ }
12498
13561
  if (filters?.status !== void 0 && task.status !== filters.status) {
12499
13562
  match = false;
12500
13563
  }
@@ -13832,6 +14895,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13832
14895
  getLatticeType() {
13833
14896
  return "skills";
13834
14897
  }
14898
+ /**
14899
+ * Default tenant ID for store operations
14900
+ * Note: SkillLatticeManager operates without explicit tenant context.
14901
+ * Store methods require tenantId for protocol compliance.
14902
+ */
14903
+ getDefaultTenantId() {
14904
+ return "default";
14905
+ }
13835
14906
  /**
13836
14907
  * Configure store for persistence
13837
14908
  * @param storeKey Store key name registered in StoreLatticeManager
@@ -13872,12 +14943,13 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13872
14943
  client.store = store;
13873
14944
  }
13874
14945
  /**
13875
- * Register a skill Lattice
14946
+ * Register a skill Lattice with tenant
14947
+ * @param tenantId Tenant ID
13876
14948
  * @param key Lattice key name
13877
14949
  * @param config Skill configuration
13878
14950
  * @param client Optional skill client implementation
13879
14951
  */
13880
- async registerLattice(key, config, client) {
14952
+ async registerLatticeWithTenant(tenantId, key, config, client) {
13881
14953
  if (!config.name) {
13882
14954
  throw new Error("Skill name is required");
13883
14955
  }
@@ -13899,10 +14971,10 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13899
14971
  config,
13900
14972
  client: client ?? null
13901
14973
  };
13902
- this.register(key, skillLattice);
14974
+ this.registerWithTenant(tenantId, key, skillLattice);
13903
14975
  if (store) {
13904
14976
  try {
13905
- await store.createSkill(key, {
14977
+ await store.createSkill(tenantId, key, {
13906
14978
  name: config.name,
13907
14979
  description: config.description,
13908
14980
  license: config.license,
@@ -13920,24 +14992,43 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13920
14992
  }
13921
14993
  }
13922
14994
  /**
13923
- * 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
13924
15015
  * @param key Lattice key name
13925
15016
  */
13926
15017
  getSkillLattice(key) {
13927
- return this.get(key);
15018
+ return this.getWithTenant(this.getDefaultTenantId(), key);
13928
15019
  }
13929
15020
  /**
13930
- * Get all skill Lattices from store
13931
- * 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
13932
15023
  */
13933
- async getAllLattices() {
15024
+ async getAllLatticesWithTenant(tenantId) {
13934
15025
  const store = this.getStore();
13935
15026
  if (!store) {
13936
- return this.getAll();
15027
+ return this.getAllByTenant(tenantId);
13937
15028
  }
13938
- const skills = await store.getAllSkills();
15029
+ const skills = await store.getAllSkills(tenantId);
13939
15030
  return skills.map((skill) => {
13940
- const memoryLattice = this.get(skill.id);
15031
+ const memoryLattice = this.getWithTenant(tenantId, skill.id);
13941
15032
  const client = memoryLattice?.client || null;
13942
15033
  if (client && store) {
13943
15034
  this.injectStoreIntoClient(client, store);
@@ -13958,23 +15049,40 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13958
15049
  });
13959
15050
  }
13960
15051
  /**
13961
- * 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
13962
15069
  * @param key Lattice key name
13963
15070
  */
13964
15071
  hasLattice(key) {
13965
- return this.has(key);
15072
+ return this.hasWithTenant(this.getDefaultTenantId(), key);
13966
15073
  }
13967
15074
  /**
13968
- * Remove Lattice
15075
+ * Remove Lattice with tenant
15076
+ * @param tenantId Tenant ID
13969
15077
  * @param key Lattice key name
13970
15078
  */
13971
- async removeLattice(key) {
13972
- const removed = this.remove(key);
15079
+ async removeLatticeWithTenant(tenantId, key) {
15080
+ const removed = this.removeWithTenant(tenantId, key);
13973
15081
  if (removed) {
13974
15082
  const store = this.getStore();
13975
15083
  if (store) {
13976
15084
  try {
13977
- await store.deleteSkill(key);
15085
+ await store.deleteSkill(tenantId, key);
13978
15086
  } catch (error) {
13979
15087
  console.warn(
13980
15088
  `Failed to remove skill ${key} from store:`,
@@ -13985,6 +15093,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13985
15093
  }
13986
15094
  return removed;
13987
15095
  }
15096
+ /**
15097
+ * Remove Lattice (backward compatible, uses "default" tenant)
15098
+ * @deprecated Use removeLatticeWithTenant(tenantId, key) instead
15099
+ * @param key Lattice key name
15100
+ */
15101
+ async removeLattice(key) {
15102
+ return this.removeLatticeWithTenant(this.getDefaultTenantId(), key);
15103
+ }
13988
15104
  /**
13989
15105
  * Clear all Lattices
13990
15106
  */
@@ -14082,7 +15198,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
14082
15198
  if (!store) {
14083
15199
  throw new Error("No store configured. Call configureStore() first.");
14084
15200
  }
14085
- const skills = await store.getAllSkills();
15201
+ const skills = await store.getAllSkills(this.getDefaultTenantId());
14086
15202
  for (const skill of skills) {
14087
15203
  const skillLattice = {
14088
15204
  key: skill.id,
@@ -14119,7 +15235,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
14119
15235
  ...updates
14120
15236
  };
14121
15237
  skillLattice.config = updatedConfig;
14122
- await store.updateSkill(key, {
15238
+ await store.updateSkill(this.getDefaultTenantId(), key, {
14123
15239
  name: updatedConfig.name,
14124
15240
  description: updatedConfig.description,
14125
15241
  license: updatedConfig.license,
@@ -14344,6 +15460,7 @@ function clearEncryptionKeyCache() {
14344
15460
  QueueLatticeManager,
14345
15461
  SandboxFilesystem,
14346
15462
  SandboxLatticeManager,
15463
+ SandboxSkillStore,
14347
15464
  ScheduleLatticeManager,
14348
15465
  SemanticMetricsClient,
14349
15466
  SkillLatticeManager,
@@ -14391,7 +15508,6 @@ function clearEncryptionKeyCache() {
14391
15508
  formatReadResponse,
14392
15509
  getAgentClient,
14393
15510
  getAgentConfig,
14394
- getAgentLattice,
14395
15511
  getAllAgentConfigs,
14396
15512
  getAllToolDefinitions,
14397
15513
  getCheckpointSaver,
@@ -14428,6 +15544,7 @@ function clearEncryptionKeyCache() {
14428
15544
  performStringReplacement,
14429
15545
  queueLatticeManager,
14430
15546
  registerAgentLattice,
15547
+ registerAgentLatticeWithTenant,
14431
15548
  registerAgentLattices,
14432
15549
  registerCheckpointSaver,
14433
15550
  registerChunkBuffer,