@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.mjs CHANGED
@@ -12,37 +12,148 @@ var _BaseLatticeManager = class _BaseLatticeManager {
12
12
  throw new Error("\u5FC5\u987B\u7531\u5B50\u7C7B\u5B9E\u73B0");
13
13
  }
14
14
  /**
15
- * 构造完整的键名,包含类型前缀
15
+ * 构造完整的键名,包含类型前缀和租户ID
16
+ * @param tenantId 租户ID,全局共享使用 "default"
16
17
  * @param key 原始键名
17
18
  */
18
- getFullKey(key) {
19
- return `${this.getLatticeType()}.${key}`;
19
+ getFullKey(tenantId, key) {
20
+ return `${this.getLatticeType()}:${tenantId}:${key}`;
20
21
  }
22
+ // ========== 带租户的新API ==========
21
23
  /**
22
- * 注册项目
24
+ * 带租户的注册项目
25
+ * @param tenantId 租户ID
23
26
  * @param key 项目键名(不含前缀)
24
27
  * @param item 项目实例
25
28
  */
26
- register(key, item) {
27
- const fullKey = this.getFullKey(key);
29
+ registerWithTenant(tenantId, key, item) {
30
+ const fullKey = this.getFullKey(tenantId, key);
28
31
  if (_BaseLatticeManager.registry.has(fullKey)) {
29
32
  throw new Error(`\u9879\u76EE "${fullKey}" \u5DF2\u7ECF\u5B58\u5728\uFF0C\u65E0\u6CD5\u91CD\u590D\u6CE8\u518C`);
30
33
  }
31
34
  _BaseLatticeManager.registry.set(fullKey, item);
32
35
  }
33
36
  /**
34
- * 获取指定项目
37
+ * 带租户的获取指定项目(同步)
38
+ * @param tenantId 租户ID
35
39
  * @param key 项目键名(不含前缀)
36
40
  */
37
- get(key) {
38
- const fullKey = this.getFullKey(key);
41
+ getWithTenant(tenantId, key) {
42
+ const fullKey = this.getFullKey(tenantId, key);
39
43
  return _BaseLatticeManager.registry.get(fullKey);
40
44
  }
41
45
  /**
42
- * 获取所有当前类型的项目
46
+ * 带租户的获取指定项目(异步,支持从store回退加载)
47
+ * 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
48
+ * @param tenantId 租户ID
49
+ * @param key 项目键名(不含前缀)
50
+ * @returns 项目实例,如果未找到则返回undefined
51
+ */
52
+ async getOrLoadWithTenant(tenantId, key) {
53
+ const item = this.getWithTenant(tenantId, key);
54
+ if (item !== void 0) {
55
+ return item;
56
+ }
57
+ if (this.loadItemFromStore) {
58
+ const loadedItem = await this.loadItemFromStore(tenantId, key);
59
+ if (loadedItem !== void 0) {
60
+ this.registerWithTenant(tenantId, key, loadedItem);
61
+ return loadedItem;
62
+ }
63
+ }
64
+ return void 0;
65
+ }
66
+ /**
67
+ * 带租户的检查项目是否存在(同步)
68
+ * @param tenantId 租户ID
69
+ * @param key 项目键名(不含前缀)
70
+ */
71
+ hasWithTenant(tenantId, key) {
72
+ const fullKey = this.getFullKey(tenantId, key);
73
+ return _BaseLatticeManager.registry.has(fullKey);
74
+ }
75
+ /**
76
+ * 带租户的检查项目是否存在(异步,支持从store回退加载)
77
+ * 如果内存中不存在且子类实现了loadItemFromStore,则尝试从store加载
78
+ * @param tenantId 租户ID
79
+ * @param key 项目键名(不含前缀)
80
+ * @returns 如果存在或能从store加载则返回true
81
+ */
82
+ async hasOrLoadWithTenant(tenantId, key) {
83
+ if (this.hasWithTenant(tenantId, key)) {
84
+ return true;
85
+ }
86
+ if (this.loadItemFromStore) {
87
+ const loadedItem = await this.loadItemFromStore(tenantId, key);
88
+ if (loadedItem !== void 0) {
89
+ this.registerWithTenant(tenantId, key, loadedItem);
90
+ return true;
91
+ }
92
+ }
93
+ return false;
94
+ }
95
+ /**
96
+ * 带租户的移除项目
97
+ * @param tenantId 租户ID
98
+ * @param key 项目键名(不含前缀)
99
+ */
100
+ removeWithTenant(tenantId, key) {
101
+ const fullKey = this.getFullKey(tenantId, key);
102
+ return _BaseLatticeManager.registry.delete(fullKey);
103
+ }
104
+ /**
105
+ * 获取指定租户的所有项目
106
+ * @param tenantId 租户ID
107
+ */
108
+ getAllByTenant(tenantId) {
109
+ const prefix = `${this.getLatticeType()}:${tenantId}:`;
110
+ const result = [];
111
+ for (const [key, value] of _BaseLatticeManager.registry.entries()) {
112
+ if (key.startsWith(prefix)) {
113
+ result.push(value);
114
+ }
115
+ }
116
+ return result;
117
+ }
118
+ /**
119
+ * 清空指定租户的所有项目
120
+ * @param tenantId 租户ID
121
+ */
122
+ clearByTenant(tenantId) {
123
+ const prefix = `${this.getLatticeType()}:${tenantId}:`;
124
+ const keysToDelete = [];
125
+ for (const key of _BaseLatticeManager.registry.keys()) {
126
+ if (key.startsWith(prefix)) {
127
+ keysToDelete.push(key);
128
+ }
129
+ }
130
+ for (const key of keysToDelete) {
131
+ _BaseLatticeManager.registry.delete(key);
132
+ }
133
+ }
134
+ // ========== 向后兼容的旧API(使用 default 租户) ==========
135
+ /**
136
+ * 注册项目(向后兼容,使用 "default" 租户)
137
+ * @deprecated Use registerWithTenant(tenantId, key, item) instead
138
+ * @param key 项目键名(不含前缀)
139
+ * @param item 项目实例
140
+ */
141
+ register(key, item) {
142
+ this.registerWithTenant("default", key, item);
143
+ }
144
+ /**
145
+ * 获取指定项目(向后兼容,使用 "default" 租户)
146
+ * @deprecated Use getWithTenant(tenantId, key) instead
147
+ * @param key 项目键名(不含前缀)
148
+ */
149
+ get(key) {
150
+ return this.getWithTenant("default", key);
151
+ }
152
+ /**
153
+ * 获取所有当前类型的项目(向后兼容,包含所有租户)
43
154
  */
44
155
  getAll() {
45
- const prefix = `${this.getLatticeType()}.`;
156
+ const prefix = `${this.getLatticeType()}:`;
46
157
  const result = [];
47
158
  for (const [key, value] of _BaseLatticeManager.registry.entries()) {
48
159
  if (key.startsWith(prefix)) {
@@ -52,26 +163,26 @@ var _BaseLatticeManager = class _BaseLatticeManager {
52
163
  return result;
53
164
  }
54
165
  /**
55
- * 检查项目是否存在
166
+ * 检查项目是否存在(向后兼容,使用 "default" 租户)
167
+ * @deprecated Use hasWithTenant(tenantId, key) instead
56
168
  * @param key 项目键名(不含前缀)
57
169
  */
58
170
  has(key) {
59
- const fullKey = this.getFullKey(key);
60
- return _BaseLatticeManager.registry.has(fullKey);
171
+ return this.hasWithTenant("default", key);
61
172
  }
62
173
  /**
63
- * 移除项目
174
+ * 移除项目(向后兼容,使用 "default" 租户)
175
+ * @deprecated Use removeWithTenant(tenantId, key) instead
64
176
  * @param key 项目键名(不含前缀)
65
177
  */
66
178
  remove(key) {
67
- const fullKey = this.getFullKey(key);
68
- return _BaseLatticeManager.registry.delete(fullKey);
179
+ return this.removeWithTenant("default", key);
69
180
  }
70
181
  /**
71
- * 清空当前类型的所有项目
182
+ * 清空当前类型的所有项目(向后兼容,包含所有租户)
72
183
  */
73
184
  clear() {
74
- const prefix = `${this.getLatticeType()}.`;
185
+ const prefix = `${this.getLatticeType()}:`;
75
186
  const keysToDelete = [];
76
187
  for (const key of _BaseLatticeManager.registry.keys()) {
77
188
  if (key.startsWith(prefix)) {
@@ -83,10 +194,10 @@ var _BaseLatticeManager = class _BaseLatticeManager {
83
194
  }
84
195
  }
85
196
  /**
86
- * 获取当前类型的项目数量
197
+ * 获取当前类型的项目数量(向后兼容,包含所有租户)
87
198
  */
88
199
  count() {
89
- const prefix = `${this.getLatticeType()}.`;
200
+ const prefix = `${this.getLatticeType()}:`;
90
201
  let count = 0;
91
202
  for (const key of _BaseLatticeManager.registry.keys()) {
92
203
  if (key.startsWith(prefix)) {
@@ -96,10 +207,26 @@ var _BaseLatticeManager = class _BaseLatticeManager {
96
207
  return count;
97
208
  }
98
209
  /**
99
- * 获取当前类型的项目键名列表(不含前缀)
210
+ * 获取当前类型的项目键名列表(向后兼容,包含所有租户)
211
+ * 返回格式: {tenantId}:{key}
100
212
  */
101
213
  keys() {
102
- const prefix = `${this.getLatticeType()}.`;
214
+ const prefix = `${this.getLatticeType()}:`;
215
+ const prefixLength = prefix.length;
216
+ const result = [];
217
+ for (const key of _BaseLatticeManager.registry.keys()) {
218
+ if (key.startsWith(prefix)) {
219
+ result.push(key.substring(prefixLength));
220
+ }
221
+ }
222
+ return result;
223
+ }
224
+ /**
225
+ * 获取当前类型的项目键名列表(仅指定租户,不含租户前缀)
226
+ * @param tenantId 租户ID
227
+ */
228
+ keysByTenant(tenantId) {
229
+ const prefix = `${this.getLatticeType()}:${tenantId}:`;
103
230
  const prefixLength = prefix.length;
104
231
  const result = [];
105
232
  for (const key of _BaseLatticeManager.registry.keys()) {
@@ -762,7 +889,7 @@ var PostgresDatabase = class {
762
889
  var SqlDatabaseManager = class _SqlDatabaseManager {
763
890
  constructor() {
764
891
  this.databases = /* @__PURE__ */ new Map();
765
- this.defaultDatabaseKey = null;
892
+ this.defaultDatabaseKeys = /* @__PURE__ */ new Map();
766
893
  }
767
894
  /**
768
895
  * Get the singleton instance
@@ -774,11 +901,23 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
774
901
  return _SqlDatabaseManager.instance;
775
902
  }
776
903
  /**
777
- * Register a database connection
778
- * @param key - Unique identifier for the database
904
+ * Get or create tenant database map
905
+ */
906
+ getTenantDatabases(tenantId) {
907
+ let tenantDbs = this.databases.get(tenantId);
908
+ if (!tenantDbs) {
909
+ tenantDbs = /* @__PURE__ */ new Map();
910
+ this.databases.set(tenantId, tenantDbs);
911
+ }
912
+ return tenantDbs;
913
+ }
914
+ /**
915
+ * Register a database connection for a tenant
916
+ * @param tenantId - Tenant identifier
917
+ * @param key - Unique identifier for the database within the tenant
779
918
  * @param config - Database configuration
780
919
  */
781
- registerDatabase(key, config) {
920
+ registerDatabase(tenantId, key, config) {
782
921
  let database;
783
922
  switch (config.type) {
784
923
  case "postgres":
@@ -791,74 +930,115 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
791
930
  default:
792
931
  throw new Error(`Unsupported database type: ${config.type}`);
793
932
  }
794
- this.databases.set(key, database);
795
- if (this.defaultDatabaseKey === null) {
796
- this.defaultDatabaseKey = key;
933
+ const tenantDbs = this.getTenantDatabases(tenantId);
934
+ tenantDbs.set(key, database);
935
+ if (!this.defaultDatabaseKeys.has(tenantId)) {
936
+ this.defaultDatabaseKeys.set(tenantId, key);
797
937
  }
798
938
  }
799
939
  /**
800
- * Set the default database
940
+ * Set the default database for a tenant
941
+ * @param tenantId - Tenant identifier
801
942
  * @param key - Database key to set as default
802
943
  */
803
- setDefaultDatabase(key) {
804
- if (!this.databases.has(key)) {
805
- throw new Error(`Database '${key}' not found`);
944
+ setDefaultDatabase(tenantId, key) {
945
+ const tenantDbs = this.databases.get(tenantId);
946
+ if (!tenantDbs || !tenantDbs.has(key)) {
947
+ throw new Error(`Database '${key}' not found for tenant '${tenantId}'`);
806
948
  }
807
- this.defaultDatabaseKey = key;
949
+ this.defaultDatabaseKeys.set(tenantId, key);
808
950
  }
809
951
  /**
810
- * Get a database by key
952
+ * Get a database by key for a specific tenant
953
+ * @param tenantId - Tenant identifier (required)
811
954
  * @param key - Database key (optional, uses default if not provided)
955
+ * @returns ISqlDatabase instance
956
+ * @throws Error if tenant or database not found
812
957
  */
813
- getDatabase(key) {
814
- const dbKey = key || this.defaultDatabaseKey;
958
+ getDatabase(tenantId, key) {
959
+ const tenantDbs = this.databases.get(tenantId);
960
+ if (!tenantDbs) {
961
+ throw new Error(`No databases registered for tenant '${tenantId}'`);
962
+ }
963
+ const dbKey = key || this.defaultDatabaseKeys.get(tenantId);
815
964
  if (!dbKey) {
816
- throw new Error("No database registered");
965
+ throw new Error(`No default database set for tenant '${tenantId}'`);
817
966
  }
818
- const database = this.databases.get(dbKey);
967
+ const database = tenantDbs.get(dbKey);
819
968
  if (!database) {
820
- throw new Error(`Database '${dbKey}' not found`);
969
+ throw new Error(`Database '${dbKey}' not found for tenant '${tenantId}'`);
821
970
  }
822
971
  return database;
823
972
  }
824
973
  /**
825
- * Check if a database is registered
974
+ * Check if a database is registered for a tenant
975
+ * @param tenantId - Tenant identifier
826
976
  * @param key - Database key
977
+ * @returns true if database exists for the tenant
827
978
  */
828
- hasDatabase(key) {
829
- return this.databases.has(key);
979
+ hasDatabase(tenantId, key) {
980
+ const tenantDbs = this.databases.get(tenantId);
981
+ return tenantDbs ? tenantDbs.has(key) : false;
830
982
  }
831
983
  /**
832
- * Get all registered database keys
984
+ * Get all registered database keys for a tenant
985
+ * @param tenantId - Tenant identifier
986
+ * @returns Array of database keys for the tenant
833
987
  */
834
- getDatabaseKeys() {
835
- return Array.from(this.databases.keys());
988
+ getDatabaseKeys(tenantId) {
989
+ const tenantDbs = this.databases.get(tenantId);
990
+ return tenantDbs ? Array.from(tenantDbs.keys()) : [];
836
991
  }
837
992
  /**
838
- * Remove a database connection
993
+ * Remove a database connection for a tenant
994
+ * @param tenantId - Tenant identifier
839
995
  * @param key - Database key
840
996
  */
841
- async removeDatabase(key) {
842
- const database = this.databases.get(key);
997
+ async removeDatabase(tenantId, key) {
998
+ const tenantDbs = this.databases.get(tenantId);
999
+ if (!tenantDbs) return;
1000
+ const database = tenantDbs.get(key);
843
1001
  if (database) {
844
1002
  await database.disconnect();
845
- this.databases.delete(key);
846
- if (this.defaultDatabaseKey === key) {
847
- this.defaultDatabaseKey = this.databases.size > 0 ? this.databases.keys().next().value || null : null;
1003
+ tenantDbs.delete(key);
1004
+ if (this.defaultDatabaseKeys.get(tenantId) === key) {
1005
+ const remainingKeys = Array.from(tenantDbs.keys());
1006
+ if (remainingKeys.length > 0) {
1007
+ this.defaultDatabaseKeys.set(tenantId, remainingKeys[0]);
1008
+ } else {
1009
+ this.defaultDatabaseKeys.delete(tenantId);
1010
+ this.databases.delete(tenantId);
1011
+ }
848
1012
  }
849
1013
  }
850
1014
  }
851
1015
  /**
852
- * Disconnect all databases
1016
+ * Disconnect all databases for a tenant
1017
+ * @param tenantId - Tenant identifier (optional, disconnects all if not provided)
853
1018
  */
854
- async disconnectAll() {
855
- for (const database of this.databases.values()) {
856
- await database.disconnect();
1019
+ async disconnectAll(tenantId) {
1020
+ if (tenantId) {
1021
+ const tenantDbs = this.databases.get(tenantId);
1022
+ if (tenantDbs) {
1023
+ for (const database of tenantDbs.values()) {
1024
+ await database.disconnect();
1025
+ }
1026
+ this.databases.delete(tenantId);
1027
+ this.defaultDatabaseKeys.delete(tenantId);
1028
+ }
1029
+ } else {
1030
+ for (const [tid, tenantDbs] of this.databases) {
1031
+ for (const database of tenantDbs.values()) {
1032
+ await database.disconnect();
1033
+ }
1034
+ }
1035
+ this.databases.clear();
1036
+ this.defaultDatabaseKeys.clear();
857
1037
  }
858
1038
  }
859
1039
  /**
860
1040
  * Load database configurations from a DatabaseConfigStore
861
- * and register them with this manager
1041
+ * and register them with this manager for a specific tenant
862
1042
  *
863
1043
  * @param store - The database configuration store
864
1044
  * @param tenantId - Tenant identifier
@@ -866,7 +1046,7 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
866
1046
  async loadConfigsFromStore(store, tenantId) {
867
1047
  const configs = await store.getAllConfigs(tenantId);
868
1048
  for (const entry of configs) {
869
- this.registerDatabase(entry.key, entry.config);
1049
+ this.registerDatabase(tenantId, entry.key, entry.config);
870
1050
  }
871
1051
  }
872
1052
  /**
@@ -878,7 +1058,21 @@ var SqlDatabaseManager = class _SqlDatabaseManager {
878
1058
  async loadAllConfigsFromStore(store) {
879
1059
  const configs = await store.getAllConfigsWithoutTenant();
880
1060
  for (const entry of configs) {
881
- this.registerDatabase(entry.key, entry.config);
1061
+ const tenantId = entry.tenantId || "default";
1062
+ this.registerDatabase(tenantId, entry.key, entry.config);
1063
+ }
1064
+ }
1065
+ /**
1066
+ * Clear all databases for a tenant (useful for testing)
1067
+ * @param tenantId - Tenant identifier (optional, clears all if not provided)
1068
+ */
1069
+ clear(tenantId) {
1070
+ if (tenantId) {
1071
+ this.databases.delete(tenantId);
1072
+ this.defaultDatabaseKeys.delete(tenantId);
1073
+ } else {
1074
+ this.databases.clear();
1075
+ this.defaultDatabaseKeys.clear();
882
1076
  }
883
1077
  }
884
1078
  };
@@ -887,8 +1081,16 @@ var sqlDatabaseManager = SqlDatabaseManager.getInstance();
887
1081
  // src/tool_lattice/sql/list_tables_sql.ts
888
1082
  import z3 from "zod";
889
1083
  import { tool as tool2 } from "langchain";
1084
+
1085
+ // src/tool_lattice/sql/utils.ts
1086
+ function getTenantIdFromConfig(exeConfig, getTenantId) {
1087
+ const runConfig = exeConfig?.configurable?.runConfig || {};
1088
+ return runConfig.tenantId || (getTenantId ? getTenantId() : "default");
1089
+ }
1090
+
1091
+ // src/tool_lattice/sql/list_tables_sql.ts
890
1092
  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.`;
891
- var createListTablesSqlTool = ({ databaseKeys, databaseDescriptions }) => {
1093
+ var createListTablesSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
892
1094
  const availableDbsText = databaseKeys.length > 0 ? `
893
1095
 
894
1096
  Available databases:
@@ -896,15 +1098,16 @@ ${databaseKeys.map(
896
1098
  (key) => `- ${key}${databaseDescriptions?.[key] ? `: ${databaseDescriptions[key]}` : ""}`
897
1099
  ).join("\n")}` : "";
898
1100
  return tool2(
899
- async ({ databaseKey }, exe_config) => {
1101
+ async ({ databaseKey }, _exeConfig) => {
900
1102
  try {
1103
+ const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId);
901
1104
  if (!databaseKey) {
902
1105
  return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
903
1106
  }
904
1107
  if (!databaseKeys.includes(databaseKey)) {
905
1108
  return `Error: databaseKey "${databaseKey}" is not in the allowed list: [${databaseKeys.join(", ")}]`;
906
1109
  }
907
- const database = sqlDatabaseManager.getDatabase(databaseKey);
1110
+ const database = sqlDatabaseManager.getDatabase(databaseKey, tenantId);
908
1111
  const tables = await database.listTables();
909
1112
  if (tables.length === 0) {
910
1113
  return "No tables found in the database.";
@@ -931,7 +1134,7 @@ ${databaseKeys.map(
931
1134
  import z4 from "zod";
932
1135
  import { tool as tool3 } from "langchain";
933
1136
  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.`;
934
- var createInfoSqlTool = ({ databaseKeys, databaseDescriptions }) => {
1137
+ var createInfoSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
935
1138
  const availableDbsText = databaseKeys.length > 0 ? `
936
1139
 
937
1140
  Available databases:
@@ -942,15 +1145,16 @@ ${databaseKeys.map(
942
1145
  async ({
943
1146
  tables,
944
1147
  databaseKey
945
- }, exe_config) => {
1148
+ }, _exeConfig) => {
946
1149
  try {
1150
+ const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId);
947
1151
  if (!databaseKey) {
948
1152
  return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
949
1153
  }
950
1154
  if (!databaseKeys.includes(databaseKey)) {
951
1155
  return `Error: databaseKey "${databaseKey}" is not in the allowed list: [${databaseKeys.join(", ")}]`;
952
1156
  }
953
- const database = sqlDatabaseManager.getDatabase(databaseKey);
1157
+ const database = sqlDatabaseManager.getDatabase(databaseKey, tenantId);
954
1158
  const tableNames = tables.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
955
1159
  if (tableNames.length === 0) {
956
1160
  return "Error: No table names provided. Please provide a comma-separated list of table names.";
@@ -1062,7 +1266,7 @@ function checkDangerousOperations(query) {
1062
1266
  }
1063
1267
  return warnings;
1064
1268
  }
1065
- var createQueryCheckerSqlTool = ({ databaseKeys, databaseDescriptions }) => {
1269
+ var createQueryCheckerSqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
1066
1270
  const availableDbsText = databaseKeys.length > 0 ? `
1067
1271
 
1068
1272
  Available databases:
@@ -1073,8 +1277,9 @@ ${databaseKeys.map(
1073
1277
  async ({
1074
1278
  query,
1075
1279
  databaseKey
1076
- }, exe_config) => {
1280
+ }, _exeConfig) => {
1077
1281
  try {
1282
+ const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId);
1078
1283
  const trimmedQuery = query.trim();
1079
1284
  if (!trimmedQuery) {
1080
1285
  return "Error: Empty query provided. Please provide a SQL query to check.";
@@ -1106,7 +1311,7 @@ ${trimmedQuery}
1106
1311
  }
1107
1312
  if (databaseKey && databaseKeys.includes(databaseKey)) {
1108
1313
  try {
1109
- const database = sqlDatabaseManager.getDatabase(databaseKey);
1314
+ const database = sqlDatabaseManager.getDatabase(databaseKey, tenantId);
1110
1315
  const dbType = database.getDatabaseType();
1111
1316
  if (dbType === "postgres") {
1112
1317
  try {
@@ -1183,7 +1388,7 @@ function formatQueryResult(rows, fields) {
1183
1388
  Total rows: ${rows.length}`);
1184
1389
  return lines.join("\n");
1185
1390
  }
1186
- var createQuerySqlTool = ({ databaseKeys, databaseDescriptions }) => {
1391
+ var createQuerySqlTool = ({ databaseKeys, databaseDescriptions, getTenantId }) => {
1187
1392
  const availableDbsText = databaseKeys.length > 0 ? `
1188
1393
 
1189
1394
  Available databases:
@@ -1194,8 +1399,9 @@ ${databaseKeys.map(
1194
1399
  async ({
1195
1400
  query,
1196
1401
  databaseKey
1197
- }, exe_config) => {
1402
+ }, _exeConfig) => {
1198
1403
  try {
1404
+ const tenantId = getTenantIdFromConfig(_exeConfig, getTenantId);
1199
1405
  if (!databaseKey) {
1200
1406
  return "Error: databaseKey parameter is required. Available databases: " + databaseKeys.join(", ");
1201
1407
  }
@@ -1206,7 +1412,7 @@ ${databaseKeys.map(
1206
1412
  if (!trimmedQuery) {
1207
1413
  return "Error: Empty query provided. Please provide a valid SQL query.";
1208
1414
  }
1209
- const database = sqlDatabaseManager.getDatabase(databaseKey);
1415
+ const database = sqlDatabaseManager.getDatabase(databaseKey, tenantId);
1210
1416
  const result = await database.executeQuery(trimmedQuery);
1211
1417
  return formatQueryResult(result.rows, result.fields);
1212
1418
  } catch (error) {
@@ -1738,7 +1944,7 @@ var MetricsServerManager = class _MetricsServerManager {
1738
1944
  constructor() {
1739
1945
  this.clients = /* @__PURE__ */ new Map();
1740
1946
  this.configs = /* @__PURE__ */ new Map();
1741
- this.defaultServerKey = null;
1947
+ this.defaultServerKeys = /* @__PURE__ */ new Map();
1742
1948
  }
1743
1949
  /**
1744
1950
  * Get the singleton instance
@@ -1750,11 +1956,34 @@ var MetricsServerManager = class _MetricsServerManager {
1750
1956
  return _MetricsServerManager.instance;
1751
1957
  }
1752
1958
  /**
1753
- * Register a metrics server
1959
+ * Get or create tenant clients map
1960
+ */
1961
+ getTenantClients(tenantId) {
1962
+ let tenantClients = this.clients.get(tenantId);
1963
+ if (!tenantClients) {
1964
+ tenantClients = /* @__PURE__ */ new Map();
1965
+ this.clients.set(tenantId, tenantClients);
1966
+ }
1967
+ return tenantClients;
1968
+ }
1969
+ /**
1970
+ * Get or create tenant configs map
1971
+ */
1972
+ getTenantConfigs(tenantId) {
1973
+ let tenantConfigs = this.configs.get(tenantId);
1974
+ if (!tenantConfigs) {
1975
+ tenantConfigs = /* @__PURE__ */ new Map();
1976
+ this.configs.set(tenantId, tenantConfigs);
1977
+ }
1978
+ return tenantConfigs;
1979
+ }
1980
+ /**
1981
+ * Register a metrics server for a tenant
1982
+ * @param tenantId - Tenant identifier
1754
1983
  * @param key - Unique identifier for the server
1755
1984
  * @param config - Metrics server configuration
1756
1985
  */
1757
- registerServer(key, config) {
1986
+ registerServer(tenantId, key, config) {
1758
1987
  let client;
1759
1988
  switch (config.type) {
1760
1989
  case "prometheus":
@@ -1769,82 +1998,136 @@ var MetricsServerManager = class _MetricsServerManager {
1769
1998
  default:
1770
1999
  throw new Error(`Unsupported metrics server type: ${config.type}`);
1771
2000
  }
1772
- this.clients.set(key, client);
1773
- this.configs.set(key, config);
1774
- if (this.defaultServerKey === null) {
1775
- this.defaultServerKey = key;
2001
+ const tenantClients = this.getTenantClients(tenantId);
2002
+ const tenantConfigs = this.getTenantConfigs(tenantId);
2003
+ tenantClients.set(key, client);
2004
+ tenantConfigs.set(key, config);
2005
+ if (!this.defaultServerKeys.has(tenantId)) {
2006
+ this.defaultServerKeys.set(tenantId, key);
1776
2007
  }
1777
2008
  }
1778
2009
  /**
1779
- * Set the default metrics server
2010
+ * Set the default metrics server for a tenant
2011
+ * @param tenantId - Tenant identifier
1780
2012
  * @param key - Server key to set as default
1781
2013
  */
1782
- setDefaultServer(key) {
1783
- if (!this.clients.has(key)) {
1784
- throw new Error(`Metrics server '${key}' not found`);
2014
+ setDefaultServer(tenantId, key) {
2015
+ const tenantClients = this.clients.get(tenantId);
2016
+ if (!tenantClients || !tenantClients.has(key)) {
2017
+ throw new Error(`Metrics server '${key}' not found for tenant '${tenantId}'`);
1785
2018
  }
1786
- this.defaultServerKey = key;
2019
+ this.defaultServerKeys.set(tenantId, key);
1787
2020
  }
1788
2021
  /**
1789
- * Get a metrics server client by key
2022
+ * Get a metrics server client by key for a specific tenant
2023
+ * @param tenantId - Tenant identifier
1790
2024
  * @param key - Server key (optional, uses default if not provided)
1791
2025
  */
1792
- getClient(key) {
1793
- const serverKey = key || this.defaultServerKey;
2026
+ getClient(tenantId, key) {
2027
+ const tenantClients = this.clients.get(tenantId);
2028
+ if (!tenantClients) {
2029
+ throw new Error(`No metrics servers registered for tenant '${tenantId}'`);
2030
+ }
2031
+ const serverKey = key || this.defaultServerKeys.get(tenantId);
1794
2032
  if (!serverKey) {
1795
- throw new Error("No metrics server registered");
2033
+ throw new Error(`No default metrics server set for tenant '${tenantId}'`);
1796
2034
  }
1797
- const client = this.clients.get(serverKey);
2035
+ const client = tenantClients.get(serverKey);
1798
2036
  if (!client) {
1799
- throw new Error(`Metrics server '${serverKey}' not found`);
2037
+ throw new Error(`Metrics server '${serverKey}' not found for tenant '${tenantId}'`);
1800
2038
  }
1801
2039
  return client;
1802
2040
  }
1803
2041
  /**
1804
- * Get metrics server configuration by key
2042
+ * Get metrics server configuration by key for a specific tenant
2043
+ * @param tenantId - Tenant identifier
1805
2044
  * @param key - Server key (optional, uses default if not provided)
1806
2045
  */
1807
- getConfig(key) {
1808
- const serverKey = key || this.defaultServerKey;
2046
+ getConfig(tenantId, key) {
2047
+ const tenantConfigs = this.configs.get(tenantId);
2048
+ if (!tenantConfigs) {
2049
+ throw new Error(`No metrics servers registered for tenant '${tenantId}'`);
2050
+ }
2051
+ const serverKey = key || this.defaultServerKeys.get(tenantId);
1809
2052
  if (!serverKey) {
1810
- throw new Error("No metrics server registered");
2053
+ throw new Error(`No default metrics server set for tenant '${tenantId}'`);
1811
2054
  }
1812
- const config = this.configs.get(serverKey);
2055
+ const config = tenantConfigs.get(serverKey);
1813
2056
  if (!config) {
1814
- throw new Error(`Metrics server '${serverKey}' not found`);
2057
+ throw new Error(`Metrics server '${serverKey}' not found for tenant '${tenantId}'`);
1815
2058
  }
1816
2059
  return config;
1817
2060
  }
1818
2061
  /**
1819
- * Check if a metrics server is registered
2062
+ * Check if a metrics server is registered for a tenant
2063
+ * @param tenantId - Tenant identifier
1820
2064
  * @param key - Server key
1821
2065
  */
1822
- hasServer(key) {
1823
- return this.clients.has(key);
2066
+ hasServer(tenantId, key) {
2067
+ const tenantClients = this.clients.get(tenantId);
2068
+ return tenantClients ? tenantClients.has(key) : false;
1824
2069
  }
1825
2070
  /**
1826
- * Get all registered metrics server keys with their types
2071
+ * Get all registered metrics server keys with their types for a tenant
2072
+ * @param tenantId - Tenant identifier
1827
2073
  */
1828
- getServerKeys() {
1829
- return Array.from(this.configs.entries()).map(([key, config]) => ({
2074
+ getServerKeys(tenantId) {
2075
+ const tenantConfigs = this.configs.get(tenantId);
2076
+ if (!tenantConfigs) {
2077
+ return [];
2078
+ }
2079
+ return Array.from(tenantConfigs.entries()).map(([key, config]) => ({
1830
2080
  key,
1831
2081
  type: config.type
1832
2082
  }));
1833
2083
  }
1834
2084
  /**
1835
- * Remove a metrics server
2085
+ * Remove a metrics server for a tenant
2086
+ * @param tenantId - Tenant identifier
1836
2087
  * @param key - Server key
1837
2088
  */
1838
- removeServer(key) {
1839
- this.clients.delete(key);
1840
- this.configs.delete(key);
1841
- if (this.defaultServerKey === key) {
1842
- this.defaultServerKey = this.clients.size > 0 ? this.clients.keys().next().value || null : null;
2089
+ removeServer(tenantId, key) {
2090
+ const tenantClients = this.clients.get(tenantId);
2091
+ const tenantConfigs = this.configs.get(tenantId);
2092
+ if (tenantClients) {
2093
+ tenantClients.delete(key);
2094
+ if (tenantClients.size === 0) {
2095
+ this.clients.delete(tenantId);
2096
+ }
2097
+ }
2098
+ if (tenantConfigs) {
2099
+ tenantConfigs.delete(key);
2100
+ if (tenantConfigs.size === 0) {
2101
+ this.configs.delete(tenantId);
2102
+ }
2103
+ }
2104
+ if (this.defaultServerKeys.get(tenantId) === key) {
2105
+ const remainingKeys = tenantClients ? Array.from(tenantClients.keys()) : [];
2106
+ if (remainingKeys.length > 0) {
2107
+ this.defaultServerKeys.set(tenantId, remainingKeys[0]);
2108
+ } else {
2109
+ this.defaultServerKeys.delete(tenantId);
2110
+ }
2111
+ }
2112
+ }
2113
+ /**
2114
+ * Clear all metrics servers for a tenant
2115
+ * @param tenantId - Tenant identifier (optional, clears all if not provided)
2116
+ */
2117
+ clear(tenantId) {
2118
+ if (tenantId) {
2119
+ this.clients.delete(tenantId);
2120
+ this.configs.delete(tenantId);
2121
+ this.defaultServerKeys.delete(tenantId);
2122
+ } else {
2123
+ this.clients.clear();
2124
+ this.configs.clear();
2125
+ this.defaultServerKeys.clear();
1843
2126
  }
1844
2127
  }
1845
2128
  /**
1846
2129
  * Load metrics server configurations from a store
1847
- * and register them with this manager
2130
+ * and register them with this manager for a specific tenant
1848
2131
  *
1849
2132
  * @param store - The metrics server configuration store
1850
2133
  * @param tenantId - Tenant identifier
@@ -1852,7 +2135,7 @@ var MetricsServerManager = class _MetricsServerManager {
1852
2135
  async loadConfigsFromStore(store, tenantId) {
1853
2136
  const configs = await store.getAllConfigs(tenantId);
1854
2137
  for (const entry of configs) {
1855
- this.registerServer(entry.key, entry.config);
2138
+ this.registerServer(tenantId, entry.key, entry.config);
1856
2139
  }
1857
2140
  }
1858
2141
  /**
@@ -1860,11 +2143,13 @@ var MetricsServerManager = class _MetricsServerManager {
1860
2143
  * across all tenants and register them with this manager
1861
2144
  *
1862
2145
  * @param store - The metrics server configuration store
2146
+ * @deprecated Use loadConfigsFromStore with specific tenant instead
1863
2147
  */
1864
2148
  async loadAllConfigsFromStore(store) {
1865
2149
  const configs = await store.getAllConfigsWithoutTenant();
1866
2150
  for (const entry of configs) {
1867
- this.registerServer(entry.key, entry.config);
2151
+ const tenantId = entry.tenantId || "default";
2152
+ this.registerServer(tenantId, entry.key, entry.config);
1868
2153
  }
1869
2154
  }
1870
2155
  };
@@ -1873,8 +2158,21 @@ var metricsServerManager = MetricsServerManager.getInstance();
1873
2158
  // src/tool_lattice/metrics/list_metrics_servers.ts
1874
2159
  import z7 from "zod";
1875
2160
  import { tool as tool6 } from "langchain";
2161
+
2162
+ // src/tool_lattice/metrics/utils.ts
2163
+ function getTenantIdFromConfig2(exeConfig, getTenantId) {
2164
+ const runConfig = exeConfig?.configurable?.runConfig || {};
2165
+ return runConfig.tenantId || (getTenantId ? getTenantId() : "default");
2166
+ }
2167
+ function filterServerKeysByTenant(serverKeys, tenantId, manager = metricsServerManager) {
2168
+ return serverKeys.filter((key) => {
2169
+ return manager.hasServer(tenantId, key);
2170
+ });
2171
+ }
2172
+
2173
+ // src/tool_lattice/metrics/list_metrics_servers.ts
1876
2174
  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.`;
1877
- var createListMetricsServersTool = ({ serverKeys, serverDescriptions }) => {
2175
+ var createListMetricsServersTool = ({ serverKeys, serverDescriptions, getTenantId }) => {
1878
2176
  const availableServersText = serverKeys.length > 0 ? `
1879
2177
 
1880
2178
  Available metrics servers:
@@ -1884,7 +2182,8 @@ ${serverKeys.map(
1884
2182
  return tool6(
1885
2183
  async (_input, _exeConfig) => {
1886
2184
  try {
1887
- const servers = metricsServerManager.getServerKeys();
2185
+ const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
2186
+ const servers = metricsServerManager.getServerKeys(tenantId);
1888
2187
  if (servers.length === 0) {
1889
2188
  return "No metrics servers registered.";
1890
2189
  }
@@ -1910,7 +2209,7 @@ ${lines.join("\n")}`;
1910
2209
  import z8 from "zod";
1911
2210
  import { tool as tool7 } from "langchain";
1912
2211
  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.`;
1913
- var createListMetricsDataSourcesTool = ({ serverKeys, serverDescriptions }) => {
2212
+ var createListMetricsDataSourcesTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
1914
2213
  const availableServersText = serverKeys.length > 0 ? `
1915
2214
 
1916
2215
  Configured metrics servers:
@@ -1920,6 +2219,12 @@ ${serverKeys.map(
1920
2219
  return tool7(
1921
2220
  async (_input, _exeConfig) => {
1922
2221
  try {
2222
+ const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
2223
+ let effectiveServerKeys = serverKeys;
2224
+ if (connectAll) {
2225
+ effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
2226
+ }
2227
+ const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
1923
2228
  const runConfig = _exeConfig?.configurable?.runConfig || {};
1924
2229
  const metricsDataSource = runConfig.metricsDataSource;
1925
2230
  if (metricsDataSource) {
@@ -1934,18 +2239,18 @@ You can directly use other metrics tools (such as query_metrics_list, query_sema
1934
2239
 
1935
2240
  To view all available data sources, please clear the current selection or reopen the data source selector.`;
1936
2241
  }
1937
- if (serverKeys.length === 0) {
1938
- return "No metrics servers configured.";
2242
+ if (filteredServerKeys.length === 0) {
2243
+ return `No metrics servers available for tenant "${tenantId}".`;
1939
2244
  }
1940
2245
  const allDataSources = [];
1941
- for (const serverKey of serverKeys) {
2246
+ for (const serverKey of filteredServerKeys) {
1942
2247
  try {
1943
- const config = metricsServerManager.getConfig(serverKey);
2248
+ const config = metricsServerManager.getConfig(tenantId, serverKey);
1944
2249
  if (config.type !== "semantic") {
1945
2250
  console.warn(`Server "${serverKey}" is not a semantic metrics server, skipping.`);
1946
2251
  continue;
1947
2252
  }
1948
- const client = metricsServerManager.getClient(serverKey);
2253
+ const client = metricsServerManager.getClient(tenantId, serverKey);
1949
2254
  const dataSources = await client.getDataSources();
1950
2255
  const selectedIds = config.selectedDataSources || [];
1951
2256
  const filteredDataSources = selectedIds.length > 0 ? dataSources.filter((ds) => selectedIds.includes(String(ds.id))) : dataSources;
@@ -1961,10 +2266,10 @@ To view all available data sources, please clear the current selection or reopen
1961
2266
  }
1962
2267
  }
1963
2268
  if (allDataSources.length === 0) {
1964
- return `No datasources found in any configured metrics servers.`;
2269
+ return `No datasources found in any configured metrics servers for tenant "${tenantId}".`;
1965
2270
  }
1966
2271
  const lines = [];
1967
- lines.push(`Found ${allDataSources.length} datasource(s) from ${serverKeys.length} server(s):
2272
+ lines.push(`Found ${allDataSources.length} datasource(s) from ${filteredServerKeys.length} server(s):
1968
2273
  `);
1969
2274
  lines.push("| Server Key | DataSource ID | Name |");
1970
2275
  lines.push("|------------|---------------|------|");
@@ -2020,7 +2325,7 @@ Response Fields Reference
2020
2325
 
2021
2326
  Next Step
2022
2327
  After finding relevant metrics, call query_metric_definition with the metricName to get detailed metadata including time dimensions and supported filters.`;
2023
- var createQueryMetricsListTool = ({ serverKeys, serverDescriptions }) => {
2328
+ var createQueryMetricsListTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
2024
2329
  const availableServersText = serverKeys.length > 0 ? `
2025
2330
 
2026
2331
  Available metrics servers:
@@ -2033,20 +2338,26 @@ ${serverKeys.map(
2033
2338
  datasourceIds
2034
2339
  }, _exeConfig) => {
2035
2340
  try {
2341
+ const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
2342
+ let effectiveServerKeys = serverKeys;
2343
+ if (connectAll) {
2344
+ effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
2345
+ }
2346
+ const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
2036
2347
  const runConfig = _exeConfig?.configurable?.runConfig || {};
2037
2348
  const metricsDataSource = runConfig.metricsDataSource;
2038
2349
  const serverKey = metricsDataSource?.serverKey || inputServerKey;
2039
2350
  if (!serverKey) {
2040
- return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
2351
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2041
2352
  }
2042
- if (!serverKeys.includes(serverKey)) {
2043
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
2353
+ if (!filteredServerKeys.includes(serverKey)) {
2354
+ return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
2044
2355
  }
2045
- const config = metricsServerManager.getConfig(serverKey);
2356
+ const config = metricsServerManager.getConfig(tenantId, serverKey);
2046
2357
  if (config.type !== "semantic") {
2047
2358
  return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2048
2359
  }
2049
- const client = metricsServerManager.getClient(serverKey);
2360
+ const client = metricsServerManager.getClient(tenantId, serverKey);
2050
2361
  const targetDatasourceIds = datasourceIds && datasourceIds.length > 0 ? datasourceIds : metricsDataSource?.datasourceId ? [metricsDataSource.datasourceId] : client.getSelectedDataSources();
2051
2362
  if (targetDatasourceIds.length === 0) {
2052
2363
  return `Error: No data sources specified and no default data sources configured for server "${serverKey}".`;
@@ -2171,7 +2482,7 @@ Rules
2171
2482
 
2172
2483
  Next Step
2173
2484
  Call query_semantic_metric_data with parameters derived from this definition.`;
2174
- var createQueryMetricDefinitionTool = ({ serverKeys, serverDescriptions }) => {
2485
+ var createQueryMetricDefinitionTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
2175
2486
  const availableServersText = serverKeys.length > 0 ? `
2176
2487
 
2177
2488
  Available metrics servers:
@@ -2185,24 +2496,30 @@ ${serverKeys.map(
2185
2496
  datasourceId: inputDatasourceId
2186
2497
  }, _exeConfig) => {
2187
2498
  try {
2499
+ const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
2500
+ let effectiveServerKeys = serverKeys;
2501
+ if (connectAll) {
2502
+ effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
2503
+ }
2504
+ const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
2188
2505
  const runConfig = _exeConfig?.configurable?.runConfig || {};
2189
2506
  const metricsDataSource = runConfig.metricsDataSource;
2190
2507
  const serverKey = metricsDataSource?.serverKey || inputServerKey;
2191
2508
  const datasourceId = inputDatasourceId || metricsDataSource?.datasourceId;
2192
2509
  if (!serverKey) {
2193
- return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
2510
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2194
2511
  }
2195
- if (!serverKeys.includes(serverKey)) {
2196
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
2512
+ if (!filteredServerKeys.includes(serverKey)) {
2513
+ return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
2197
2514
  }
2198
2515
  if (!metricName) {
2199
2516
  return "Error: metricName parameter is required.";
2200
2517
  }
2201
- const config = metricsServerManager.getConfig(serverKey);
2518
+ const config = metricsServerManager.getConfig(tenantId, serverKey);
2202
2519
  if (config.type !== "semantic") {
2203
2520
  return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2204
2521
  }
2205
- const client = metricsServerManager.getClient(serverKey);
2522
+ const client = metricsServerManager.getClient(tenantId, serverKey);
2206
2523
  const targetDatasourceIds = datasourceId ? [datasourceId] : client.getSelectedDataSources();
2207
2524
  if (targetDatasourceIds.length === 0) {
2208
2525
  return `Error: No datasourceId specified and no default data sources configured for server "${serverKey}".`;
@@ -2591,7 +2908,7 @@ Data Source: ${datasourceId}${datasourceName ? ` (${datasourceName})` : ""}`;
2591
2908
  }
2592
2909
  return lines.join("\n");
2593
2910
  }
2594
- var createQuerySemanticMetricDataTool = ({ serverKeys, serverDescriptions }) => {
2911
+ var createQuerySemanticMetricDataTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
2595
2912
  const availableServersText = serverKeys.length > 0 ? `
2596
2913
 
2597
2914
  Available metrics servers:
@@ -2608,15 +2925,21 @@ ${serverKeys.map(
2608
2925
  limit
2609
2926
  }, _exeConfig) => {
2610
2927
  try {
2928
+ const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
2929
+ let effectiveServerKeys = serverKeys;
2930
+ if (connectAll) {
2931
+ effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
2932
+ }
2933
+ const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
2611
2934
  const runConfig = _exeConfig?.configurable?.runConfig || {};
2612
2935
  const metricsDataSource = runConfig.metricsDataSource;
2613
2936
  const serverKey = metricsDataSource?.serverKey || inputServerKey;
2614
2937
  const datasourceId = metricsDataSource?.datasourceId || inputDatasourceId;
2615
2938
  if (!serverKey) {
2616
- return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
2939
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2617
2940
  }
2618
- if (!serverKeys.includes(serverKey)) {
2619
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
2941
+ if (!filteredServerKeys.includes(serverKey)) {
2942
+ return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
2620
2943
  }
2621
2944
  if (!datasourceId) {
2622
2945
  return "Error: datasourceId parameter is required.";
@@ -2624,11 +2947,11 @@ ${serverKeys.map(
2624
2947
  if (!metrics || metrics.length === 0) {
2625
2948
  return "Error: metrics parameter is required (at least one metric name).";
2626
2949
  }
2627
- const config = metricsServerManager.getConfig(serverKey);
2950
+ const config = metricsServerManager.getConfig(tenantId, serverKey);
2628
2951
  if (config.type !== "semantic") {
2629
2952
  return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2630
2953
  }
2631
- const client = metricsServerManager.getClient(serverKey);
2954
+ const client = metricsServerManager.getClient(tenantId, serverKey);
2632
2955
  const semanticFilters = (filters || []).map((f) => ({
2633
2956
  dimension: f.dimension,
2634
2957
  operator: f.operator,
@@ -2674,7 +2997,7 @@ ${serverKeys.map(
2674
2997
  import z12 from "zod";
2675
2998
  import { tool as tool11 } from "langchain";
2676
2999
  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.`;
2677
- var createQueryTablesListTool = ({ serverKeys, serverDescriptions }) => {
3000
+ var createQueryTablesListTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
2678
3001
  const availableServersText = serverKeys.length > 0 ? `
2679
3002
 
2680
3003
  Available metrics servers:
@@ -2687,20 +3010,26 @@ ${serverKeys.map(
2687
3010
  datasourceIds
2688
3011
  }, _exeConfig) => {
2689
3012
  try {
3013
+ const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
3014
+ let effectiveServerKeys = serverKeys;
3015
+ if (connectAll) {
3016
+ effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
3017
+ }
3018
+ const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
2690
3019
  const runConfig = _exeConfig?.configurable?.runConfig || {};
2691
3020
  const metricsDataSource = runConfig.metricsDataSource;
2692
3021
  const serverKey = metricsDataSource?.serverKey || inputServerKey;
2693
3022
  if (!serverKey) {
2694
- return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
3023
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2695
3024
  }
2696
- if (!serverKeys.includes(serverKey)) {
2697
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
3025
+ if (!filteredServerKeys.includes(serverKey)) {
3026
+ return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
2698
3027
  }
2699
- const config = metricsServerManager.getConfig(serverKey);
3028
+ const config = metricsServerManager.getConfig(tenantId, serverKey);
2700
3029
  if (config.type !== "semantic") {
2701
3030
  return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2702
3031
  }
2703
- const client = metricsServerManager.getClient(serverKey);
3032
+ const client = metricsServerManager.getClient(tenantId, serverKey);
2704
3033
  const targetDatasourceIds = datasourceIds && datasourceIds.length > 0 ? datasourceIds : metricsDataSource?.datasourceId ? [metricsDataSource.datasourceId] : client.getSelectedDataSources();
2705
3034
  if (targetDatasourceIds.length === 0) {
2706
3035
  return `Error: No data sources specified and no default data sources configured for server "${serverKey}".`;
@@ -2772,7 +3101,7 @@ ${serverKeys.map(
2772
3101
  import z13 from "zod";
2773
3102
  import { tool as tool12 } from "langchain";
2774
3103
  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.`;
2775
- var createQueryTableDefinitionTool = ({ serverKeys, serverDescriptions }) => {
3104
+ var createQueryTableDefinitionTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
2776
3105
  const availableServersText = serverKeys.length > 0 ? `
2777
3106
 
2778
3107
  Available metrics servers:
@@ -2786,24 +3115,30 @@ ${serverKeys.map(
2786
3115
  datasourceId: inputDatasourceId
2787
3116
  }, _exeConfig) => {
2788
3117
  try {
3118
+ const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
3119
+ let effectiveServerKeys = serverKeys;
3120
+ if (connectAll) {
3121
+ effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
3122
+ }
3123
+ const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
2789
3124
  const runConfig = _exeConfig?.configurable?.runConfig || {};
2790
3125
  const metricsDataSource = runConfig.metricsDataSource;
2791
3126
  const serverKey = metricsDataSource?.serverKey || inputServerKey;
2792
3127
  const datasourceId = inputDatasourceId || metricsDataSource?.datasourceId;
2793
3128
  if (!serverKey) {
2794
- return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
3129
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2795
3130
  }
2796
- if (!serverKeys.includes(serverKey)) {
2797
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
3131
+ if (!filteredServerKeys.includes(serverKey)) {
3132
+ return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
2798
3133
  }
2799
3134
  if (!tableName) {
2800
3135
  return "Error: tableName parameter is required.";
2801
3136
  }
2802
- const config = metricsServerManager.getConfig(serverKey);
3137
+ const config = metricsServerManager.getConfig(tenantId, serverKey);
2803
3138
  if (config.type !== "semantic") {
2804
3139
  return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2805
3140
  }
2806
- const client = metricsServerManager.getClient(serverKey);
3141
+ const client = metricsServerManager.getClient(tenantId, serverKey);
2807
3142
  const targetDatasourceIds = datasourceId ? [datasourceId] : client.getSelectedDataSources();
2808
3143
  if (targetDatasourceIds.length === 0) {
2809
3144
  return `Error: No datasourceId specified and no default data sources configured for server "${serverKey}".`;
@@ -2904,7 +3239,7 @@ Example:
2904
3239
  },
2905
3240
  "limit": 100
2906
3241
  }`;
2907
- var createExecuteSqlQueryTool = ({ serverKeys, serverDescriptions }) => {
3242
+ var createExecuteSqlQueryTool = ({ serverKeys, serverDescriptions, getTenantId, connectAll }) => {
2908
3243
  const availableServersText = serverKeys.length > 0 ? `
2909
3244
 
2910
3245
  Available metrics servers:
@@ -2920,15 +3255,21 @@ ${serverKeys.map(
2920
3255
  limit
2921
3256
  }, _exeConfig) => {
2922
3257
  try {
3258
+ const tenantId = getTenantIdFromConfig2(_exeConfig, getTenantId);
3259
+ let effectiveServerKeys = serverKeys;
3260
+ if (connectAll) {
3261
+ effectiveServerKeys = metricsServerManager.getServerKeys(tenantId).map((s) => s.key);
3262
+ }
3263
+ const filteredServerKeys = filterServerKeysByTenant(effectiveServerKeys, tenantId);
2923
3264
  const runConfig = _exeConfig?.configurable?.runConfig || {};
2924
3265
  const metricsDataSource = runConfig.metricsDataSource;
2925
3266
  const serverKey = metricsDataSource?.serverKey || inputServerKey;
2926
3267
  const datasourceId = metricsDataSource?.datasourceId || inputDatasourceId;
2927
3268
  if (!serverKey) {
2928
- return "Error: serverKey parameter is required. Available servers: " + serverKeys.join(", ");
3269
+ return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
2929
3270
  }
2930
- if (!serverKeys.includes(serverKey)) {
2931
- return `Error: serverKey "${serverKey}" is not in the allowed list: [${serverKeys.join(", ")}]`;
3271
+ if (!filteredServerKeys.includes(serverKey)) {
3272
+ return `Error: serverKey "${serverKey}" is not available for tenant "${tenantId}". Available servers: [${filteredServerKeys.join(", ")}]`;
2932
3273
  }
2933
3274
  if (!datasourceId) {
2934
3275
  return "Error: datasourceId parameter is required.";
@@ -2936,11 +3277,11 @@ ${serverKeys.map(
2936
3277
  if (!customSql || customSql.trim().length === 0) {
2937
3278
  return "Error: customSql parameter is required and cannot be empty.";
2938
3279
  }
2939
- const config = metricsServerManager.getConfig(serverKey);
3280
+ const config = metricsServerManager.getConfig(tenantId, serverKey);
2940
3281
  if (config.type !== "semantic") {
2941
3282
  return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
2942
3283
  }
2943
- const client = metricsServerManager.getClient(serverKey);
3284
+ const client = metricsServerManager.getClient(tenantId, serverKey);
2944
3285
  const result = await client.executeSqlQuery({
2945
3286
  datasourceId,
2946
3287
  customSql,
@@ -4702,104 +5043,137 @@ import { createMiddleware as createMiddleware4 } from "langchain";
4702
5043
  // src/store_lattice/InMemoryThreadStore.ts
4703
5044
  var InMemoryThreadStore = class {
4704
5045
  constructor() {
4705
- // Map<assistantId, Map<threadId, Thread>>
5046
+ // Map<tenantId, Map<assistantId, Map<threadId, Thread>>>
4706
5047
  this.threads = /* @__PURE__ */ new Map();
4707
5048
  }
4708
5049
  /**
4709
- * Get all threads for a specific assistant
5050
+ * Get all threads for a specific tenant and assistant
4710
5051
  */
4711
- async getThreadsByAssistantId(assistantId) {
4712
- const assistantThreads = this.threads.get(assistantId);
5052
+ async getThreadsByAssistantId(tenantId, assistantId) {
5053
+ const tenantThreads = this.threads.get(tenantId);
5054
+ if (!tenantThreads) {
5055
+ return [];
5056
+ }
5057
+ const assistantThreads = tenantThreads.get(assistantId);
4713
5058
  if (!assistantThreads) {
4714
5059
  return [];
4715
5060
  }
4716
5061
  return Array.from(assistantThreads.values());
4717
5062
  }
4718
5063
  /**
4719
- * Get a thread by ID for a specific assistant
5064
+ * Get a thread by ID for a specific tenant
4720
5065
  */
4721
- async getThreadById(assistantId, threadId) {
4722
- const assistantThreads = this.threads.get(assistantId);
4723
- if (!assistantThreads) {
5066
+ async getThreadById(tenantId, threadId) {
5067
+ const tenantThreads = this.threads.get(tenantId);
5068
+ if (!tenantThreads) {
4724
5069
  return void 0;
4725
5070
  }
4726
- return assistantThreads.get(threadId);
5071
+ for (const assistantThreads of tenantThreads.values()) {
5072
+ const thread = assistantThreads.get(threadId);
5073
+ if (thread) {
5074
+ return thread;
5075
+ }
5076
+ }
5077
+ return void 0;
4727
5078
  }
4728
5079
  /**
4729
- * Create a new thread for an assistant
5080
+ * Create a new thread for a tenant and assistant
4730
5081
  */
4731
- async createThread(assistantId, threadId, data) {
5082
+ async createThread(tenantId, assistantId, threadId, data) {
4732
5083
  const now = /* @__PURE__ */ new Date();
4733
5084
  const thread = {
4734
5085
  id: threadId,
5086
+ tenantId,
4735
5087
  assistantId,
4736
5088
  metadata: data.metadata || {},
4737
5089
  createdAt: now,
4738
5090
  updatedAt: now
4739
5091
  };
4740
- if (!this.threads.has(assistantId)) {
4741
- this.threads.set(assistantId, /* @__PURE__ */ new Map());
5092
+ if (!this.threads.has(tenantId)) {
5093
+ this.threads.set(tenantId, /* @__PURE__ */ new Map());
5094
+ }
5095
+ const tenantThreads = this.threads.get(tenantId);
5096
+ if (!tenantThreads.has(assistantId)) {
5097
+ tenantThreads.set(assistantId, /* @__PURE__ */ new Map());
4742
5098
  }
4743
- const assistantThreads = this.threads.get(assistantId);
5099
+ const assistantThreads = tenantThreads.get(assistantId);
4744
5100
  assistantThreads.set(threadId, thread);
4745
5101
  return thread;
4746
5102
  }
4747
5103
  /**
4748
5104
  * Update an existing thread
4749
5105
  */
4750
- async updateThread(assistantId, threadId, updates) {
4751
- const assistantThreads = this.threads.get(assistantId);
4752
- if (!assistantThreads) {
5106
+ async updateThread(tenantId, threadId, updates) {
5107
+ const tenantThreads = this.threads.get(tenantId);
5108
+ if (!tenantThreads) {
4753
5109
  return null;
4754
5110
  }
4755
- const existing = assistantThreads.get(threadId);
4756
- if (!existing) {
4757
- return null;
5111
+ for (const assistantThreads of tenantThreads.values()) {
5112
+ const existing = assistantThreads.get(threadId);
5113
+ if (existing) {
5114
+ const updated = {
5115
+ ...existing,
5116
+ metadata: {
5117
+ ...existing.metadata,
5118
+ ...updates.metadata || {}
5119
+ },
5120
+ updatedAt: /* @__PURE__ */ new Date()
5121
+ };
5122
+ assistantThreads.set(threadId, updated);
5123
+ return updated;
5124
+ }
4758
5125
  }
4759
- const updated = {
4760
- ...existing,
4761
- metadata: {
4762
- ...existing.metadata,
4763
- ...updates.metadata || {}
4764
- },
4765
- updatedAt: /* @__PURE__ */ new Date()
4766
- };
4767
- assistantThreads.set(threadId, updated);
4768
- return updated;
5126
+ return null;
4769
5127
  }
4770
5128
  /**
4771
5129
  * Delete a thread by ID
4772
5130
  */
4773
- async deleteThread(assistantId, threadId) {
4774
- const assistantThreads = this.threads.get(assistantId);
4775
- if (!assistantThreads) {
5131
+ async deleteThread(tenantId, threadId) {
5132
+ const tenantThreads = this.threads.get(tenantId);
5133
+ if (!tenantThreads) {
4776
5134
  return false;
4777
5135
  }
4778
- return assistantThreads.delete(threadId);
5136
+ for (const assistantThreads of tenantThreads.values()) {
5137
+ if (assistantThreads.has(threadId)) {
5138
+ return assistantThreads.delete(threadId);
5139
+ }
5140
+ }
5141
+ return false;
4779
5142
  }
4780
5143
  /**
4781
5144
  * Check if thread exists
4782
5145
  */
4783
- async hasThread(assistantId, threadId) {
4784
- const assistantThreads = this.threads.get(assistantId);
4785
- if (!assistantThreads) {
5146
+ async hasThread(tenantId, threadId) {
5147
+ const tenantThreads = this.threads.get(tenantId);
5148
+ if (!tenantThreads) {
4786
5149
  return false;
4787
5150
  }
4788
- return assistantThreads.has(threadId);
5151
+ for (const assistantThreads of tenantThreads.values()) {
5152
+ if (assistantThreads.has(threadId)) {
5153
+ return true;
5154
+ }
5155
+ }
5156
+ return false;
4789
5157
  }
4790
5158
  /**
4791
- * Clear all threads (useful for testing)
5159
+ * Clear all threads for a tenant (useful for testing)
4792
5160
  */
4793
- clear() {
4794
- this.threads.clear();
5161
+ clear(tenantId) {
5162
+ if (tenantId) {
5163
+ this.threads.delete(tenantId);
5164
+ } else {
5165
+ this.threads.clear();
5166
+ }
4795
5167
  }
4796
5168
  /**
4797
5169
  * Get all threads for all assistants (useful for debugging)
4798
5170
  */
4799
5171
  getAllThreads() {
4800
5172
  const allThreads = [];
4801
- for (const assistantThreads of this.threads.values()) {
4802
- allThreads.push(...Array.from(assistantThreads.values()));
5173
+ for (const tenantThreads of this.threads.values()) {
5174
+ for (const assistantThreads of tenantThreads.values()) {
5175
+ allThreads.push(...Array.from(assistantThreads.values()));
5176
+ }
4803
5177
  }
4804
5178
  return allThreads;
4805
5179
  }
@@ -4811,38 +5185,50 @@ var InMemoryAssistantStore = class {
4811
5185
  this.assistants = /* @__PURE__ */ new Map();
4812
5186
  }
4813
5187
  /**
4814
- * Get all assistants
5188
+ * Get all assistants for a tenant
4815
5189
  */
4816
- async getAllAssistants() {
4817
- return Array.from(this.assistants.values());
5190
+ async getAllAssistants(tenantId) {
5191
+ const tenantAssistants = this.assistants.get(tenantId);
5192
+ if (!tenantAssistants) return [];
5193
+ return Array.from(tenantAssistants.values());
4818
5194
  }
4819
5195
  /**
4820
5196
  * Get assistant by ID
4821
5197
  */
4822
- async getAssistantById(id) {
4823
- return this.assistants.get(id) || null;
5198
+ async getAssistantById(tenantId, id) {
5199
+ const tenantAssistants = this.assistants.get(tenantId);
5200
+ if (!tenantAssistants) return null;
5201
+ return tenantAssistants.get(id) || null;
4824
5202
  }
4825
5203
  /**
4826
5204
  * Create a new assistant
4827
5205
  */
4828
- async createAssistant(id, data) {
5206
+ async createAssistant(tenantId, id, data) {
5207
+ if (!this.assistants.has(tenantId)) {
5208
+ this.assistants.set(tenantId, /* @__PURE__ */ new Map());
5209
+ }
4829
5210
  const now = /* @__PURE__ */ new Date();
4830
5211
  const assistant = {
4831
5212
  id,
5213
+ tenantId,
4832
5214
  name: data.name,
4833
5215
  description: data.description,
4834
5216
  graphDefinition: data.graphDefinition,
4835
5217
  createdAt: now,
4836
5218
  updatedAt: now
4837
5219
  };
4838
- this.assistants.set(id, assistant);
5220
+ this.assistants.get(tenantId).set(id, assistant);
4839
5221
  return assistant;
4840
5222
  }
4841
5223
  /**
4842
5224
  * Update an existing assistant
4843
5225
  */
4844
- async updateAssistant(id, updates) {
4845
- const existing = this.assistants.get(id);
5226
+ async updateAssistant(tenantId, id, updates) {
5227
+ const tenantAssistants = this.assistants.get(tenantId);
5228
+ if (!tenantAssistants) {
5229
+ return null;
5230
+ }
5231
+ const existing = tenantAssistants.get(id);
4846
5232
  if (!existing) {
4847
5233
  return null;
4848
5234
  }
@@ -4851,26 +5237,38 @@ var InMemoryAssistantStore = class {
4851
5237
  ...updates,
4852
5238
  updatedAt: /* @__PURE__ */ new Date()
4853
5239
  };
4854
- this.assistants.set(id, updated);
5240
+ tenantAssistants.set(id, updated);
4855
5241
  return updated;
4856
5242
  }
4857
5243
  /**
4858
5244
  * Delete an assistant by ID
4859
5245
  */
4860
- async deleteAssistant(id) {
4861
- return this.assistants.delete(id);
5246
+ async deleteAssistant(tenantId, id) {
5247
+ const tenantAssistants = this.assistants.get(tenantId);
5248
+ if (!tenantAssistants) {
5249
+ return false;
5250
+ }
5251
+ return tenantAssistants.delete(id);
4862
5252
  }
4863
5253
  /**
4864
5254
  * Check if assistant exists
4865
5255
  */
4866
- async hasAssistant(id) {
4867
- return this.assistants.has(id);
5256
+ async hasAssistant(tenantId, id) {
5257
+ const tenantAssistants = this.assistants.get(tenantId);
5258
+ if (!tenantAssistants) {
5259
+ return false;
5260
+ }
5261
+ return tenantAssistants.has(id);
4868
5262
  }
4869
5263
  /**
4870
- * Clear all assistants (useful for testing)
5264
+ * Clear all assistants for a tenant (useful for testing)
4871
5265
  */
4872
- clear() {
4873
- this.assistants.clear();
5266
+ clear(tenantId) {
5267
+ if (tenantId) {
5268
+ this.assistants.delete(tenantId);
5269
+ } else {
5270
+ this.assistants.clear();
5271
+ }
4874
5272
  }
4875
5273
  };
4876
5274
 
@@ -5116,6 +5514,8 @@ var FileSystemSkillStore = class {
5116
5514
  return {
5117
5515
  id: name,
5118
5516
  // id equals name (name is used for path addressing)
5517
+ tenantId: "default",
5518
+ // FileSystemSkillStore uses default tenant
5119
5519
  name: frontmatter.name,
5120
5520
  description: frontmatter.description,
5121
5521
  license: frontmatter.license,
@@ -5163,9 +5563,11 @@ ${body}` : `${frontmatter}
5163
5563
  await fs.writeFile(filePath, content, "utf-8");
5164
5564
  }
5165
5565
  /**
5166
- * Get all skills
5566
+ * Get all skills for a tenant
5567
+ * Note: FileSystemSkillStore uses a flat structure. TenantId is accepted for protocol compliance
5568
+ * but all skills are returned regardless of tenant.
5167
5569
  */
5168
- async getAllSkills() {
5570
+ async getAllSkills(_tenantId) {
5169
5571
  await this.ensureDirectoryExists();
5170
5572
  try {
5171
5573
  const entries = await fs.readdir(this.rootDir, { withFileTypes: true });
@@ -5202,17 +5604,19 @@ ${body}` : `${frontmatter}
5202
5604
  }
5203
5605
  }
5204
5606
  /**
5205
- * Get skill by ID
5607
+ * Get skill by ID for a tenant
5206
5608
  * ID should equal name (name is used for path addressing)
5609
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5207
5610
  */
5208
- async getSkillById(id) {
5611
+ async getSkillById(_tenantId, id) {
5209
5612
  return this.readSkillFile(id);
5210
5613
  }
5211
5614
  /**
5212
- * Create a new skill
5615
+ * Create a new skill for a tenant
5213
5616
  * id should equal name (name is used for path addressing)
5617
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5214
5618
  */
5215
- async createSkill(id, data) {
5619
+ async createSkill(_tenantId, id, data) {
5216
5620
  await this.ensureDirectoryExists();
5217
5621
  validateSkillName(data.name);
5218
5622
  if (id !== data.name) {
@@ -5220,14 +5624,15 @@ ${body}` : `${frontmatter}
5220
5624
  `Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
5221
5625
  );
5222
5626
  }
5223
- const existing = await this.getSkillById(id);
5627
+ const existing = await this.getSkillById(_tenantId, id);
5224
5628
  if (existing) {
5225
- return this.updateSkill(id, data);
5629
+ return this.updateSkill(_tenantId, id, data);
5226
5630
  }
5227
5631
  const now = /* @__PURE__ */ new Date();
5228
5632
  const skill = {
5229
5633
  id: data.name,
5230
5634
  // id equals name
5635
+ tenantId: _tenantId,
5231
5636
  name: data.name,
5232
5637
  description: data.description,
5233
5638
  license: data.license,
@@ -5242,9 +5647,10 @@ ${body}` : `${frontmatter}
5242
5647
  return skill;
5243
5648
  }
5244
5649
  /**
5245
- * Update an existing skill
5650
+ * Update an existing skill for a tenant
5651
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5246
5652
  */
5247
- async updateSkill(id, updates) {
5653
+ async updateSkill(_tenantId, id, updates) {
5248
5654
  const skill = await this.readSkillFile(id);
5249
5655
  if (!skill) {
5250
5656
  return null;
@@ -5268,6 +5674,7 @@ ${body}` : `${frontmatter}
5268
5674
  name: updates.name ?? skill.name,
5269
5675
  id: updates.name ?? skill.id,
5270
5676
  // id equals name
5677
+ tenantId: _tenantId,
5271
5678
  description: updates.description ?? skill.description,
5272
5679
  license: updates.license ?? skill.license,
5273
5680
  compatibility: updates.compatibility ?? skill.compatibility,
@@ -5280,10 +5687,11 @@ ${body}` : `${frontmatter}
5280
5687
  return updatedSkill;
5281
5688
  }
5282
5689
  /**
5283
- * Delete a skill by ID
5690
+ * Delete a skill by ID for a tenant
5284
5691
  * Deletes the entire directory (name is the directory name)
5692
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5285
5693
  */
5286
- async deleteSkill(id) {
5694
+ async deleteSkill(_tenantId, id) {
5287
5695
  await this.ensureDirectoryExists();
5288
5696
  const skillDir = this.getSkillDirectoryPath(id);
5289
5697
  try {
@@ -5297,50 +5705,55 @@ ${body}` : `${frontmatter}
5297
5705
  }
5298
5706
  }
5299
5707
  /**
5300
- * Check if skill exists
5708
+ * Check if skill exists for a tenant
5709
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5301
5710
  */
5302
- async hasSkill(id) {
5303
- const skill = await this.getSkillById(id);
5711
+ async hasSkill(_tenantId, id) {
5712
+ const skill = await this.getSkillById(_tenantId, id);
5304
5713
  return skill !== null;
5305
5714
  }
5306
5715
  /**
5307
- * Search skills by metadata
5716
+ * Search skills by metadata within a tenant
5717
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5308
5718
  */
5309
- async searchByMetadata(metadataKey, metadataValue) {
5310
- const allSkills = await this.getAllSkills();
5719
+ async searchByMetadata(_tenantId, metadataKey, metadataValue) {
5720
+ const allSkills = await this.getAllSkills(_tenantId);
5311
5721
  return allSkills.filter((skill) => {
5312
5722
  return skill.metadata && skill.metadata[metadataKey] === metadataValue;
5313
5723
  });
5314
5724
  }
5315
5725
  /**
5316
- * Filter skills by compatibility
5726
+ * Filter skills by compatibility within a tenant
5727
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5317
5728
  */
5318
- async filterByCompatibility(compatibility) {
5319
- const allSkills = await this.getAllSkills();
5729
+ async filterByCompatibility(_tenantId, compatibility) {
5730
+ const allSkills = await this.getAllSkills(_tenantId);
5320
5731
  return allSkills.filter((skill) => {
5321
5732
  return skill.compatibility === compatibility;
5322
5733
  });
5323
5734
  }
5324
5735
  /**
5325
- * Filter skills by license
5736
+ * Filter skills by license within a tenant
5737
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5326
5738
  */
5327
- async filterByLicense(license) {
5328
- const allSkills = await this.getAllSkills();
5739
+ async filterByLicense(_tenantId, license) {
5740
+ const allSkills = await this.getAllSkills(_tenantId);
5329
5741
  return allSkills.filter((skill) => {
5330
5742
  return skill.license === license;
5331
5743
  });
5332
5744
  }
5333
5745
  /**
5334
- * Get sub-skills of a parent skill
5746
+ * Get sub-skills of a parent skill within a tenant
5747
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5335
5748
  */
5336
- async getSubSkills(parentSkillName) {
5337
- const parentSkill = await this.getSkillById(parentSkillName);
5749
+ async getSubSkills(_tenantId, parentSkillName) {
5750
+ const parentSkill = await this.getSkillById(_tenantId, parentSkillName);
5338
5751
  if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
5339
5752
  return [];
5340
5753
  }
5341
5754
  const subSkills = [];
5342
5755
  for (const subSkillName of parentSkill.subSkills) {
5343
- const subSkill = await this.getSkillById(subSkillName);
5756
+ const subSkill = await this.getSkillById(_tenantId, subSkillName);
5344
5757
  if (subSkill) {
5345
5758
  subSkills.push(subSkill);
5346
5759
  }
@@ -5349,10 +5762,11 @@ ${body}` : `${frontmatter}
5349
5762
  }
5350
5763
  /**
5351
5764
  * List all resources in a skill's resources directory
5765
+ * @param tenantId The tenant identifier (accepted for protocol compliance)
5352
5766
  * @param skillName The skill name
5353
5767
  * @returns Array of resource paths relative to resources/ directory
5354
5768
  */
5355
- async listSkillResources(skillName) {
5769
+ async listSkillResources(_tenantId, skillName) {
5356
5770
  const skillDir = this.getSkillDirectoryPath(skillName);
5357
5771
  const resourcesDir = path3.join(skillDir, "resources");
5358
5772
  try {
@@ -5375,11 +5789,12 @@ ${body}` : `${frontmatter}
5375
5789
  }
5376
5790
  /**
5377
5791
  * Load a specific resource from a skill's resources directory
5792
+ * @param tenantId The tenant identifier (accepted for protocol compliance)
5378
5793
  * @param skillName The skill name
5379
5794
  * @param resourcePath Path to the resource relative to resources/ directory
5380
5795
  * @returns The resource content as string
5381
5796
  */
5382
- async loadSkillResource(skillName, resourcePath) {
5797
+ async loadSkillResource(_tenantId, skillName, resourcePath) {
5383
5798
  const skillDir = this.getSkillDirectoryPath(skillName);
5384
5799
  const resourcesDir = path3.join(skillDir, "resources");
5385
5800
  const fullPath = path3.join(resourcesDir, resourcePath);
@@ -6116,93 +6531,520 @@ var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager
6116
6531
  return storeLattice;
6117
6532
  }
6118
6533
  /**
6119
- * Get StoreLattice without type checking (for backward compatibility)
6120
- * @param key Lattice key name
6121
- * @param type Store type
6122
- * @returns StoreLattice (type may be unknown)
6534
+ * Get StoreLattice without type checking (for backward compatibility)
6535
+ * @param key Lattice key name
6536
+ * @param type Store type
6537
+ * @returns StoreLattice (type may be unknown)
6538
+ */
6539
+ getStoreLatticeUnsafe(key, type) {
6540
+ const compositeKey = this.getCompositeKey(key, type);
6541
+ const storeLattice = this.get(compositeKey);
6542
+ if (!storeLattice) {
6543
+ throw new Error(`StoreLattice ${key}:${type} not found`);
6544
+ }
6545
+ return storeLattice;
6546
+ }
6547
+ /**
6548
+ * Get all Lattices
6549
+ */
6550
+ getAllLattices() {
6551
+ return this.getAll();
6552
+ }
6553
+ /**
6554
+ * Check if Lattice exists
6555
+ * Uses composite key (key + type) to check existence
6556
+ * @param key Lattice key name
6557
+ * @param type Store type
6558
+ */
6559
+ hasLattice(key, type) {
6560
+ const compositeKey = this.getCompositeKey(key, type);
6561
+ return this.has(compositeKey);
6562
+ }
6563
+ /**
6564
+ * Remove Lattice
6565
+ * Uses composite key (key + type) to remove the store
6566
+ * @param key Lattice key name
6567
+ * @param type Store type
6568
+ */
6569
+ removeLattice(key, type) {
6570
+ const compositeKey = this.getCompositeKey(key, type);
6571
+ return this.remove(compositeKey);
6572
+ }
6573
+ /**
6574
+ * Clear all Lattices
6575
+ */
6576
+ clearLattices() {
6577
+ this.clear();
6578
+ }
6579
+ /**
6580
+ * Get Lattice count
6581
+ */
6582
+ getLatticeCount() {
6583
+ return this.count();
6584
+ }
6585
+ /**
6586
+ * Get Lattice key list
6587
+ */
6588
+ getLatticeKeys() {
6589
+ return this.keys();
6590
+ }
6591
+ };
6592
+ var storeLatticeManager = StoreLatticeManager.getInstance();
6593
+ var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
6594
+ var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
6595
+ var defaultThreadStore = new InMemoryThreadStore();
6596
+ var defaultAssistantStore = new InMemoryAssistantStore();
6597
+ var defaultSkillStore = new FileSystemSkillStore();
6598
+ var defaultWorkspaceStore = new InMemoryWorkspaceStore();
6599
+ var defaultProjectStore = new InMemoryProjectStore();
6600
+ var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
6601
+ var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
6602
+ var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
6603
+ storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
6604
+ storeLatticeManager.registerLattice(
6605
+ "default",
6606
+ "assistant",
6607
+ defaultAssistantStore
6608
+ );
6609
+ storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
6610
+ storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
6611
+ storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
6612
+ storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
6613
+ storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
6614
+ storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
6615
+ var defaultUserStore = new InMemoryUserStore();
6616
+ var defaultTenantStore = new InMemoryTenantStore();
6617
+ var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
6618
+ storeLatticeManager.registerLattice("default", "user", defaultUserStore);
6619
+ storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
6620
+ storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
6621
+
6622
+ // src/store_lattice/SandboxSkillStore.ts
6623
+ function parseFrontmatter2(content) {
6624
+ const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
6625
+ const match = content.match(frontmatterRegex);
6626
+ if (!match) {
6627
+ return { frontmatter: {}, body: content };
6628
+ }
6629
+ const frontmatterText = match[1];
6630
+ const body = match[2] || "";
6631
+ const frontmatter = {};
6632
+ const lines = frontmatterText.split("\n");
6633
+ let currentKey = null;
6634
+ let metadataIndent = 0;
6635
+ for (let i = 0; i < lines.length; i++) {
6636
+ const line = lines[i];
6637
+ const trimmed = line.trim();
6638
+ if (!trimmed || trimmed.startsWith("#")) {
6639
+ continue;
6640
+ }
6641
+ const indentMatch = line.match(/^(\s*)/);
6642
+ const indent = indentMatch ? indentMatch[1].length : 0;
6643
+ if (currentKey === "metadata" && indent > metadataIndent) {
6644
+ const colonIndex2 = trimmed.indexOf(":");
6645
+ if (colonIndex2 !== -1) {
6646
+ const key2 = trimmed.substring(0, colonIndex2).trim();
6647
+ let value2 = trimmed.substring(colonIndex2 + 1).trim();
6648
+ if (value2.startsWith('"') && value2.endsWith('"') || value2.startsWith("'") && value2.endsWith("'")) {
6649
+ value2 = value2.slice(1, -1);
6650
+ }
6651
+ if (!frontmatter.metadata) {
6652
+ frontmatter.metadata = {};
6653
+ }
6654
+ frontmatter.metadata[key2] = value2;
6655
+ }
6656
+ continue;
6657
+ }
6658
+ if (currentKey === "subSkills" && indent > metadataIndent) {
6659
+ if (trimmed.startsWith("-")) {
6660
+ let value2 = trimmed.substring(1).trim();
6661
+ if (value2.startsWith('"') && value2.endsWith('"') || value2.startsWith("'") && value2.endsWith("'")) {
6662
+ value2 = value2.slice(1, -1);
6663
+ }
6664
+ if (!frontmatter.subSkills) {
6665
+ frontmatter.subSkills = [];
6666
+ }
6667
+ frontmatter.subSkills.push(value2);
6668
+ }
6669
+ continue;
6670
+ }
6671
+ if ((currentKey === "metadata" || currentKey === "subSkills") && indent <= metadataIndent) {
6672
+ currentKey = null;
6673
+ metadataIndent = 0;
6674
+ }
6675
+ const colonIndex = trimmed.indexOf(":");
6676
+ if (colonIndex === -1) {
6677
+ continue;
6678
+ }
6679
+ const key = trimmed.substring(0, colonIndex).trim();
6680
+ let value = trimmed.substring(colonIndex + 1).trim();
6681
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
6682
+ value = value.slice(1, -1);
6683
+ }
6684
+ if (key === "metadata") {
6685
+ if (value === "" || value === "{}") {
6686
+ if (i + 1 < lines.length) {
6687
+ const nextLine = lines[i + 1];
6688
+ const nextIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;
6689
+ if (nextIndent > indent) {
6690
+ currentKey = "metadata";
6691
+ metadataIndent = indent;
6692
+ frontmatter.metadata = {};
6693
+ continue;
6694
+ }
6695
+ }
6696
+ frontmatter[key] = {};
6697
+ } else if (value.startsWith("{")) {
6698
+ try {
6699
+ frontmatter[key] = JSON.parse(value);
6700
+ } catch {
6701
+ frontmatter[key] = {};
6702
+ }
6703
+ } else {
6704
+ frontmatter[key] = {};
6705
+ }
6706
+ } else if (key === "subSkills") {
6707
+ if (value === "" || value === "[]") {
6708
+ if (i + 1 < lines.length) {
6709
+ const nextLine = lines[i + 1];
6710
+ const nextIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;
6711
+ if (nextIndent > indent && nextLine.trim().startsWith("-")) {
6712
+ currentKey = "subSkills";
6713
+ metadataIndent = indent;
6714
+ frontmatter.subSkills = [];
6715
+ continue;
6716
+ }
6717
+ }
6718
+ frontmatter[key] = [];
6719
+ } else if (value.startsWith("[")) {
6720
+ try {
6721
+ frontmatter[key] = JSON.parse(value);
6722
+ } catch {
6723
+ frontmatter[key] = [];
6724
+ }
6725
+ } else {
6726
+ frontmatter[key] = [];
6727
+ }
6728
+ } else {
6729
+ frontmatter[key] = value;
6730
+ }
6731
+ }
6732
+ return { frontmatter, body };
6733
+ }
6734
+ function generateFrontmatter2(data) {
6735
+ const lines = ["---"];
6736
+ lines.push(`name: ${data.name}`);
6737
+ lines.push(`description: ${data.description}`);
6738
+ if (data.license) {
6739
+ lines.push(`license: ${data.license}`);
6740
+ }
6741
+ if (data.compatibility) {
6742
+ lines.push(`compatibility: ${data.compatibility}`);
6743
+ }
6744
+ if (data.metadata && Object.keys(data.metadata).length > 0) {
6745
+ lines.push("metadata:");
6746
+ for (const [key, value] of Object.entries(data.metadata)) {
6747
+ lines.push(` ${key}: ${value}`);
6748
+ }
6749
+ }
6750
+ if (data.subSkills && data.subSkills.length > 0) {
6751
+ lines.push("subSkills:");
6752
+ for (const subSkill of data.subSkills) {
6753
+ lines.push(` - ${subSkill}`);
6754
+ }
6755
+ }
6756
+ lines.push("---");
6757
+ return lines.join("\n");
6758
+ }
6759
+ var SandboxSkillStore = class {
6760
+ constructor(options = {}) {
6761
+ this.sandboxManager = options.sandboxManager;
6762
+ this.basePath = options.basePath || "/home/gem/tenants";
6763
+ }
6764
+ /**
6765
+ * Get sandbox manager for a tenant
6766
+ */
6767
+ async getSandboxManager() {
6768
+ if (this.sandboxManager) {
6769
+ return this.sandboxManager;
6770
+ }
6771
+ return getSandBoxManager();
6772
+ }
6773
+ /**
6774
+ * Get skill directory path in sandbox
6775
+ */
6776
+ getSkillDirectoryPath(tenantId, name) {
6777
+ if (name.includes("..") || name.includes("/") || name.includes("\\")) {
6778
+ throw new Error(`Invalid skill name: ${name} (contains invalid characters)`);
6779
+ }
6780
+ return `${this.basePath}/${tenantId}/skills/${name}`;
6781
+ }
6782
+ /**
6783
+ * Get skill file path in sandbox
6784
+ */
6785
+ getSkillFilePath(tenantId, name) {
6786
+ return `${this.getSkillDirectoryPath(tenantId, name)}/SKILL.md`;
6787
+ }
6788
+ /**
6789
+ * Read skill from sandbox
6790
+ */
6791
+ async readSkillFile(tenantId, name) {
6792
+ try {
6793
+ const sandboxManager = await this.getSandboxManager();
6794
+ const sandbox = await sandboxManager.createSandbox("global");
6795
+ const filePath = this.getSkillFilePath(tenantId, name);
6796
+ const result = await sandbox.file.readFile({ file: filePath });
6797
+ if (!result.ok) {
6798
+ return null;
6799
+ }
6800
+ let content;
6801
+ if (typeof result.body === "string") {
6802
+ content = result.body;
6803
+ } else if (result.body && typeof result.body === "object") {
6804
+ const body = result.body;
6805
+ content = body.content || body.data?.content || JSON.stringify(body);
6806
+ } else {
6807
+ content = String(result.body);
6808
+ }
6809
+ const { frontmatter, body: skillBody } = parseFrontmatter2(content);
6810
+ if (!frontmatter.name || !frontmatter.description) {
6811
+ console.warn(`Invalid skill file ${name}: missing required fields`);
6812
+ return null;
6813
+ }
6814
+ return {
6815
+ id: name,
6816
+ tenantId,
6817
+ name: frontmatter.name,
6818
+ description: frontmatter.description,
6819
+ license: frontmatter.license,
6820
+ compatibility: frontmatter.compatibility,
6821
+ metadata: frontmatter.metadata || {},
6822
+ content: skillBody.trim() || void 0,
6823
+ subSkills: Array.isArray(frontmatter.subSkills) ? frontmatter.subSkills : void 0,
6824
+ createdAt: /* @__PURE__ */ new Date(),
6825
+ // Sandbox doesn't provide file stats easily
6826
+ updatedAt: /* @__PURE__ */ new Date()
6827
+ };
6828
+ } catch (error) {
6829
+ console.error(`Error reading skill ${name} from sandbox:`, error);
6830
+ return null;
6831
+ }
6832
+ }
6833
+ /**
6834
+ * Write skill to sandbox
6835
+ */
6836
+ async writeSkillFile(skill) {
6837
+ const sandboxManager = await this.getSandboxManager();
6838
+ const sandbox = await sandboxManager.createSandbox("global");
6839
+ const filePath = this.getSkillFilePath(skill.tenantId, skill.name);
6840
+ const frontmatter = generateFrontmatter2({
6841
+ name: skill.name,
6842
+ description: skill.description,
6843
+ license: skill.license,
6844
+ compatibility: skill.compatibility,
6845
+ metadata: skill.metadata,
6846
+ subSkills: skill.subSkills
6847
+ });
6848
+ const body = skill.content || "";
6849
+ const content = body ? `${frontmatter}
6850
+ ${body}` : `${frontmatter}
6851
+ `;
6852
+ const result = await sandbox.file.writeFile({
6853
+ file: filePath,
6854
+ content,
6855
+ encoding: "utf-8",
6856
+ append: false
6857
+ });
6858
+ if (!result.ok) {
6859
+ throw new Error(`Failed to write skill to sandbox: ${JSON.stringify(result.error)}`);
6860
+ }
6861
+ }
6862
+ /**
6863
+ * Get all skills for a tenant
6864
+ */
6865
+ async getAllSkills(tenantId) {
6866
+ try {
6867
+ const sandboxManager = await this.getSandboxManager();
6868
+ const sandbox = await sandboxManager.createSandbox("global");
6869
+ const skillsDir = `${this.basePath}/${tenantId}/skills`;
6870
+ const result = await sandbox.file.listPath({
6871
+ path: skillsDir,
6872
+ recursive: false,
6873
+ show_hidden: false
6874
+ });
6875
+ if (!result.ok || !result.body) {
6876
+ return [];
6877
+ }
6878
+ const files = result.body?.data?.files || [];
6879
+ const skills = [];
6880
+ for (const entry of files) {
6881
+ if (entry.is_directory) {
6882
+ const pathParts = entry.path.split("/");
6883
+ const skillName = pathParts[pathParts.length - 1];
6884
+ if (!skillName) continue;
6885
+ try {
6886
+ const skill = await this.readSkillFile(tenantId, skillName);
6887
+ if (skill) {
6888
+ skills.push(skill);
6889
+ }
6890
+ } catch (error) {
6891
+ console.error(`Error loading skill "${skillName}":`, error);
6892
+ }
6893
+ }
6894
+ }
6895
+ return skills.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
6896
+ } catch (error) {
6897
+ console.error(`Error listing skills for tenant ${tenantId}:`, error);
6898
+ return [];
6899
+ }
6900
+ }
6901
+ /**
6902
+ * Get skill by ID
6903
+ */
6904
+ async getSkillById(tenantId, id) {
6905
+ return this.readSkillFile(tenantId, id);
6906
+ }
6907
+ /**
6908
+ * Create a new skill
6909
+ */
6910
+ async createSkill(tenantId, id, data) {
6911
+ validateSkillName(data.name);
6912
+ if (id !== data.name) {
6913
+ throw new Error(
6914
+ `Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
6915
+ );
6916
+ }
6917
+ const existing = await this.getSkillById(tenantId, id);
6918
+ if (existing) {
6919
+ return this.updateSkill(tenantId, id, data);
6920
+ }
6921
+ const now = /* @__PURE__ */ new Date();
6922
+ const skill = {
6923
+ id: data.name,
6924
+ tenantId,
6925
+ name: data.name,
6926
+ description: data.description,
6927
+ license: data.license,
6928
+ compatibility: data.compatibility,
6929
+ metadata: data.metadata || {},
6930
+ content: data.content,
6931
+ subSkills: data.subSkills,
6932
+ createdAt: now,
6933
+ updatedAt: now
6934
+ };
6935
+ await this.writeSkillFile(skill);
6936
+ return skill;
6937
+ }
6938
+ /**
6939
+ * Update an existing skill
6123
6940
  */
6124
- getStoreLatticeUnsafe(key, type) {
6125
- const compositeKey = this.getCompositeKey(key, type);
6126
- const storeLattice = this.get(compositeKey);
6127
- if (!storeLattice) {
6128
- throw new Error(`StoreLattice ${key}:${type} not found`);
6941
+ async updateSkill(tenantId, id, updates) {
6942
+ const skill = await this.readSkillFile(tenantId, id);
6943
+ if (!skill) {
6944
+ return null;
6129
6945
  }
6130
- return storeLattice;
6946
+ if (updates.name !== void 0) {
6947
+ validateSkillName(updates.name);
6948
+ if (updates.name !== skill.name) {
6949
+ const newSkill = {
6950
+ ...skill,
6951
+ name: updates.name,
6952
+ id: updates.name,
6953
+ description: updates.description ?? skill.description,
6954
+ license: updates.license ?? skill.license,
6955
+ compatibility: updates.compatibility ?? skill.compatibility,
6956
+ metadata: updates.metadata ?? skill.metadata,
6957
+ content: updates.content !== void 0 ? updates.content : skill.content,
6958
+ subSkills: updates.subSkills !== void 0 ? updates.subSkills : skill.subSkills,
6959
+ updatedAt: /* @__PURE__ */ new Date()
6960
+ };
6961
+ await this.writeSkillFile(newSkill);
6962
+ await this.deleteSkill(tenantId, id);
6963
+ return newSkill;
6964
+ }
6965
+ }
6966
+ const updatedSkill = {
6967
+ ...skill,
6968
+ name: updates.name ?? skill.name,
6969
+ description: updates.description ?? skill.description,
6970
+ license: updates.license ?? skill.license,
6971
+ compatibility: updates.compatibility ?? skill.compatibility,
6972
+ metadata: updates.metadata ?? skill.metadata,
6973
+ content: updates.content !== void 0 ? updates.content : skill.content,
6974
+ subSkills: updates.subSkills !== void 0 ? updates.subSkills : skill.subSkills,
6975
+ updatedAt: /* @__PURE__ */ new Date()
6976
+ };
6977
+ await this.writeSkillFile(updatedSkill);
6978
+ return updatedSkill;
6131
6979
  }
6132
6980
  /**
6133
- * Get all Lattices
6981
+ * Delete a skill by ID
6134
6982
  */
6135
- getAllLattices() {
6136
- return this.getAll();
6983
+ async deleteSkill(tenantId, id) {
6984
+ try {
6985
+ const sandboxManager = await this.getSandboxManager();
6986
+ const sandbox = await sandboxManager.createSandbox("global");
6987
+ const filePath = this.getSkillFilePath(tenantId, id);
6988
+ const deleteResult = await sandbox.shell.execCommand({
6989
+ command: `rm -f "${filePath}"`
6990
+ });
6991
+ if (!deleteResult.ok) {
6992
+ return false;
6993
+ }
6994
+ return true;
6995
+ } catch (error) {
6996
+ console.error(`Error deleting skill ${id}:`, error);
6997
+ return false;
6998
+ }
6137
6999
  }
6138
7000
  /**
6139
- * Check if Lattice exists
6140
- * Uses composite key (key + type) to check existence
6141
- * @param key Lattice key name
6142
- * @param type Store type
7001
+ * Check if skill exists
6143
7002
  */
6144
- hasLattice(key, type) {
6145
- const compositeKey = this.getCompositeKey(key, type);
6146
- return this.has(compositeKey);
7003
+ async hasSkill(tenantId, id) {
7004
+ const skill = await this.getSkillById(tenantId, id);
7005
+ return skill !== null;
6147
7006
  }
6148
7007
  /**
6149
- * Remove Lattice
6150
- * Uses composite key (key + type) to remove the store
6151
- * @param key Lattice key name
6152
- * @param type Store type
7008
+ * Search skills by metadata within a tenant
6153
7009
  */
6154
- removeLattice(key, type) {
6155
- const compositeKey = this.getCompositeKey(key, type);
6156
- return this.remove(compositeKey);
7010
+ async searchByMetadata(tenantId, metadataKey, metadataValue) {
7011
+ const allSkills = await this.getAllSkills(tenantId);
7012
+ return allSkills.filter(
7013
+ (skill) => skill.metadata && skill.metadata[metadataKey] === metadataValue
7014
+ );
6157
7015
  }
6158
7016
  /**
6159
- * Clear all Lattices
7017
+ * Filter skills by compatibility within a tenant
6160
7018
  */
6161
- clearLattices() {
6162
- this.clear();
7019
+ async filterByCompatibility(tenantId, compatibility) {
7020
+ const allSkills = await this.getAllSkills(tenantId);
7021
+ return allSkills.filter((skill) => skill.compatibility === compatibility);
6163
7022
  }
6164
7023
  /**
6165
- * Get Lattice count
7024
+ * Filter skills by license within a tenant
6166
7025
  */
6167
- getLatticeCount() {
6168
- return this.count();
7026
+ async filterByLicense(tenantId, license) {
7027
+ const allSkills = await this.getAllSkills(tenantId);
7028
+ return allSkills.filter((skill) => skill.license === license);
6169
7029
  }
6170
7030
  /**
6171
- * Get Lattice key list
7031
+ * Get sub-skills of a parent skill within a tenant
6172
7032
  */
6173
- getLatticeKeys() {
6174
- return this.keys();
7033
+ async getSubSkills(tenantId, parentSkillName) {
7034
+ const parentSkill = await this.getSkillById(tenantId, parentSkillName);
7035
+ if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
7036
+ return [];
7037
+ }
7038
+ const subSkills = [];
7039
+ for (const subSkillName of parentSkill.subSkills) {
7040
+ const subSkill = await this.getSkillById(tenantId, subSkillName);
7041
+ if (subSkill) {
7042
+ subSkills.push(subSkill);
7043
+ }
7044
+ }
7045
+ return subSkills;
6175
7046
  }
6176
7047
  };
6177
- var storeLatticeManager = StoreLatticeManager.getInstance();
6178
- var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
6179
- var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
6180
- var defaultThreadStore = new InMemoryThreadStore();
6181
- var defaultAssistantStore = new InMemoryAssistantStore();
6182
- var defaultSkillStore = new FileSystemSkillStore();
6183
- var defaultWorkspaceStore = new InMemoryWorkspaceStore();
6184
- var defaultProjectStore = new InMemoryProjectStore();
6185
- var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
6186
- var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
6187
- var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
6188
- storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
6189
- storeLatticeManager.registerLattice(
6190
- "default",
6191
- "assistant",
6192
- defaultAssistantStore
6193
- );
6194
- storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
6195
- storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
6196
- storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
6197
- storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
6198
- storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
6199
- storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
6200
- var defaultUserStore = new InMemoryUserStore();
6201
- var defaultTenantStore = new InMemoryTenantStore();
6202
- var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
6203
- storeLatticeManager.registerLattice("default", "user", defaultUserStore);
6204
- storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
6205
- storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
6206
7048
 
6207
7049
  // src/tool_lattice/skill/load_skills.ts
6208
7050
  import z40 from "zod";
@@ -6241,9 +7083,11 @@ var createLoadSkillContentTool = () => {
6241
7083
  try {
6242
7084
  const storeLattice = getStoreLattice("default", "skill");
6243
7085
  const skillStore = storeLattice.store;
6244
- const skill = await skillStore.getSkillById(input.skill_name);
7086
+ const runConfig = _exe_config?.configurable?.runConfig || {};
7087
+ const tenantId = runConfig.tenantId || "default";
7088
+ const skill = await skillStore.getSkillById(tenantId, input.skill_name);
6245
7089
  if (!skill) {
6246
- const allSkills = await skillStore.getAllSkills();
7090
+ const allSkills = await skillStore.getAllSkills(tenantId);
6247
7091
  const availableSkills = allSkills.map((s) => s.name).join(", ");
6248
7092
  return `Skill "${input.skill_name}" not found. Available skills: ${availableSkills}`;
6249
7093
  }
@@ -6275,7 +7119,7 @@ ${content}`;
6275
7119
  const fsStore = skillStore;
6276
7120
  if (fsStore.listSkillResources) {
6277
7121
  try {
6278
- const resources = await fsStore.listSkillResources(input.skill_name);
7122
+ const resources = await fsStore.listSkillResources(tenantId, input.skill_name);
6279
7123
  if (resources.length > 0) {
6280
7124
  result += "\n\n---\n\n**Resources** (use `load_skill_resource` tool to access):\n";
6281
7125
  resources.forEach((resource) => {
@@ -6309,7 +7153,8 @@ var createLoadSkillResourceTool = () => {
6309
7153
  return tool41(
6310
7154
  async (input, _exe_config) => {
6311
7155
  try {
6312
- const storeLattice = getStoreLattice("default", "skill");
7156
+ const tenantId = _exe_config?.configurable?.runConfig?.tenantId || "default";
7157
+ const storeLattice = getStoreLattice(tenantId, "skill");
6313
7158
  const skillStore = storeLattice.store;
6314
7159
  const fsStore = skillStore;
6315
7160
  if (!fsStore.loadSkillResource) {
@@ -6349,15 +7194,16 @@ function createSkillMiddleware(params = {}) {
6349
7194
  createLoadSkillContentTool(),
6350
7195
  createLoadSkillResourceTool()
6351
7196
  ],
6352
- beforeAgent: async () => {
7197
+ beforeAgent: async (state, runtime) => {
6353
7198
  try {
6354
7199
  const storeLattice = getStoreLattice("default", "skill");
6355
7200
  const skillStore = storeLattice?.store;
7201
+ const tenantId = runtime?.context?.tenantId || state?.tenantId || "default";
6356
7202
  if (readAll) {
6357
- latestSkills = await skillStore.getAllSkills();
7203
+ latestSkills = await skillStore.getAllSkills(tenantId);
6358
7204
  } else if (skills && skills.length > 0) {
6359
7205
  const skillLatticePromises = skills.map(
6360
- (skillId) => skillStore.getSkillById(skillId)
7206
+ (skillId) => skillStore.getSkillById(tenantId, skillId)
6361
7207
  );
6362
7208
  const skillLattices = await Promise.all(skillLatticePromises);
6363
7209
  latestSkills = skillLattices.filter((skill) => skill !== void 0);
@@ -7243,19 +8089,20 @@ ${systemPrompt}` : systemPrompt;
7243
8089
  import { createMiddleware as createMiddleware6 } from "langchain";
7244
8090
  function createMetricsMiddleware(params) {
7245
8091
  const { serverKeys, serverDescriptions, connectAll } = params;
7246
- let effectiveServerKeys = serverKeys;
7247
- if (connectAll) {
7248
- effectiveServerKeys = metricsServerManager.getServerKeys().map((s) => s.key);
7249
- }
7250
- if (!effectiveServerKeys || effectiveServerKeys.length === 0) {
8092
+ if (!serverKeys || serverKeys.length === 0) {
7251
8093
  return createMiddleware6({
7252
8094
  name: "metricsMiddleware",
7253
8095
  tools: []
7254
8096
  });
7255
8097
  }
7256
8098
  const toolParams = {
7257
- serverKeys: effectiveServerKeys,
7258
- serverDescriptions
8099
+ serverKeys,
8100
+ serverDescriptions,
8101
+ // When connectAll is true, tools will dynamically get all servers for the tenant at runtime
8102
+ connectAll,
8103
+ // getTenantId will be called at runtime by each tool
8104
+ getTenantId: void 0
8105
+ // Tools will extract tenantId from _exeConfig.configurable.runConfig
7259
8106
  };
7260
8107
  return createMiddleware6({
7261
8108
  name: "metricsMiddleware",
@@ -7388,7 +8235,7 @@ function createAskUserClarifyMiddleware() {
7388
8235
  }
7389
8236
 
7390
8237
  // src/agent_lattice/builders/commonMiddleware.ts
7391
- function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
8238
+ async function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
7392
8239
  const middlewares = [];
7393
8240
  const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
7394
8241
  if (filesystemConfig?.enabled && filesystemBackend) {
@@ -7443,14 +8290,16 @@ function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
7443
8290
 
7444
8291
  // src/agent_lattice/builders/ReActAgentGraphBuilder.ts
7445
8292
  var ReActAgentGraphBuilder = class {
7446
- createFilesystemBackendFactory(middlewareConfigs) {
8293
+ createFilesystemBackendFactory(middlewareConfigs, agentLattice) {
7447
8294
  const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
7448
8295
  if (!filesystemConfig || !filesystemConfig.enabled) {
7449
8296
  return void 0;
7450
8297
  }
7451
8298
  const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
7452
- return async (config) => {
7453
- const { workspaceId, projectId } = config;
8299
+ const agentTenantId = agentLattice.config.tenantId;
8300
+ return async (stateAndStore) => {
8301
+ const { tenantId: runtimeTenantId, workspaceId, projectId } = stateAndStore;
8302
+ const tenantId = runtimeTenantId || agentTenantId;
7454
8303
  let sandboxName = "global";
7455
8304
  if (isolatedLevel === "agent") {
7456
8305
  sandboxName = "agent";
@@ -7461,14 +8310,22 @@ var ReActAgentGraphBuilder = class {
7461
8310
  if (!sandboxManager) {
7462
8311
  throw new Error("Sandbox manager not found");
7463
8312
  }
8313
+ let workingDirectory = "/";
8314
+ if (workspaceId && projectId) {
8315
+ if (tenantId) {
8316
+ workingDirectory = `/tenants/${tenantId}/${workspaceId}/${projectId}`;
8317
+ } else {
8318
+ workingDirectory = `/${workspaceId}/${projectId}`;
8319
+ }
8320
+ }
7464
8321
  return new SandboxFilesystem({
7465
8322
  sandboxInstance: await sandboxManager.createSandbox(sandboxName),
7466
- workingDirectory: workspaceId && projectId ? `/${workspaceId}/${projectId}` : "/"
8323
+ workingDirectory
7467
8324
  });
7468
8325
  };
7469
8326
  }
7470
- createMiddlewares(middlewareConfigs) {
7471
- return createCommonMiddlewares(middlewareConfigs);
8327
+ async createMiddlewares(middlewareConfigs) {
8328
+ return await createCommonMiddlewares(middlewareConfigs);
7472
8329
  }
7473
8330
  /**
7474
8331
  * 构建ReAct Agent Graph
@@ -7477,15 +8334,15 @@ var ReActAgentGraphBuilder = class {
7477
8334
  * @param params Agent构建参数
7478
8335
  * @returns 返回CompiledGraph对象
7479
8336
  */
7480
- build(agentLattice, params) {
8337
+ async build(agentLattice, params) {
7481
8338
  const tools = params.tools.map((t) => {
7482
8339
  const tool48 = getToolClient(t.key);
7483
8340
  return tool48;
7484
8341
  }).filter((tool48) => tool48 !== void 0);
7485
8342
  const stateSchema2 = createReactAgentSchema(params.stateSchema);
7486
8343
  const middlewareConfigs = params.middleware || [];
7487
- const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs);
7488
- const middlewares = createCommonMiddlewares(middlewareConfigs, filesystemBackend);
8344
+ const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs, agentLattice);
8345
+ const middlewares = await createCommonMiddlewares(middlewareConfigs, filesystemBackend);
7489
8346
  return createAgent({
7490
8347
  model: params.model,
7491
8348
  tools,
@@ -8328,14 +9185,18 @@ var StoreBackend = class {
8328
9185
  /**
8329
9186
  * Get the namespace for store operations.
8330
9187
  *
8331
- * If an assistant_id is available in stateAndStore, return
8332
- * [assistant_id, "filesystem"] to provide per-assistant isolation.
9188
+ * If both tenant_id and assistant_id are available, return
9189
+ * [tenant_id, assistant_id, "filesystem"] for full tenant + assistant isolation.
9190
+ * If only assistant_id is available, return [assistant_id, "filesystem"].
8333
9191
  * Otherwise return ["filesystem"].
8334
9192
  */
8335
9193
  getNamespace() {
8336
9194
  const namespace = "filesystem";
9195
+ const tenantId = this.stateAndStore.tenantId;
8337
9196
  const assistantId = this.stateAndStore.assistantId;
8338
- if (assistantId) {
9197
+ if (tenantId && assistantId) {
9198
+ return [tenantId, assistantId, namespace];
9199
+ } else if (assistantId) {
8339
9200
  return [assistantId, namespace];
8340
9201
  }
8341
9202
  return [namespace];
@@ -9762,8 +10623,8 @@ function createFilesystemBackendFactory(middlewareConfigs) {
9762
10623
  return void 0;
9763
10624
  }
9764
10625
  const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
9765
- return async (config) => {
9766
- const { workspaceId, projectId } = config;
10626
+ return async (stateAndStore) => {
10627
+ const { tenantId, workspaceId, projectId } = stateAndStore;
9767
10628
  let sandboxName = "global";
9768
10629
  if (isolatedLevel === "agent") {
9769
10630
  sandboxName = "agent";
@@ -9774,9 +10635,17 @@ function createFilesystemBackendFactory(middlewareConfigs) {
9774
10635
  if (!sandboxManager) {
9775
10636
  throw new Error("Sandbox manager not found");
9776
10637
  }
10638
+ let workingDirectory = "/";
10639
+ if (workspaceId && projectId) {
10640
+ if (tenantId) {
10641
+ workingDirectory = `/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`;
10642
+ } else {
10643
+ workingDirectory = `/workspaces/${workspaceId}/${projectId}`;
10644
+ }
10645
+ }
9777
10646
  return new SandboxFilesystem({
9778
10647
  sandboxInstance: await sandboxManager.createSandbox(sandboxName),
9779
- workingDirectory: workspaceId && projectId ? `/workspaces/${workspaceId}/${projectId}` : "/"
10648
+ workingDirectory
9780
10649
  });
9781
10650
  };
9782
10651
  }
@@ -9786,8 +10655,8 @@ var DeepAgentGraphBuilder = class {
9786
10655
  /**
9787
10656
  * 根据 middleware 配置创建 middlewares
9788
10657
  */
9789
- createMiddlewares(middlewareConfigs) {
9790
- return createCommonMiddlewares(middlewareConfigs);
10658
+ async createMiddlewares(middlewareConfigs) {
10659
+ return await createCommonMiddlewares(middlewareConfigs);
9791
10660
  }
9792
10661
  /**
9793
10662
  * 构建Deep Agent Graph
@@ -9796,12 +10665,12 @@ var DeepAgentGraphBuilder = class {
9796
10665
  * @param params Agent构建参数
9797
10666
  * @returns 返回CompiledGraph对象
9798
10667
  */
9799
- build(agentLattice, params) {
10668
+ async build(agentLattice, params) {
9800
10669
  const tools = params.tools.map((t) => {
9801
10670
  const toolClient = getToolClient(t.key);
9802
10671
  return toolClient;
9803
10672
  }).filter((tool48) => tool48 !== void 0);
9804
- const subagents = params.subAgents.map((sa) => {
10673
+ const subagents = await Promise.all(params.subAgents.map(async (sa) => {
9805
10674
  if (sa.client) {
9806
10675
  return {
9807
10676
  key: sa.config.key,
@@ -9810,7 +10679,7 @@ var DeepAgentGraphBuilder = class {
9810
10679
  runnable: sa.client
9811
10680
  };
9812
10681
  } else {
9813
- const subagentClient = createAgentClientFromAgentLattice({
10682
+ const subagentClient = await createAgentClientFromAgentLattice({
9814
10683
  config: sa.config
9815
10684
  });
9816
10685
  return {
@@ -9820,10 +10689,10 @@ var DeepAgentGraphBuilder = class {
9820
10689
  runnable: subagentClient
9821
10690
  };
9822
10691
  }
9823
- });
10692
+ }));
9824
10693
  const middlewareConfigs = params.middleware || [];
9825
10694
  const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
9826
- const middlewares = this.createMiddlewares(middlewareConfigs);
10695
+ const middlewares = await this.createMiddlewares(middlewareConfigs);
9827
10696
  const deepAgent = createDeepAgent({
9828
10697
  tools,
9829
10698
  model: params.model,
@@ -11399,7 +12268,7 @@ var TeamAgentGraphBuilder = class {
11399
12268
  * @param params - Build params with resolved tools and model
11400
12269
  * @returns AgentClient (the TeamLead ReactAgent)
11401
12270
  */
11402
- build(agentLattice, params) {
12271
+ async build(agentLattice, params) {
11403
12272
  const config = agentLattice.config;
11404
12273
  if (!isTeamAgentConfig(config)) {
11405
12274
  throw new Error(
@@ -11422,7 +12291,7 @@ var TeamAgentGraphBuilder = class {
11422
12291
  });
11423
12292
  const middlewareConfigs = params.middleware || [];
11424
12293
  let filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
11425
- const middlewares = createCommonMiddlewares(middlewareConfigs);
12294
+ const middlewares = await createCommonMiddlewares(middlewareConfigs);
11426
12295
  if (!filesystemBackend) {
11427
12296
  filesystemBackend = async (config2) => {
11428
12297
  return new StateBackend(config2);
@@ -11605,6 +12474,31 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11605
12474
  this.initialized = false;
11606
12475
  this.subscribeToAssistantEvents();
11607
12476
  }
12477
+ /**
12478
+ * 从store异步加载单个AgentLattice
12479
+ * 实现BaseLatticeManager的可选方法,支持从assistant store加载单个agent
12480
+ * @param tenantId 租户ID
12481
+ * @param key Agent键名
12482
+ * @returns AgentLattice或undefined
12483
+ */
12484
+ async loadItemFromStore(tenantId, key) {
12485
+ try {
12486
+ const storeLattice = getStoreLattice("default", "assistant");
12487
+ const assistant = await storeLattice.store.getAssistantById(tenantId, key);
12488
+ if (!assistant) {
12489
+ return void 0;
12490
+ }
12491
+ const config = assistantToConfig(assistant);
12492
+ const agentLattice = {
12493
+ config,
12494
+ client: void 0
12495
+ };
12496
+ return agentLattice;
12497
+ } catch (error) {
12498
+ console.error(`Failed to load agent from store [tenant: ${tenantId}, key: ${key}]:`, error);
12499
+ return void 0;
12500
+ }
12501
+ }
11608
12502
  /**
11609
12503
  * 获取AgentLatticeManager单例实例
11610
12504
  */
@@ -11614,11 +12508,15 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11614
12508
  }
11615
12509
  return _AgentLatticeManager._instance;
11616
12510
  }
12511
+ /**
12512
+ * @deprecated This method loads assistants only for the "default" tenant.
12513
+ * Use initializeStoredAssistantsForTenant(tenantId) for proper tenant isolation.
12514
+ */
11617
12515
  async initializeStoredAssistants() {
11618
12516
  if (this.initialized) return;
11619
12517
  try {
11620
12518
  const storeLattice = getStoreLattice("default", "assistant");
11621
- const assistants = await storeLattice.store.getAllAssistants();
12519
+ const assistants = await storeLattice.store.getAllAssistants("default");
11622
12520
  for (const assistant of assistants) {
11623
12521
  if (this.has(assistant.id)) continue;
11624
12522
  const config = assistantToConfig(assistant);
@@ -11631,33 +12529,33 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11631
12529
  }
11632
12530
  subscribeToAssistantEvents() {
11633
12531
  event_bus_default.subscribe("assistant:created", (data) => {
11634
- this.handleAssistantChange(data.id);
12532
+ this.handleAssistantChange(data.id, data.tenantId ?? "default");
11635
12533
  });
11636
12534
  event_bus_default.subscribe("assistant:updated", (data) => {
11637
- this.handleAssistantChange(data.id);
12535
+ this.handleAssistantChange(data.id, data.tenantId ?? "default");
11638
12536
  });
11639
12537
  event_bus_default.subscribe("assistant:deleted", (data) => {
11640
- this.handleAssistantDelete(data.id);
12538
+ this.handleAssistantDelete(data.id, data.tenantId ?? "default");
11641
12539
  });
11642
12540
  }
11643
- async handleAssistantChange(assistantId) {
12541
+ async handleAssistantChange(assistantId, tenantId = "default") {
11644
12542
  try {
11645
12543
  const storeLattice = getStoreLattice("default", "assistant");
11646
- const assistant = await storeLattice.store.getAssistantById(assistantId);
12544
+ const assistant = await storeLattice.store.getAssistantById(tenantId, assistantId);
11647
12545
  if (assistant) {
11648
- if (this.has(assistantId)) {
11649
- this.remove(assistantId);
12546
+ if (this.hasWithTenant(tenantId, assistantId)) {
12547
+ this.removeWithTenant(tenantId, assistantId);
11650
12548
  }
11651
12549
  const config = assistantToConfig(assistant);
11652
- this.registerLattice(config);
12550
+ this.registerLatticeWithTenant(tenantId, config);
11653
12551
  }
11654
12552
  } catch (error) {
11655
- console.error(`Failed to handle assistant change for ${assistantId}:`, error);
12553
+ console.error(`Failed to handle assistant change for ${assistantId} (tenant: ${tenantId}):`, error);
11656
12554
  }
11657
12555
  }
11658
- handleAssistantDelete(assistantId) {
11659
- if (this.has(assistantId)) {
11660
- this.remove(assistantId);
12556
+ handleAssistantDelete(assistantId, tenantId = "default") {
12557
+ if (this.hasWithTenant(tenantId, assistantId)) {
12558
+ this.removeWithTenant(tenantId, assistantId);
11661
12559
  }
11662
12560
  }
11663
12561
  /**
@@ -11666,8 +12564,96 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11666
12564
  getLatticeType() {
11667
12565
  return "agents";
11668
12566
  }
12567
+ // ========== 带租户的新API ==========
12568
+ /**
12569
+ * 带租户注册Agent Lattice
12570
+ * @param tenantId 租户ID
12571
+ * @param config Agent配置
12572
+ */
12573
+ registerLatticeWithTenant(tenantId, config) {
12574
+ const agentLattice = {
12575
+ config: { ...config, tenantId },
12576
+ client: void 0
12577
+ // 客户端将在需要时由initializeClient创建
12578
+ };
12579
+ this.registerWithTenant(tenantId, config.key, agentLattice);
12580
+ }
12581
+ /**
12582
+ * 带租户获取AgentLattice
12583
+ * @param tenantId 租户ID
12584
+ * @param key Lattice键名
12585
+ */
12586
+ getAgentLatticeWithTenant(tenantId, key) {
12587
+ return this.getWithTenant(tenantId, key);
12588
+ }
12589
+ /**
12590
+ * 带租户检查Lattice是否存在
12591
+ * @param tenantId 租户ID
12592
+ * @param key Lattice键名
12593
+ */
12594
+ hasAgentLatticeWithTenant(tenantId, key) {
12595
+ return this.hasWithTenant(tenantId, key);
12596
+ }
12597
+ /**
12598
+ * 带租户移除Lattice
12599
+ * @param tenantId 租户ID
12600
+ * @param key Lattice键名
12601
+ */
12602
+ removeAgentLatticeWithTenant(tenantId, key) {
12603
+ return this.removeWithTenant(tenantId, key);
12604
+ }
12605
+ /**
12606
+ * 获取指定租户的所有Agent Lattice
12607
+ * @param tenantId 租户ID
12608
+ */
12609
+ getAllAgentLatticesByTenant(tenantId) {
12610
+ return this.getAllByTenant(tenantId);
12611
+ }
12612
+ /**
12613
+ * 清空指定租户的所有Agent Lattice
12614
+ * @param tenantId 租户ID
12615
+ */
12616
+ clearAgentLatticesByTenant(tenantId) {
12617
+ this.clearByTenant(tenantId);
12618
+ }
12619
+ /**
12620
+ * 带租户获取Agent配置
12621
+ * @param tenantId 租户ID
12622
+ * @param key Lattice键名
12623
+ */
12624
+ getAgentConfigWithTenant(tenantId, key) {
12625
+ return this.getAgentLatticeWithTenant(tenantId, key)?.config;
12626
+ }
12627
+ /**
12628
+ * 获取指定租户的所有Agent配置
12629
+ * 先从数据库加载该租户的 assistants,然后返回所有配置
12630
+ * @param tenantId 租户ID
12631
+ */
12632
+ async getAllAgentConfigsByTenant(tenantId) {
12633
+ await this.initializeStoredAssistantsForTenant(tenantId);
12634
+ return this.getAllAgentLatticesByTenant(tenantId).map((lattice) => lattice.config);
12635
+ }
12636
+ /**
12637
+ * 从数据库加载指定租户的存储助手
12638
+ * @param tenantId 租户ID
12639
+ */
12640
+ async initializeStoredAssistantsForTenant(tenantId) {
12641
+ try {
12642
+ const storeLattice = getStoreLattice("default", "assistant");
12643
+ const assistants = await storeLattice.store.getAllAssistants(tenantId);
12644
+ for (const assistant of assistants) {
12645
+ if (this.hasAgentLatticeWithTenant(tenantId, assistant.id)) continue;
12646
+ const config = assistantToConfig(assistant);
12647
+ this.registerLatticeWithTenant(tenantId, config);
12648
+ }
12649
+ } catch (error) {
12650
+ console.error(`Failed to initialize stored assistants for tenant ${tenantId}:`, error);
12651
+ }
12652
+ }
12653
+ // ========== 向后兼容的旧API(使用 default 租户) ==========
11669
12654
  /**
11670
- * 注册Agent Lattice
12655
+ * 注册Agent Lattice(向后兼容,使用 "default" 租户)
12656
+ * @deprecated Use registerLatticeWithTenant(tenantId, config) instead
11671
12657
  * @param config Agent配置
11672
12658
  */
11673
12659
  registerLattice(config) {
@@ -11705,7 +12691,8 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11705
12691
  return this.remove(key);
11706
12692
  }
11707
12693
  /**
11708
- * 获取AgentLattice
12694
+ * 获取AgentLattice(向后兼容,使用 "default" 租户)
12695
+ * @deprecated Use getAgentLatticeWithTenant(tenantId, key) instead
11709
12696
  * @param key Lattice键名
11710
12697
  */
11711
12698
  getAgentLattice(key) {
@@ -11718,25 +12705,28 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11718
12705
  return this.getAll();
11719
12706
  }
11720
12707
  /**
11721
- * 检查Lattice是否存在
12708
+ * 检查Lattice是否存在(向后兼容,使用 "default" 租户)
12709
+ * @deprecated Use hasAgentLatticeWithTenant(tenantId, key) instead
11722
12710
  * @param key Lattice键名
11723
12711
  */
11724
12712
  hasLattice(key) {
11725
12713
  return this.has(key);
11726
12714
  }
11727
12715
  /**
11728
- * 移除Lattice
12716
+ * 移除Lattice(向后兼容,使用 "default" 租户)
12717
+ * @deprecated Use removeAgentLatticeWithTenant(tenantId, key) instead
11729
12718
  * @param key Lattice键名
11730
12719
  */
11731
12720
  removeLattice(key) {
11732
12721
  return this.remove(key);
11733
12722
  }
11734
12723
  /**
11735
- * 获取Agent配置
12724
+ * 获取Agent配置(向后兼容,使用 "default" 租户)
12725
+ * @deprecated Use getAgentConfigWithTenant(tenantId, key) instead
11736
12726
  * @param key Lattice键名
11737
12727
  */
11738
12728
  getAgentConfig(key) {
11739
- return this.getAgentLattice(key)?.config;
12729
+ return this.getAgentLatticeWithTenant("default", key)?.config;
11740
12730
  }
11741
12731
  /**
11742
12732
  * 获取所有Agent配置
@@ -11757,8 +12747,9 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11757
12747
  return false;
11758
12748
  }
11759
12749
  try {
11760
- if (agentLattice.config.schema) {
11761
- agentLattice.config.schema.parse(input);
12750
+ const config = agentLattice.config;
12751
+ if ("schema" in config && config.schema) {
12752
+ config.schema.parse(input);
11762
12753
  }
11763
12754
  return true;
11764
12755
  } catch {
@@ -11806,9 +12797,10 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11806
12797
  * @returns 返回Agent构建参数
11807
12798
  */
11808
12799
  buildAgentParams(agentLattice, options) {
12800
+ const tenantId = agentLattice.config.tenantId || "default";
11809
12801
  const paramsBuilder = new AgentParamsBuilder((key) => {
11810
- this.initializeClient(key);
11811
- return this.getAgentLattice(key);
12802
+ this.initializeClient(tenantId, key);
12803
+ return this.getAgentLatticeWithTenant(tenantId, key);
11812
12804
  });
11813
12805
  return paramsBuilder.buildParams(agentLattice, options);
11814
12806
  }
@@ -11819,7 +12811,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11819
12811
  * @param options Build options
11820
12812
  * @returns AgentClient instance
11821
12813
  */
11822
- createAgentClientFromConfig(agentLattice, options) {
12814
+ async createAgentClientFromConfig(agentLattice, options) {
11823
12815
  const resolvedConfig = this.resolveInheritedConfig(agentLattice.config);
11824
12816
  const resolvedLattice = {
11825
12817
  ...agentLattice,
@@ -11828,26 +12820,50 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11828
12820
  const factory = AgentGraphBuilderFactory.getInstance();
11829
12821
  const builder = factory.getBuilder(resolvedConfig.type);
11830
12822
  const params = this.buildAgentParams(resolvedLattice, options);
11831
- return builder.build(resolvedLattice, params);
12823
+ return await builder.build(resolvedLattice, params);
11832
12824
  }
11833
12825
  /**
11834
12826
  * 初始化Agent客户端
11835
12827
  *
11836
12828
  * 使用AgentGraphBuilderFactory构建Graph并设置为客户端
11837
12829
  *
12830
+ * @param tenantId 租户ID
11838
12831
  * @param key Lattice键名
11839
12832
  * @param options 构建选项
11840
12833
  * @returns 返回CompiledGraph对象
11841
12834
  */
11842
- initializeClient(key, options) {
11843
- const agentLattice = this.getAgentLattice(key);
12835
+ async initializeClient(tenantId, key, options) {
12836
+ const agentLattice = this.getAgentLatticeWithTenant(tenantId, key);
12837
+ if (!agentLattice) {
12838
+ throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
12839
+ }
12840
+ if (agentLattice.client) {
12841
+ return agentLattice.client;
12842
+ }
12843
+ const graph = await this.createAgentClientFromConfig(agentLattice, options);
12844
+ agentLattice.client = graph;
12845
+ return graph;
12846
+ }
12847
+ /**
12848
+ * 异步初始化Agent客户端(支持从store加载)
12849
+ *
12850
+ * 如果内存中不存在,会尝试从store加载
12851
+ * 使用AgentGraphBuilderFactory构建Graph并设置为客户端
12852
+ *
12853
+ * @param tenantId 租户ID
12854
+ * @param key Lattice键名
12855
+ * @param options 构建选项
12856
+ * @returns 返回CompiledGraph对象
12857
+ */
12858
+ async initializeClientAsync(tenantId, key, options) {
12859
+ const agentLattice = await this.getOrLoadWithTenant(tenantId, key);
11844
12860
  if (!agentLattice) {
11845
- throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728`);
12861
+ throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
11846
12862
  }
11847
12863
  if (agentLattice.client) {
11848
12864
  return agentLattice.client;
11849
12865
  }
11850
- const graph = this.createAgentClientFromConfig(agentLattice, options);
12866
+ const graph = await this.createAgentClientFromConfig(agentLattice, options);
11851
12867
  agentLattice.client = graph;
11852
12868
  return graph;
11853
12869
  }
@@ -11856,19 +12872,24 @@ var agentLatticeManager = AgentLatticeManager.getInstance();
11856
12872
  var registerAgentLattice = (config) => {
11857
12873
  agentLatticeManager.registerLattice(config);
11858
12874
  };
11859
- var registerAgentLattices = (configs) => {
12875
+ var registerAgentLatticeWithTenant = (tenantId, config) => {
12876
+ agentLatticeManager.registerLatticeWithTenant(tenantId, config);
12877
+ };
12878
+ var registerAgentLattices = (tenantId, configs) => {
12879
+ if (!tenantId) {
12880
+ throw new Error("tenantId is required");
12881
+ }
11860
12882
  configs.forEach((config) => {
11861
- agentLatticeManager.registerLattice(config);
12883
+ agentLatticeManager.registerLatticeWithTenant(tenantId, config);
11862
12884
  });
11863
12885
  };
11864
- var getAgentLattice = (key) => agentLatticeManager.getAgentLattice(key);
11865
12886
  var getAgentConfig = (key) => agentLatticeManager.getAgentConfig(key);
11866
12887
  var getAllAgentConfigs = () => agentLatticeManager.getAllAgentConfigs();
11867
12888
  var validateAgentInput = (key, input) => agentLatticeManager.validateAgentInput(key, input);
11868
12889
  var registerTeammateAgent = (key, client) => agentLatticeManager.registerTeammateAgent(key, client);
11869
12890
  var unregisterTeammateAgent = (key) => agentLatticeManager.unregisterTeammateAgent(key);
11870
- var getAgentClient = (key, options) => agentLatticeManager.initializeClient(key, options);
11871
- var createAgentClientFromAgentLattice = (agentLattice, options) => agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
12891
+ var getAgentClient = (tenantId, key, options) => agentLatticeManager.initializeClient(tenantId, key, options);
12892
+ var createAgentClientFromAgentLattice = async (agentLattice, options) => await agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
11872
12893
 
11873
12894
  // src/chunk_buffer_lattice/ChunkBuffer.ts
11874
12895
  var ChunkBuffer = class {
@@ -11950,6 +12971,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
11950
12971
  buffer = {
11951
12972
  threadId,
11952
12973
  chunks$: new ReplaySubject(this.config.maxChunks),
12974
+ chunks: [],
11953
12975
  status: "active" /* ACTIVE */,
11954
12976
  createdAt: now,
11955
12977
  updatedAt: now,
@@ -11960,14 +12982,27 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
11960
12982
  if (buffer.status !== "active" /* ACTIVE */) {
11961
12983
  buffer.status = "active" /* ACTIVE */;
11962
12984
  buffer.chunks$ = new ReplaySubject(this.config.maxChunks);
12985
+ buffer.chunks = [];
11963
12986
  buffer.updatedAt = Date.now();
11964
12987
  buffer.expiresAt = Date.now() + this.config.ttl;
11965
12988
  }
11966
12989
  return buffer;
11967
12990
  }
11968
- async addChunk(threadId, content) {
12991
+ async addChunk(threadId, arg2, arg3) {
11969
12992
  const buffer = this.getOrCreateBuffer(threadId);
11970
- const chunk = content;
12993
+ let chunk;
12994
+ if (typeof arg2 === "string" && arg3 !== void 0) {
12995
+ chunk = {
12996
+ type: "message_chunk",
12997
+ data: {
12998
+ id: arg2,
12999
+ content: arg3
13000
+ }
13001
+ };
13002
+ } else {
13003
+ chunk = arg2;
13004
+ }
13005
+ buffer.chunks.push(chunk);
11971
13006
  buffer.chunks$.next(chunk);
11972
13007
  buffer.updatedAt = Date.now();
11973
13008
  buffer.expiresAt = Date.now() + this.config.ttl;
@@ -11999,7 +13034,25 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
11999
13034
  async getThreadBuffer(threadId) {
12000
13035
  const buffer = this.getBufferIfValid(threadId);
12001
13036
  if (!buffer) return void 0;
12002
- return buffer;
13037
+ return {
13038
+ ...buffer,
13039
+ chunks: [...buffer.chunks]
13040
+ };
13041
+ }
13042
+ async getChunks(threadId) {
13043
+ const buffer = this.getBufferIfValid(threadId);
13044
+ if (!buffer) return [];
13045
+ return [...buffer.chunks];
13046
+ }
13047
+ async getAccumulatedContent(threadId) {
13048
+ const buffer = this.getBufferIfValid(threadId);
13049
+ if (!buffer) return "";
13050
+ return buffer.chunks.map((chunk) => chunk.data?.content || "").join("");
13051
+ }
13052
+ async getChunksByMessageId(threadId, messageId) {
13053
+ const buffer = this.getBufferIfValid(threadId);
13054
+ if (!buffer) return [];
13055
+ return buffer.chunks.filter((chunk) => chunk.data?.id === messageId);
12003
13056
  }
12004
13057
  async clearThread(threadId) {
12005
13058
  this.buffers.delete(threadId);
@@ -12129,6 +13182,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12129
13182
  let activeCount = 0;
12130
13183
  let completedCount = 0;
12131
13184
  let abortedCount = 0;
13185
+ let totalChunkCount = 0;
12132
13186
  const validBuffers = [];
12133
13187
  for (const [threadId, buffer] of this.buffers.entries()) {
12134
13188
  if (this.isExpired(buffer)) {
@@ -12149,12 +13203,14 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12149
13203
  abortedCount++;
12150
13204
  break;
12151
13205
  }
13206
+ totalChunkCount += buffer.chunks.length;
12152
13207
  }
12153
13208
  return {
12154
13209
  totalThreads: validBuffers.length,
12155
13210
  activeThreads: activeCount,
12156
13211
  completedThreads: completedCount,
12157
13212
  abortedThreads: abortedCount,
13213
+ totalChunks: totalChunkCount,
12158
13214
  config: this.config
12159
13215
  };
12160
13216
  }
@@ -12322,6 +13378,9 @@ var MemoryScheduleStorage = class {
12322
13378
  let result = [];
12323
13379
  for (const task of this.tasks.values()) {
12324
13380
  let match = true;
13381
+ if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
13382
+ match = false;
13383
+ }
12325
13384
  if (filters?.status !== void 0 && task.status !== filters.status) {
12326
13385
  match = false;
12327
13386
  }
@@ -12358,6 +13417,9 @@ var MemoryScheduleStorage = class {
12358
13417
  let count = 0;
12359
13418
  for (const task of this.tasks.values()) {
12360
13419
  let match = true;
13420
+ if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
13421
+ match = false;
13422
+ }
12361
13423
  if (filters?.status !== void 0 && task.status !== filters.status) {
12362
13424
  match = false;
12363
13425
  }
@@ -13697,6 +14759,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13697
14759
  getLatticeType() {
13698
14760
  return "skills";
13699
14761
  }
14762
+ /**
14763
+ * Default tenant ID for store operations
14764
+ * Note: SkillLatticeManager operates without explicit tenant context.
14765
+ * Store methods require tenantId for protocol compliance.
14766
+ */
14767
+ getDefaultTenantId() {
14768
+ return "default";
14769
+ }
13700
14770
  /**
13701
14771
  * Configure store for persistence
13702
14772
  * @param storeKey Store key name registered in StoreLatticeManager
@@ -13737,12 +14807,13 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13737
14807
  client.store = store;
13738
14808
  }
13739
14809
  /**
13740
- * Register a skill Lattice
14810
+ * Register a skill Lattice with tenant
14811
+ * @param tenantId Tenant ID
13741
14812
  * @param key Lattice key name
13742
14813
  * @param config Skill configuration
13743
14814
  * @param client Optional skill client implementation
13744
14815
  */
13745
- async registerLattice(key, config, client) {
14816
+ async registerLatticeWithTenant(tenantId, key, config, client) {
13746
14817
  if (!config.name) {
13747
14818
  throw new Error("Skill name is required");
13748
14819
  }
@@ -13764,10 +14835,10 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13764
14835
  config,
13765
14836
  client: client ?? null
13766
14837
  };
13767
- this.register(key, skillLattice);
14838
+ this.registerWithTenant(tenantId, key, skillLattice);
13768
14839
  if (store) {
13769
14840
  try {
13770
- await store.createSkill(key, {
14841
+ await store.createSkill(tenantId, key, {
13771
14842
  name: config.name,
13772
14843
  description: config.description,
13773
14844
  license: config.license,
@@ -13785,24 +14856,43 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13785
14856
  }
13786
14857
  }
13787
14858
  /**
13788
- * Get skill Lattice by key
14859
+ * Register a skill Lattice (backward compatible, uses "default" tenant)
14860
+ * @deprecated Use registerLatticeWithTenant(tenantId, key, config, client) instead
14861
+ * @param key Lattice key name
14862
+ * @param config Skill configuration
14863
+ * @param client Optional skill client implementation
14864
+ */
14865
+ async registerLattice(key, config, client) {
14866
+ return this.registerLatticeWithTenant(this.getDefaultTenantId(), key, config, client);
14867
+ }
14868
+ /**
14869
+ * Get skill Lattice by key with tenant
14870
+ * @param tenantId Tenant ID
14871
+ * @param key Lattice key name
14872
+ */
14873
+ getSkillLatticeWithTenant(tenantId, key) {
14874
+ return this.getWithTenant(tenantId, key);
14875
+ }
14876
+ /**
14877
+ * Get skill Lattice by key (backward compatible, uses "default" tenant)
14878
+ * @deprecated Use getSkillLatticeWithTenant(tenantId, key) instead
13789
14879
  * @param key Lattice key name
13790
14880
  */
13791
14881
  getSkillLattice(key) {
13792
- return this.get(key);
14882
+ return this.getWithTenant(this.getDefaultTenantId(), key);
13793
14883
  }
13794
14884
  /**
13795
- * Get all skill Lattices from store
13796
- * Always reads from the configured store and merges with in-memory clients
14885
+ * Get all skill Lattices from store with tenant
14886
+ * @param tenantId Tenant ID
13797
14887
  */
13798
- async getAllLattices() {
14888
+ async getAllLatticesWithTenant(tenantId) {
13799
14889
  const store = this.getStore();
13800
14890
  if (!store) {
13801
- return this.getAll();
14891
+ return this.getAllByTenant(tenantId);
13802
14892
  }
13803
- const skills = await store.getAllSkills();
14893
+ const skills = await store.getAllSkills(tenantId);
13804
14894
  return skills.map((skill) => {
13805
- const memoryLattice = this.get(skill.id);
14895
+ const memoryLattice = this.getWithTenant(tenantId, skill.id);
13806
14896
  const client = memoryLattice?.client || null;
13807
14897
  if (client && store) {
13808
14898
  this.injectStoreIntoClient(client, store);
@@ -13823,23 +14913,40 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13823
14913
  });
13824
14914
  }
13825
14915
  /**
13826
- * Check if Lattice exists
14916
+ * Get all skill Lattices from store (backward compatible, uses "default" tenant)
14917
+ * @deprecated Use getAllLatticesWithTenant(tenantId) instead
14918
+ */
14919
+ async getAllLattices() {
14920
+ return this.getAllLatticesWithTenant(this.getDefaultTenantId());
14921
+ }
14922
+ /**
14923
+ * Check if Lattice exists with tenant
14924
+ * @param tenantId Tenant ID
14925
+ * @param key Lattice key name
14926
+ */
14927
+ hasLatticeWithTenant(tenantId, key) {
14928
+ return this.hasWithTenant(tenantId, key);
14929
+ }
14930
+ /**
14931
+ * Check if Lattice exists (backward compatible, uses "default" tenant)
14932
+ * @deprecated Use hasLatticeWithTenant(tenantId, key) instead
13827
14933
  * @param key Lattice key name
13828
14934
  */
13829
14935
  hasLattice(key) {
13830
- return this.has(key);
14936
+ return this.hasWithTenant(this.getDefaultTenantId(), key);
13831
14937
  }
13832
14938
  /**
13833
- * Remove Lattice
14939
+ * Remove Lattice with tenant
14940
+ * @param tenantId Tenant ID
13834
14941
  * @param key Lattice key name
13835
14942
  */
13836
- async removeLattice(key) {
13837
- const removed = this.remove(key);
14943
+ async removeLatticeWithTenant(tenantId, key) {
14944
+ const removed = this.removeWithTenant(tenantId, key);
13838
14945
  if (removed) {
13839
14946
  const store = this.getStore();
13840
14947
  if (store) {
13841
14948
  try {
13842
- await store.deleteSkill(key);
14949
+ await store.deleteSkill(tenantId, key);
13843
14950
  } catch (error) {
13844
14951
  console.warn(
13845
14952
  `Failed to remove skill ${key} from store:`,
@@ -13850,6 +14957,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13850
14957
  }
13851
14958
  return removed;
13852
14959
  }
14960
+ /**
14961
+ * Remove Lattice (backward compatible, uses "default" tenant)
14962
+ * @deprecated Use removeLatticeWithTenant(tenantId, key) instead
14963
+ * @param key Lattice key name
14964
+ */
14965
+ async removeLattice(key) {
14966
+ return this.removeLatticeWithTenant(this.getDefaultTenantId(), key);
14967
+ }
13853
14968
  /**
13854
14969
  * Clear all Lattices
13855
14970
  */
@@ -13947,7 +15062,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13947
15062
  if (!store) {
13948
15063
  throw new Error("No store configured. Call configureStore() first.");
13949
15064
  }
13950
- const skills = await store.getAllSkills();
15065
+ const skills = await store.getAllSkills(this.getDefaultTenantId());
13951
15066
  for (const skill of skills) {
13952
15067
  const skillLattice = {
13953
15068
  key: skill.id,
@@ -13984,7 +15099,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13984
15099
  ...updates
13985
15100
  };
13986
15101
  skillLattice.config = updatedConfig;
13987
- await store.updateSkill(key, {
15102
+ await store.updateSkill(this.getDefaultTenantId(), key, {
13988
15103
  name: updatedConfig.name,
13989
15104
  description: updatedConfig.description,
13990
15105
  license: updatedConfig.license,
@@ -14208,6 +15323,7 @@ export {
14208
15323
  QueueLatticeManager,
14209
15324
  SandboxFilesystem,
14210
15325
  SandboxLatticeManager,
15326
+ SandboxSkillStore,
14211
15327
  ScheduleLatticeManager,
14212
15328
  SemanticMetricsClient,
14213
15329
  SkillLatticeManager,
@@ -14255,7 +15371,6 @@ export {
14255
15371
  formatReadResponse,
14256
15372
  getAgentClient,
14257
15373
  getAgentConfig,
14258
- getAgentLattice,
14259
15374
  getAllAgentConfigs,
14260
15375
  getAllToolDefinitions,
14261
15376
  getCheckpointSaver,
@@ -14292,6 +15407,7 @@ export {
14292
15407
  performStringReplacement,
14293
15408
  queueLatticeManager,
14294
15409
  registerAgentLattice,
15410
+ registerAgentLatticeWithTenant,
14295
15411
  registerAgentLattices,
14296
15412
  registerCheckpointSaver,
14297
15413
  registerChunkBuffer,