@axiom-lattice/core 2.1.31 → 2.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.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,18 +3277,19 @@ ${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,
2947
3288
  params,
2948
- limit: limit || 1e3
3289
+ limit: limit || 100
2949
3290
  });
2950
- return JSON.stringify(result, null, 2);
3291
+ const rows = result.result?.rows || [];
3292
+ return "query_result:\n" + JSON.stringify(rows, null, 2);
2951
3293
  } catch (error) {
2952
3294
  return `Error executing SQL query: ${error instanceof Error ? error.message : String(error)}`;
2953
3295
  }
@@ -4701,104 +5043,137 @@ import { createMiddleware as createMiddleware4 } from "langchain";
4701
5043
  // src/store_lattice/InMemoryThreadStore.ts
4702
5044
  var InMemoryThreadStore = class {
4703
5045
  constructor() {
4704
- // Map<assistantId, Map<threadId, Thread>>
5046
+ // Map<tenantId, Map<assistantId, Map<threadId, Thread>>>
4705
5047
  this.threads = /* @__PURE__ */ new Map();
4706
5048
  }
4707
5049
  /**
4708
- * Get all threads for a specific assistant
5050
+ * Get all threads for a specific tenant and assistant
4709
5051
  */
4710
- async getThreadsByAssistantId(assistantId) {
4711
- 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);
4712
5058
  if (!assistantThreads) {
4713
5059
  return [];
4714
5060
  }
4715
5061
  return Array.from(assistantThreads.values());
4716
5062
  }
4717
5063
  /**
4718
- * Get a thread by ID for a specific assistant
5064
+ * Get a thread by ID for a specific tenant
4719
5065
  */
4720
- async getThreadById(assistantId, threadId) {
4721
- const assistantThreads = this.threads.get(assistantId);
4722
- if (!assistantThreads) {
5066
+ async getThreadById(tenantId, threadId) {
5067
+ const tenantThreads = this.threads.get(tenantId);
5068
+ if (!tenantThreads) {
4723
5069
  return void 0;
4724
5070
  }
4725
- 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;
4726
5078
  }
4727
5079
  /**
4728
- * Create a new thread for an assistant
5080
+ * Create a new thread for a tenant and assistant
4729
5081
  */
4730
- async createThread(assistantId, threadId, data) {
5082
+ async createThread(tenantId, assistantId, threadId, data) {
4731
5083
  const now = /* @__PURE__ */ new Date();
4732
5084
  const thread = {
4733
5085
  id: threadId,
5086
+ tenantId,
4734
5087
  assistantId,
4735
5088
  metadata: data.metadata || {},
4736
5089
  createdAt: now,
4737
5090
  updatedAt: now
4738
5091
  };
4739
- if (!this.threads.has(assistantId)) {
4740
- this.threads.set(assistantId, /* @__PURE__ */ new Map());
5092
+ if (!this.threads.has(tenantId)) {
5093
+ this.threads.set(tenantId, /* @__PURE__ */ new Map());
4741
5094
  }
4742
- const assistantThreads = this.threads.get(assistantId);
5095
+ const tenantThreads = this.threads.get(tenantId);
5096
+ if (!tenantThreads.has(assistantId)) {
5097
+ tenantThreads.set(assistantId, /* @__PURE__ */ new Map());
5098
+ }
5099
+ const assistantThreads = tenantThreads.get(assistantId);
4743
5100
  assistantThreads.set(threadId, thread);
4744
5101
  return thread;
4745
5102
  }
4746
5103
  /**
4747
5104
  * Update an existing thread
4748
5105
  */
4749
- async updateThread(assistantId, threadId, updates) {
4750
- const assistantThreads = this.threads.get(assistantId);
4751
- if (!assistantThreads) {
5106
+ async updateThread(tenantId, threadId, updates) {
5107
+ const tenantThreads = this.threads.get(tenantId);
5108
+ if (!tenantThreads) {
4752
5109
  return null;
4753
5110
  }
4754
- const existing = assistantThreads.get(threadId);
4755
- if (!existing) {
4756
- 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
+ }
4757
5125
  }
4758
- const updated = {
4759
- ...existing,
4760
- metadata: {
4761
- ...existing.metadata,
4762
- ...updates.metadata || {}
4763
- },
4764
- updatedAt: /* @__PURE__ */ new Date()
4765
- };
4766
- assistantThreads.set(threadId, updated);
4767
- return updated;
5126
+ return null;
4768
5127
  }
4769
5128
  /**
4770
5129
  * Delete a thread by ID
4771
5130
  */
4772
- async deleteThread(assistantId, threadId) {
4773
- const assistantThreads = this.threads.get(assistantId);
4774
- if (!assistantThreads) {
5131
+ async deleteThread(tenantId, threadId) {
5132
+ const tenantThreads = this.threads.get(tenantId);
5133
+ if (!tenantThreads) {
4775
5134
  return false;
4776
5135
  }
4777
- 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;
4778
5142
  }
4779
5143
  /**
4780
5144
  * Check if thread exists
4781
5145
  */
4782
- async hasThread(assistantId, threadId) {
4783
- const assistantThreads = this.threads.get(assistantId);
4784
- if (!assistantThreads) {
5146
+ async hasThread(tenantId, threadId) {
5147
+ const tenantThreads = this.threads.get(tenantId);
5148
+ if (!tenantThreads) {
4785
5149
  return false;
4786
5150
  }
4787
- return assistantThreads.has(threadId);
5151
+ for (const assistantThreads of tenantThreads.values()) {
5152
+ if (assistantThreads.has(threadId)) {
5153
+ return true;
5154
+ }
5155
+ }
5156
+ return false;
4788
5157
  }
4789
5158
  /**
4790
- * Clear all threads (useful for testing)
5159
+ * Clear all threads for a tenant (useful for testing)
4791
5160
  */
4792
- clear() {
4793
- this.threads.clear();
5161
+ clear(tenantId) {
5162
+ if (tenantId) {
5163
+ this.threads.delete(tenantId);
5164
+ } else {
5165
+ this.threads.clear();
5166
+ }
4794
5167
  }
4795
5168
  /**
4796
5169
  * Get all threads for all assistants (useful for debugging)
4797
5170
  */
4798
5171
  getAllThreads() {
4799
5172
  const allThreads = [];
4800
- for (const assistantThreads of this.threads.values()) {
4801
- 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
+ }
4802
5177
  }
4803
5178
  return allThreads;
4804
5179
  }
@@ -4810,38 +5185,50 @@ var InMemoryAssistantStore = class {
4810
5185
  this.assistants = /* @__PURE__ */ new Map();
4811
5186
  }
4812
5187
  /**
4813
- * Get all assistants
5188
+ * Get all assistants for a tenant
4814
5189
  */
4815
- async getAllAssistants() {
4816
- 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());
4817
5194
  }
4818
5195
  /**
4819
5196
  * Get assistant by ID
4820
5197
  */
4821
- async getAssistantById(id) {
4822
- 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;
4823
5202
  }
4824
5203
  /**
4825
5204
  * Create a new assistant
4826
5205
  */
4827
- 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
+ }
4828
5210
  const now = /* @__PURE__ */ new Date();
4829
5211
  const assistant = {
4830
5212
  id,
5213
+ tenantId,
4831
5214
  name: data.name,
4832
5215
  description: data.description,
4833
5216
  graphDefinition: data.graphDefinition,
4834
5217
  createdAt: now,
4835
5218
  updatedAt: now
4836
5219
  };
4837
- this.assistants.set(id, assistant);
5220
+ this.assistants.get(tenantId).set(id, assistant);
4838
5221
  return assistant;
4839
5222
  }
4840
5223
  /**
4841
5224
  * Update an existing assistant
4842
5225
  */
4843
- async updateAssistant(id, updates) {
4844
- 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);
4845
5232
  if (!existing) {
4846
5233
  return null;
4847
5234
  }
@@ -4850,26 +5237,38 @@ var InMemoryAssistantStore = class {
4850
5237
  ...updates,
4851
5238
  updatedAt: /* @__PURE__ */ new Date()
4852
5239
  };
4853
- this.assistants.set(id, updated);
5240
+ tenantAssistants.set(id, updated);
4854
5241
  return updated;
4855
5242
  }
4856
5243
  /**
4857
5244
  * Delete an assistant by ID
4858
5245
  */
4859
- async deleteAssistant(id) {
4860
- 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);
4861
5252
  }
4862
5253
  /**
4863
5254
  * Check if assistant exists
4864
5255
  */
4865
- async hasAssistant(id) {
4866
- 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);
4867
5262
  }
4868
5263
  /**
4869
- * Clear all assistants (useful for testing)
5264
+ * Clear all assistants for a tenant (useful for testing)
4870
5265
  */
4871
- clear() {
4872
- this.assistants.clear();
5266
+ clear(tenantId) {
5267
+ if (tenantId) {
5268
+ this.assistants.delete(tenantId);
5269
+ } else {
5270
+ this.assistants.clear();
5271
+ }
4873
5272
  }
4874
5273
  };
4875
5274
 
@@ -5115,6 +5514,8 @@ var FileSystemSkillStore = class {
5115
5514
  return {
5116
5515
  id: name,
5117
5516
  // id equals name (name is used for path addressing)
5517
+ tenantId: "default",
5518
+ // FileSystemSkillStore uses default tenant
5118
5519
  name: frontmatter.name,
5119
5520
  description: frontmatter.description,
5120
5521
  license: frontmatter.license,
@@ -5162,9 +5563,11 @@ ${body}` : `${frontmatter}
5162
5563
  await fs.writeFile(filePath, content, "utf-8");
5163
5564
  }
5164
5565
  /**
5165
- * 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.
5166
5569
  */
5167
- async getAllSkills() {
5570
+ async getAllSkills(_tenantId) {
5168
5571
  await this.ensureDirectoryExists();
5169
5572
  try {
5170
5573
  const entries = await fs.readdir(this.rootDir, { withFileTypes: true });
@@ -5201,17 +5604,19 @@ ${body}` : `${frontmatter}
5201
5604
  }
5202
5605
  }
5203
5606
  /**
5204
- * Get skill by ID
5607
+ * Get skill by ID for a tenant
5205
5608
  * ID should equal name (name is used for path addressing)
5609
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5206
5610
  */
5207
- async getSkillById(id) {
5611
+ async getSkillById(_tenantId, id) {
5208
5612
  return this.readSkillFile(id);
5209
5613
  }
5210
5614
  /**
5211
- * Create a new skill
5615
+ * Create a new skill for a tenant
5212
5616
  * id should equal name (name is used for path addressing)
5617
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5213
5618
  */
5214
- async createSkill(id, data) {
5619
+ async createSkill(_tenantId, id, data) {
5215
5620
  await this.ensureDirectoryExists();
5216
5621
  validateSkillName(data.name);
5217
5622
  if (id !== data.name) {
@@ -5219,14 +5624,15 @@ ${body}` : `${frontmatter}
5219
5624
  `Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
5220
5625
  );
5221
5626
  }
5222
- const existing = await this.getSkillById(id);
5627
+ const existing = await this.getSkillById(_tenantId, id);
5223
5628
  if (existing) {
5224
- return this.updateSkill(id, data);
5629
+ return this.updateSkill(_tenantId, id, data);
5225
5630
  }
5226
5631
  const now = /* @__PURE__ */ new Date();
5227
5632
  const skill = {
5228
5633
  id: data.name,
5229
5634
  // id equals name
5635
+ tenantId: _tenantId,
5230
5636
  name: data.name,
5231
5637
  description: data.description,
5232
5638
  license: data.license,
@@ -5241,9 +5647,10 @@ ${body}` : `${frontmatter}
5241
5647
  return skill;
5242
5648
  }
5243
5649
  /**
5244
- * 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
5245
5652
  */
5246
- async updateSkill(id, updates) {
5653
+ async updateSkill(_tenantId, id, updates) {
5247
5654
  const skill = await this.readSkillFile(id);
5248
5655
  if (!skill) {
5249
5656
  return null;
@@ -5267,6 +5674,7 @@ ${body}` : `${frontmatter}
5267
5674
  name: updates.name ?? skill.name,
5268
5675
  id: updates.name ?? skill.id,
5269
5676
  // id equals name
5677
+ tenantId: _tenantId,
5270
5678
  description: updates.description ?? skill.description,
5271
5679
  license: updates.license ?? skill.license,
5272
5680
  compatibility: updates.compatibility ?? skill.compatibility,
@@ -5279,10 +5687,11 @@ ${body}` : `${frontmatter}
5279
5687
  return updatedSkill;
5280
5688
  }
5281
5689
  /**
5282
- * Delete a skill by ID
5690
+ * Delete a skill by ID for a tenant
5283
5691
  * Deletes the entire directory (name is the directory name)
5692
+ * Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
5284
5693
  */
5285
- async deleteSkill(id) {
5694
+ async deleteSkill(_tenantId, id) {
5286
5695
  await this.ensureDirectoryExists();
5287
5696
  const skillDir = this.getSkillDirectoryPath(id);
5288
5697
  try {
@@ -5296,50 +5705,55 @@ ${body}` : `${frontmatter}
5296
5705
  }
5297
5706
  }
5298
5707
  /**
5299
- * 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
5300
5710
  */
5301
- async hasSkill(id) {
5302
- const skill = await this.getSkillById(id);
5711
+ async hasSkill(_tenantId, id) {
5712
+ const skill = await this.getSkillById(_tenantId, id);
5303
5713
  return skill !== null;
5304
5714
  }
5305
5715
  /**
5306
- * 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
5307
5718
  */
5308
- async searchByMetadata(metadataKey, metadataValue) {
5309
- const allSkills = await this.getAllSkills();
5719
+ async searchByMetadata(_tenantId, metadataKey, metadataValue) {
5720
+ const allSkills = await this.getAllSkills(_tenantId);
5310
5721
  return allSkills.filter((skill) => {
5311
5722
  return skill.metadata && skill.metadata[metadataKey] === metadataValue;
5312
5723
  });
5313
5724
  }
5314
5725
  /**
5315
- * 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
5316
5728
  */
5317
- async filterByCompatibility(compatibility) {
5318
- const allSkills = await this.getAllSkills();
5729
+ async filterByCompatibility(_tenantId, compatibility) {
5730
+ const allSkills = await this.getAllSkills(_tenantId);
5319
5731
  return allSkills.filter((skill) => {
5320
5732
  return skill.compatibility === compatibility;
5321
5733
  });
5322
5734
  }
5323
5735
  /**
5324
- * 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
5325
5738
  */
5326
- async filterByLicense(license) {
5327
- const allSkills = await this.getAllSkills();
5739
+ async filterByLicense(_tenantId, license) {
5740
+ const allSkills = await this.getAllSkills(_tenantId);
5328
5741
  return allSkills.filter((skill) => {
5329
5742
  return skill.license === license;
5330
5743
  });
5331
5744
  }
5332
5745
  /**
5333
- * 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
5334
5748
  */
5335
- async getSubSkills(parentSkillName) {
5336
- const parentSkill = await this.getSkillById(parentSkillName);
5749
+ async getSubSkills(_tenantId, parentSkillName) {
5750
+ const parentSkill = await this.getSkillById(_tenantId, parentSkillName);
5337
5751
  if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
5338
5752
  return [];
5339
5753
  }
5340
5754
  const subSkills = [];
5341
5755
  for (const subSkillName of parentSkill.subSkills) {
5342
- const subSkill = await this.getSkillById(subSkillName);
5756
+ const subSkill = await this.getSkillById(_tenantId, subSkillName);
5343
5757
  if (subSkill) {
5344
5758
  subSkills.push(subSkill);
5345
5759
  }
@@ -5348,10 +5762,11 @@ ${body}` : `${frontmatter}
5348
5762
  }
5349
5763
  /**
5350
5764
  * List all resources in a skill's resources directory
5765
+ * @param tenantId The tenant identifier (accepted for protocol compliance)
5351
5766
  * @param skillName The skill name
5352
5767
  * @returns Array of resource paths relative to resources/ directory
5353
5768
  */
5354
- async listSkillResources(skillName) {
5769
+ async listSkillResources(_tenantId, skillName) {
5355
5770
  const skillDir = this.getSkillDirectoryPath(skillName);
5356
5771
  const resourcesDir = path3.join(skillDir, "resources");
5357
5772
  try {
@@ -5374,11 +5789,12 @@ ${body}` : `${frontmatter}
5374
5789
  }
5375
5790
  /**
5376
5791
  * Load a specific resource from a skill's resources directory
5792
+ * @param tenantId The tenant identifier (accepted for protocol compliance)
5377
5793
  * @param skillName The skill name
5378
5794
  * @param resourcePath Path to the resource relative to resources/ directory
5379
5795
  * @returns The resource content as string
5380
5796
  */
5381
- async loadSkillResource(skillName, resourcePath) {
5797
+ async loadSkillResource(_tenantId, skillName, resourcePath) {
5382
5798
  const skillDir = this.getSkillDirectoryPath(skillName);
5383
5799
  const resourcesDir = path3.join(skillDir, "resources");
5384
5800
  const fullPath = path3.join(resourcesDir, resourcePath);
@@ -6115,93 +6531,520 @@ var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager
6115
6531
  return storeLattice;
6116
6532
  }
6117
6533
  /**
6118
- * Get StoreLattice without type checking (for backward compatibility)
6119
- * @param key Lattice key name
6120
- * @param type Store type
6121
- * @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
6122
6940
  */
6123
- getStoreLatticeUnsafe(key, type) {
6124
- const compositeKey = this.getCompositeKey(key, type);
6125
- const storeLattice = this.get(compositeKey);
6126
- if (!storeLattice) {
6127
- 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;
6128
6945
  }
6129
- 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;
6130
6979
  }
6131
6980
  /**
6132
- * Get all Lattices
6981
+ * Delete a skill by ID
6133
6982
  */
6134
- getAllLattices() {
6135
- 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
+ }
6136
6999
  }
6137
7000
  /**
6138
- * Check if Lattice exists
6139
- * Uses composite key (key + type) to check existence
6140
- * @param key Lattice key name
6141
- * @param type Store type
7001
+ * Check if skill exists
6142
7002
  */
6143
- hasLattice(key, type) {
6144
- const compositeKey = this.getCompositeKey(key, type);
6145
- return this.has(compositeKey);
7003
+ async hasSkill(tenantId, id) {
7004
+ const skill = await this.getSkillById(tenantId, id);
7005
+ return skill !== null;
6146
7006
  }
6147
7007
  /**
6148
- * Remove Lattice
6149
- * Uses composite key (key + type) to remove the store
6150
- * @param key Lattice key name
6151
- * @param type Store type
7008
+ * Search skills by metadata within a tenant
6152
7009
  */
6153
- removeLattice(key, type) {
6154
- const compositeKey = this.getCompositeKey(key, type);
6155
- 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
+ );
6156
7015
  }
6157
7016
  /**
6158
- * Clear all Lattices
7017
+ * Filter skills by compatibility within a tenant
6159
7018
  */
6160
- clearLattices() {
6161
- this.clear();
7019
+ async filterByCompatibility(tenantId, compatibility) {
7020
+ const allSkills = await this.getAllSkills(tenantId);
7021
+ return allSkills.filter((skill) => skill.compatibility === compatibility);
6162
7022
  }
6163
7023
  /**
6164
- * Get Lattice count
7024
+ * Filter skills by license within a tenant
6165
7025
  */
6166
- getLatticeCount() {
6167
- return this.count();
7026
+ async filterByLicense(tenantId, license) {
7027
+ const allSkills = await this.getAllSkills(tenantId);
7028
+ return allSkills.filter((skill) => skill.license === license);
6168
7029
  }
6169
7030
  /**
6170
- * Get Lattice key list
7031
+ * Get sub-skills of a parent skill within a tenant
6171
7032
  */
6172
- getLatticeKeys() {
6173
- 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;
6174
7046
  }
6175
7047
  };
6176
- var storeLatticeManager = StoreLatticeManager.getInstance();
6177
- var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
6178
- var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
6179
- var defaultThreadStore = new InMemoryThreadStore();
6180
- var defaultAssistantStore = new InMemoryAssistantStore();
6181
- var defaultSkillStore = new FileSystemSkillStore();
6182
- var defaultWorkspaceStore = new InMemoryWorkspaceStore();
6183
- var defaultProjectStore = new InMemoryProjectStore();
6184
- var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
6185
- var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
6186
- var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
6187
- storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
6188
- storeLatticeManager.registerLattice(
6189
- "default",
6190
- "assistant",
6191
- defaultAssistantStore
6192
- );
6193
- storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
6194
- storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
6195
- storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
6196
- storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
6197
- storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
6198
- storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
6199
- var defaultUserStore = new InMemoryUserStore();
6200
- var defaultTenantStore = new InMemoryTenantStore();
6201
- var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
6202
- storeLatticeManager.registerLattice("default", "user", defaultUserStore);
6203
- storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
6204
- storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
6205
7048
 
6206
7049
  // src/tool_lattice/skill/load_skills.ts
6207
7050
  import z40 from "zod";
@@ -6240,9 +7083,11 @@ var createLoadSkillContentTool = () => {
6240
7083
  try {
6241
7084
  const storeLattice = getStoreLattice("default", "skill");
6242
7085
  const skillStore = storeLattice.store;
6243
- 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);
6244
7089
  if (!skill) {
6245
- const allSkills = await skillStore.getAllSkills();
7090
+ const allSkills = await skillStore.getAllSkills(tenantId);
6246
7091
  const availableSkills = allSkills.map((s) => s.name).join(", ");
6247
7092
  return `Skill "${input.skill_name}" not found. Available skills: ${availableSkills}`;
6248
7093
  }
@@ -6274,7 +7119,7 @@ ${content}`;
6274
7119
  const fsStore = skillStore;
6275
7120
  if (fsStore.listSkillResources) {
6276
7121
  try {
6277
- const resources = await fsStore.listSkillResources(input.skill_name);
7122
+ const resources = await fsStore.listSkillResources(tenantId, input.skill_name);
6278
7123
  if (resources.length > 0) {
6279
7124
  result += "\n\n---\n\n**Resources** (use `load_skill_resource` tool to access):\n";
6280
7125
  resources.forEach((resource) => {
@@ -6308,7 +7153,8 @@ var createLoadSkillResourceTool = () => {
6308
7153
  return tool41(
6309
7154
  async (input, _exe_config) => {
6310
7155
  try {
6311
- const storeLattice = getStoreLattice("default", "skill");
7156
+ const tenantId = _exe_config?.configurable?.runConfig?.tenantId || "default";
7157
+ const storeLattice = getStoreLattice(tenantId, "skill");
6312
7158
  const skillStore = storeLattice.store;
6313
7159
  const fsStore = skillStore;
6314
7160
  if (!fsStore.loadSkillResource) {
@@ -6348,15 +7194,16 @@ function createSkillMiddleware(params = {}) {
6348
7194
  createLoadSkillContentTool(),
6349
7195
  createLoadSkillResourceTool()
6350
7196
  ],
6351
- beforeAgent: async () => {
7197
+ beforeAgent: async (state, runtime) => {
6352
7198
  try {
6353
7199
  const storeLattice = getStoreLattice("default", "skill");
6354
7200
  const skillStore = storeLattice?.store;
7201
+ const tenantId = runtime?.context?.tenantId || state?.tenantId || "default";
6355
7202
  if (readAll) {
6356
- latestSkills = await skillStore.getAllSkills();
7203
+ latestSkills = await skillStore.getAllSkills(tenantId);
6357
7204
  } else if (skills && skills.length > 0) {
6358
7205
  const skillLatticePromises = skills.map(
6359
- (skillId) => skillStore.getSkillById(skillId)
7206
+ (skillId) => skillStore.getSkillById(tenantId, skillId)
6360
7207
  );
6361
7208
  const skillLattices = await Promise.all(skillLatticePromises);
6362
7209
  latestSkills = skillLattices.filter((skill) => skill !== void 0);
@@ -7242,19 +8089,20 @@ ${systemPrompt}` : systemPrompt;
7242
8089
  import { createMiddleware as createMiddleware6 } from "langchain";
7243
8090
  function createMetricsMiddleware(params) {
7244
8091
  const { serverKeys, serverDescriptions, connectAll } = params;
7245
- let effectiveServerKeys = serverKeys;
7246
- if (connectAll) {
7247
- effectiveServerKeys = metricsServerManager.getServerKeys().map((s) => s.key);
7248
- }
7249
- if (!effectiveServerKeys || effectiveServerKeys.length === 0) {
8092
+ if (!serverKeys || serverKeys.length === 0) {
7250
8093
  return createMiddleware6({
7251
8094
  name: "metricsMiddleware",
7252
8095
  tools: []
7253
8096
  });
7254
8097
  }
7255
8098
  const toolParams = {
7256
- serverKeys: effectiveServerKeys,
7257
- 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
7258
8106
  };
7259
8107
  return createMiddleware6({
7260
8108
  name: "metricsMiddleware",
@@ -7387,7 +8235,7 @@ function createAskUserClarifyMiddleware() {
7387
8235
  }
7388
8236
 
7389
8237
  // src/agent_lattice/builders/commonMiddleware.ts
7390
- function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
8238
+ async function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
7391
8239
  const middlewares = [];
7392
8240
  const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
7393
8241
  if (filesystemConfig?.enabled && filesystemBackend) {
@@ -7442,14 +8290,16 @@ function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
7442
8290
 
7443
8291
  // src/agent_lattice/builders/ReActAgentGraphBuilder.ts
7444
8292
  var ReActAgentGraphBuilder = class {
7445
- createFilesystemBackendFactory(middlewareConfigs) {
8293
+ createFilesystemBackendFactory(middlewareConfigs, agentLattice) {
7446
8294
  const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
7447
8295
  if (!filesystemConfig || !filesystemConfig.enabled) {
7448
8296
  return void 0;
7449
8297
  }
7450
8298
  const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
7451
- return async (config) => {
7452
- 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;
7453
8303
  let sandboxName = "global";
7454
8304
  if (isolatedLevel === "agent") {
7455
8305
  sandboxName = "agent";
@@ -7460,14 +8310,22 @@ var ReActAgentGraphBuilder = class {
7460
8310
  if (!sandboxManager) {
7461
8311
  throw new Error("Sandbox manager not found");
7462
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
+ }
7463
8321
  return new SandboxFilesystem({
7464
8322
  sandboxInstance: await sandboxManager.createSandbox(sandboxName),
7465
- workingDirectory: workspaceId && projectId ? `/${workspaceId}/${projectId}` : "/"
8323
+ workingDirectory
7466
8324
  });
7467
8325
  };
7468
8326
  }
7469
- createMiddlewares(middlewareConfigs) {
7470
- return createCommonMiddlewares(middlewareConfigs);
8327
+ async createMiddlewares(middlewareConfigs) {
8328
+ return await createCommonMiddlewares(middlewareConfigs);
7471
8329
  }
7472
8330
  /**
7473
8331
  * 构建ReAct Agent Graph
@@ -7476,15 +8334,15 @@ var ReActAgentGraphBuilder = class {
7476
8334
  * @param params Agent构建参数
7477
8335
  * @returns 返回CompiledGraph对象
7478
8336
  */
7479
- build(agentLattice, params) {
8337
+ async build(agentLattice, params) {
7480
8338
  const tools = params.tools.map((t) => {
7481
8339
  const tool48 = getToolClient(t.key);
7482
8340
  return tool48;
7483
8341
  }).filter((tool48) => tool48 !== void 0);
7484
8342
  const stateSchema2 = createReactAgentSchema(params.stateSchema);
7485
8343
  const middlewareConfigs = params.middleware || [];
7486
- const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs);
7487
- const middlewares = createCommonMiddlewares(middlewareConfigs, filesystemBackend);
8344
+ const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs, agentLattice);
8345
+ const middlewares = await createCommonMiddlewares(middlewareConfigs, filesystemBackend);
7488
8346
  return createAgent({
7489
8347
  model: params.model,
7490
8348
  tools,
@@ -8327,14 +9185,18 @@ var StoreBackend = class {
8327
9185
  /**
8328
9186
  * Get the namespace for store operations.
8329
9187
  *
8330
- * If an assistant_id is available in stateAndStore, return
8331
- * [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"].
8332
9191
  * Otherwise return ["filesystem"].
8333
9192
  */
8334
9193
  getNamespace() {
8335
9194
  const namespace = "filesystem";
9195
+ const tenantId = this.stateAndStore.tenantId;
8336
9196
  const assistantId = this.stateAndStore.assistantId;
8337
- if (assistantId) {
9197
+ if (tenantId && assistantId) {
9198
+ return [tenantId, assistantId, namespace];
9199
+ } else if (assistantId) {
8338
9200
  return [assistantId, namespace];
8339
9201
  }
8340
9202
  return [namespace];
@@ -9761,8 +10623,8 @@ function createFilesystemBackendFactory(middlewareConfigs) {
9761
10623
  return void 0;
9762
10624
  }
9763
10625
  const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
9764
- return async (config) => {
9765
- const { workspaceId, projectId } = config;
10626
+ return async (stateAndStore) => {
10627
+ const { tenantId, workspaceId, projectId } = stateAndStore;
9766
10628
  let sandboxName = "global";
9767
10629
  if (isolatedLevel === "agent") {
9768
10630
  sandboxName = "agent";
@@ -9773,9 +10635,17 @@ function createFilesystemBackendFactory(middlewareConfigs) {
9773
10635
  if (!sandboxManager) {
9774
10636
  throw new Error("Sandbox manager not found");
9775
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
+ }
9776
10646
  return new SandboxFilesystem({
9777
10647
  sandboxInstance: await sandboxManager.createSandbox(sandboxName),
9778
- workingDirectory: workspaceId && projectId ? `/workspaces/${workspaceId}/${projectId}` : "/"
10648
+ workingDirectory
9779
10649
  });
9780
10650
  };
9781
10651
  }
@@ -9785,8 +10655,8 @@ var DeepAgentGraphBuilder = class {
9785
10655
  /**
9786
10656
  * 根据 middleware 配置创建 middlewares
9787
10657
  */
9788
- createMiddlewares(middlewareConfigs) {
9789
- return createCommonMiddlewares(middlewareConfigs);
10658
+ async createMiddlewares(middlewareConfigs) {
10659
+ return await createCommonMiddlewares(middlewareConfigs);
9790
10660
  }
9791
10661
  /**
9792
10662
  * 构建Deep Agent Graph
@@ -9795,12 +10665,12 @@ var DeepAgentGraphBuilder = class {
9795
10665
  * @param params Agent构建参数
9796
10666
  * @returns 返回CompiledGraph对象
9797
10667
  */
9798
- build(agentLattice, params) {
10668
+ async build(agentLattice, params) {
9799
10669
  const tools = params.tools.map((t) => {
9800
10670
  const toolClient = getToolClient(t.key);
9801
10671
  return toolClient;
9802
10672
  }).filter((tool48) => tool48 !== void 0);
9803
- const subagents = params.subAgents.map((sa) => {
10673
+ const subagents = await Promise.all(params.subAgents.map(async (sa) => {
9804
10674
  if (sa.client) {
9805
10675
  return {
9806
10676
  key: sa.config.key,
@@ -9809,7 +10679,7 @@ var DeepAgentGraphBuilder = class {
9809
10679
  runnable: sa.client
9810
10680
  };
9811
10681
  } else {
9812
- const subagentClient = createAgentClientFromAgentLattice({
10682
+ const subagentClient = await createAgentClientFromAgentLattice({
9813
10683
  config: sa.config
9814
10684
  });
9815
10685
  return {
@@ -9819,10 +10689,10 @@ var DeepAgentGraphBuilder = class {
9819
10689
  runnable: subagentClient
9820
10690
  };
9821
10691
  }
9822
- });
10692
+ }));
9823
10693
  const middlewareConfigs = params.middleware || [];
9824
10694
  const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
9825
- const middlewares = this.createMiddlewares(middlewareConfigs);
10695
+ const middlewares = await this.createMiddlewares(middlewareConfigs);
9826
10696
  const deepAgent = createDeepAgent({
9827
10697
  tools,
9828
10698
  model: params.model,
@@ -11398,7 +12268,7 @@ var TeamAgentGraphBuilder = class {
11398
12268
  * @param params - Build params with resolved tools and model
11399
12269
  * @returns AgentClient (the TeamLead ReactAgent)
11400
12270
  */
11401
- build(agentLattice, params) {
12271
+ async build(agentLattice, params) {
11402
12272
  const config = agentLattice.config;
11403
12273
  if (!isTeamAgentConfig(config)) {
11404
12274
  throw new Error(
@@ -11421,7 +12291,7 @@ var TeamAgentGraphBuilder = class {
11421
12291
  });
11422
12292
  const middlewareConfigs = params.middleware || [];
11423
12293
  let filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
11424
- const middlewares = createCommonMiddlewares(middlewareConfigs);
12294
+ const middlewares = await createCommonMiddlewares(middlewareConfigs);
11425
12295
  if (!filesystemBackend) {
11426
12296
  filesystemBackend = async (config2) => {
11427
12297
  return new StateBackend(config2);
@@ -11604,6 +12474,31 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11604
12474
  this.initialized = false;
11605
12475
  this.subscribeToAssistantEvents();
11606
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
+ }
11607
12502
  /**
11608
12503
  * 获取AgentLatticeManager单例实例
11609
12504
  */
@@ -11613,11 +12508,15 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11613
12508
  }
11614
12509
  return _AgentLatticeManager._instance;
11615
12510
  }
12511
+ /**
12512
+ * @deprecated This method loads assistants only for the "default" tenant.
12513
+ * Use initializeStoredAssistantsForTenant(tenantId) for proper tenant isolation.
12514
+ */
11616
12515
  async initializeStoredAssistants() {
11617
12516
  if (this.initialized) return;
11618
12517
  try {
11619
12518
  const storeLattice = getStoreLattice("default", "assistant");
11620
- const assistants = await storeLattice.store.getAllAssistants();
12519
+ const assistants = await storeLattice.store.getAllAssistants("default");
11621
12520
  for (const assistant of assistants) {
11622
12521
  if (this.has(assistant.id)) continue;
11623
12522
  const config = assistantToConfig(assistant);
@@ -11630,33 +12529,33 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11630
12529
  }
11631
12530
  subscribeToAssistantEvents() {
11632
12531
  event_bus_default.subscribe("assistant:created", (data) => {
11633
- this.handleAssistantChange(data.id);
12532
+ this.handleAssistantChange(data.id, data.tenantId ?? "default");
11634
12533
  });
11635
12534
  event_bus_default.subscribe("assistant:updated", (data) => {
11636
- this.handleAssistantChange(data.id);
12535
+ this.handleAssistantChange(data.id, data.tenantId ?? "default");
11637
12536
  });
11638
12537
  event_bus_default.subscribe("assistant:deleted", (data) => {
11639
- this.handleAssistantDelete(data.id);
12538
+ this.handleAssistantDelete(data.id, data.tenantId ?? "default");
11640
12539
  });
11641
12540
  }
11642
- async handleAssistantChange(assistantId) {
12541
+ async handleAssistantChange(assistantId, tenantId = "default") {
11643
12542
  try {
11644
12543
  const storeLattice = getStoreLattice("default", "assistant");
11645
- const assistant = await storeLattice.store.getAssistantById(assistantId);
12544
+ const assistant = await storeLattice.store.getAssistantById(tenantId, assistantId);
11646
12545
  if (assistant) {
11647
- if (this.has(assistantId)) {
11648
- this.remove(assistantId);
12546
+ if (this.hasWithTenant(tenantId, assistantId)) {
12547
+ this.removeWithTenant(tenantId, assistantId);
11649
12548
  }
11650
12549
  const config = assistantToConfig(assistant);
11651
- this.registerLattice(config);
12550
+ this.registerLatticeWithTenant(tenantId, config);
11652
12551
  }
11653
12552
  } catch (error) {
11654
- console.error(`Failed to handle assistant change for ${assistantId}:`, error);
12553
+ console.error(`Failed to handle assistant change for ${assistantId} (tenant: ${tenantId}):`, error);
11655
12554
  }
11656
12555
  }
11657
- handleAssistantDelete(assistantId) {
11658
- if (this.has(assistantId)) {
11659
- this.remove(assistantId);
12556
+ handleAssistantDelete(assistantId, tenantId = "default") {
12557
+ if (this.hasWithTenant(tenantId, assistantId)) {
12558
+ this.removeWithTenant(tenantId, assistantId);
11660
12559
  }
11661
12560
  }
11662
12561
  /**
@@ -11665,8 +12564,96 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11665
12564
  getLatticeType() {
11666
12565
  return "agents";
11667
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 租户) ==========
11668
12654
  /**
11669
- * 注册Agent Lattice
12655
+ * 注册Agent Lattice(向后兼容,使用 "default" 租户)
12656
+ * @deprecated Use registerLatticeWithTenant(tenantId, config) instead
11670
12657
  * @param config Agent配置
11671
12658
  */
11672
12659
  registerLattice(config) {
@@ -11704,7 +12691,8 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11704
12691
  return this.remove(key);
11705
12692
  }
11706
12693
  /**
11707
- * 获取AgentLattice
12694
+ * 获取AgentLattice(向后兼容,使用 "default" 租户)
12695
+ * @deprecated Use getAgentLatticeWithTenant(tenantId, key) instead
11708
12696
  * @param key Lattice键名
11709
12697
  */
11710
12698
  getAgentLattice(key) {
@@ -11717,25 +12705,28 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11717
12705
  return this.getAll();
11718
12706
  }
11719
12707
  /**
11720
- * 检查Lattice是否存在
12708
+ * 检查Lattice是否存在(向后兼容,使用 "default" 租户)
12709
+ * @deprecated Use hasAgentLatticeWithTenant(tenantId, key) instead
11721
12710
  * @param key Lattice键名
11722
12711
  */
11723
12712
  hasLattice(key) {
11724
12713
  return this.has(key);
11725
12714
  }
11726
12715
  /**
11727
- * 移除Lattice
12716
+ * 移除Lattice(向后兼容,使用 "default" 租户)
12717
+ * @deprecated Use removeAgentLatticeWithTenant(tenantId, key) instead
11728
12718
  * @param key Lattice键名
11729
12719
  */
11730
12720
  removeLattice(key) {
11731
12721
  return this.remove(key);
11732
12722
  }
11733
12723
  /**
11734
- * 获取Agent配置
12724
+ * 获取Agent配置(向后兼容,使用 "default" 租户)
12725
+ * @deprecated Use getAgentConfigWithTenant(tenantId, key) instead
11735
12726
  * @param key Lattice键名
11736
12727
  */
11737
12728
  getAgentConfig(key) {
11738
- return this.getAgentLattice(key)?.config;
12729
+ return this.getAgentLatticeWithTenant("default", key)?.config;
11739
12730
  }
11740
12731
  /**
11741
12732
  * 获取所有Agent配置
@@ -11756,8 +12747,9 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11756
12747
  return false;
11757
12748
  }
11758
12749
  try {
11759
- if (agentLattice.config.schema) {
11760
- agentLattice.config.schema.parse(input);
12750
+ const config = agentLattice.config;
12751
+ if ("schema" in config && config.schema) {
12752
+ config.schema.parse(input);
11761
12753
  }
11762
12754
  return true;
11763
12755
  } catch {
@@ -11805,9 +12797,10 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11805
12797
  * @returns 返回Agent构建参数
11806
12798
  */
11807
12799
  buildAgentParams(agentLattice, options) {
12800
+ const tenantId = agentLattice.config.tenantId || "default";
11808
12801
  const paramsBuilder = new AgentParamsBuilder((key) => {
11809
- this.initializeClient(key);
11810
- return this.getAgentLattice(key);
12802
+ this.initializeClient(tenantId, key);
12803
+ return this.getAgentLatticeWithTenant(tenantId, key);
11811
12804
  });
11812
12805
  return paramsBuilder.buildParams(agentLattice, options);
11813
12806
  }
@@ -11818,7 +12811,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11818
12811
  * @param options Build options
11819
12812
  * @returns AgentClient instance
11820
12813
  */
11821
- createAgentClientFromConfig(agentLattice, options) {
12814
+ async createAgentClientFromConfig(agentLattice, options) {
11822
12815
  const resolvedConfig = this.resolveInheritedConfig(agentLattice.config);
11823
12816
  const resolvedLattice = {
11824
12817
  ...agentLattice,
@@ -11827,26 +12820,50 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
11827
12820
  const factory = AgentGraphBuilderFactory.getInstance();
11828
12821
  const builder = factory.getBuilder(resolvedConfig.type);
11829
12822
  const params = this.buildAgentParams(resolvedLattice, options);
11830
- return builder.build(resolvedLattice, params);
12823
+ return await builder.build(resolvedLattice, params);
11831
12824
  }
11832
12825
  /**
11833
12826
  * 初始化Agent客户端
11834
12827
  *
11835
12828
  * 使用AgentGraphBuilderFactory构建Graph并设置为客户端
11836
12829
  *
12830
+ * @param tenantId 租户ID
11837
12831
  * @param key Lattice键名
11838
12832
  * @param options 构建选项
11839
12833
  * @returns 返回CompiledGraph对象
11840
12834
  */
11841
- initializeClient(key, options) {
11842
- 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);
11843
12860
  if (!agentLattice) {
11844
- throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728`);
12861
+ throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
11845
12862
  }
11846
12863
  if (agentLattice.client) {
11847
12864
  return agentLattice.client;
11848
12865
  }
11849
- const graph = this.createAgentClientFromConfig(agentLattice, options);
12866
+ const graph = await this.createAgentClientFromConfig(agentLattice, options);
11850
12867
  agentLattice.client = graph;
11851
12868
  return graph;
11852
12869
  }
@@ -11855,19 +12872,24 @@ var agentLatticeManager = AgentLatticeManager.getInstance();
11855
12872
  var registerAgentLattice = (config) => {
11856
12873
  agentLatticeManager.registerLattice(config);
11857
12874
  };
11858
- 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
+ }
11859
12882
  configs.forEach((config) => {
11860
- agentLatticeManager.registerLattice(config);
12883
+ agentLatticeManager.registerLatticeWithTenant(tenantId, config);
11861
12884
  });
11862
12885
  };
11863
- var getAgentLattice = (key) => agentLatticeManager.getAgentLattice(key);
11864
12886
  var getAgentConfig = (key) => agentLatticeManager.getAgentConfig(key);
11865
12887
  var getAllAgentConfigs = () => agentLatticeManager.getAllAgentConfigs();
11866
12888
  var validateAgentInput = (key, input) => agentLatticeManager.validateAgentInput(key, input);
11867
12889
  var registerTeammateAgent = (key, client) => agentLatticeManager.registerTeammateAgent(key, client);
11868
12890
  var unregisterTeammateAgent = (key) => agentLatticeManager.unregisterTeammateAgent(key);
11869
- var getAgentClient = (key, options) => agentLatticeManager.initializeClient(key, options);
11870
- 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);
11871
12893
 
11872
12894
  // src/chunk_buffer_lattice/ChunkBuffer.ts
11873
12895
  var ChunkBuffer = class {
@@ -11949,6 +12971,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
11949
12971
  buffer = {
11950
12972
  threadId,
11951
12973
  chunks$: new ReplaySubject(this.config.maxChunks),
12974
+ chunks: [],
11952
12975
  status: "active" /* ACTIVE */,
11953
12976
  createdAt: now,
11954
12977
  updatedAt: now,
@@ -11959,14 +12982,27 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
11959
12982
  if (buffer.status !== "active" /* ACTIVE */) {
11960
12983
  buffer.status = "active" /* ACTIVE */;
11961
12984
  buffer.chunks$ = new ReplaySubject(this.config.maxChunks);
12985
+ buffer.chunks = [];
11962
12986
  buffer.updatedAt = Date.now();
11963
12987
  buffer.expiresAt = Date.now() + this.config.ttl;
11964
12988
  }
11965
12989
  return buffer;
11966
12990
  }
11967
- async addChunk(threadId, content) {
12991
+ async addChunk(threadId, arg2, arg3) {
11968
12992
  const buffer = this.getOrCreateBuffer(threadId);
11969
- 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);
11970
13006
  buffer.chunks$.next(chunk);
11971
13007
  buffer.updatedAt = Date.now();
11972
13008
  buffer.expiresAt = Date.now() + this.config.ttl;
@@ -11998,7 +13034,25 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
11998
13034
  async getThreadBuffer(threadId) {
11999
13035
  const buffer = this.getBufferIfValid(threadId);
12000
13036
  if (!buffer) return void 0;
12001
- 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);
12002
13056
  }
12003
13057
  async clearThread(threadId) {
12004
13058
  this.buffers.delete(threadId);
@@ -12128,6 +13182,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12128
13182
  let activeCount = 0;
12129
13183
  let completedCount = 0;
12130
13184
  let abortedCount = 0;
13185
+ let totalChunkCount = 0;
12131
13186
  const validBuffers = [];
12132
13187
  for (const [threadId, buffer] of this.buffers.entries()) {
12133
13188
  if (this.isExpired(buffer)) {
@@ -12148,12 +13203,14 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
12148
13203
  abortedCount++;
12149
13204
  break;
12150
13205
  }
13206
+ totalChunkCount += buffer.chunks.length;
12151
13207
  }
12152
13208
  return {
12153
13209
  totalThreads: validBuffers.length,
12154
13210
  activeThreads: activeCount,
12155
13211
  completedThreads: completedCount,
12156
13212
  abortedThreads: abortedCount,
13213
+ totalChunks: totalChunkCount,
12157
13214
  config: this.config
12158
13215
  };
12159
13216
  }
@@ -12321,6 +13378,9 @@ var MemoryScheduleStorage = class {
12321
13378
  let result = [];
12322
13379
  for (const task of this.tasks.values()) {
12323
13380
  let match = true;
13381
+ if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
13382
+ match = false;
13383
+ }
12324
13384
  if (filters?.status !== void 0 && task.status !== filters.status) {
12325
13385
  match = false;
12326
13386
  }
@@ -12357,6 +13417,9 @@ var MemoryScheduleStorage = class {
12357
13417
  let count = 0;
12358
13418
  for (const task of this.tasks.values()) {
12359
13419
  let match = true;
13420
+ if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
13421
+ match = false;
13422
+ }
12360
13423
  if (filters?.status !== void 0 && task.status !== filters.status) {
12361
13424
  match = false;
12362
13425
  }
@@ -13696,6 +14759,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13696
14759
  getLatticeType() {
13697
14760
  return "skills";
13698
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
+ }
13699
14770
  /**
13700
14771
  * Configure store for persistence
13701
14772
  * @param storeKey Store key name registered in StoreLatticeManager
@@ -13736,12 +14807,13 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13736
14807
  client.store = store;
13737
14808
  }
13738
14809
  /**
13739
- * Register a skill Lattice
14810
+ * Register a skill Lattice with tenant
14811
+ * @param tenantId Tenant ID
13740
14812
  * @param key Lattice key name
13741
14813
  * @param config Skill configuration
13742
14814
  * @param client Optional skill client implementation
13743
14815
  */
13744
- async registerLattice(key, config, client) {
14816
+ async registerLatticeWithTenant(tenantId, key, config, client) {
13745
14817
  if (!config.name) {
13746
14818
  throw new Error("Skill name is required");
13747
14819
  }
@@ -13763,10 +14835,10 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13763
14835
  config,
13764
14836
  client: client ?? null
13765
14837
  };
13766
- this.register(key, skillLattice);
14838
+ this.registerWithTenant(tenantId, key, skillLattice);
13767
14839
  if (store) {
13768
14840
  try {
13769
- await store.createSkill(key, {
14841
+ await store.createSkill(tenantId, key, {
13770
14842
  name: config.name,
13771
14843
  description: config.description,
13772
14844
  license: config.license,
@@ -13784,24 +14856,43 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13784
14856
  }
13785
14857
  }
13786
14858
  /**
13787
- * 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
13788
14879
  * @param key Lattice key name
13789
14880
  */
13790
14881
  getSkillLattice(key) {
13791
- return this.get(key);
14882
+ return this.getWithTenant(this.getDefaultTenantId(), key);
13792
14883
  }
13793
14884
  /**
13794
- * Get all skill Lattices from store
13795
- * 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
13796
14887
  */
13797
- async getAllLattices() {
14888
+ async getAllLatticesWithTenant(tenantId) {
13798
14889
  const store = this.getStore();
13799
14890
  if (!store) {
13800
- return this.getAll();
14891
+ return this.getAllByTenant(tenantId);
13801
14892
  }
13802
- const skills = await store.getAllSkills();
14893
+ const skills = await store.getAllSkills(tenantId);
13803
14894
  return skills.map((skill) => {
13804
- const memoryLattice = this.get(skill.id);
14895
+ const memoryLattice = this.getWithTenant(tenantId, skill.id);
13805
14896
  const client = memoryLattice?.client || null;
13806
14897
  if (client && store) {
13807
14898
  this.injectStoreIntoClient(client, store);
@@ -13822,23 +14913,40 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13822
14913
  });
13823
14914
  }
13824
14915
  /**
13825
- * 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
13826
14933
  * @param key Lattice key name
13827
14934
  */
13828
14935
  hasLattice(key) {
13829
- return this.has(key);
14936
+ return this.hasWithTenant(this.getDefaultTenantId(), key);
13830
14937
  }
13831
14938
  /**
13832
- * Remove Lattice
14939
+ * Remove Lattice with tenant
14940
+ * @param tenantId Tenant ID
13833
14941
  * @param key Lattice key name
13834
14942
  */
13835
- async removeLattice(key) {
13836
- const removed = this.remove(key);
14943
+ async removeLatticeWithTenant(tenantId, key) {
14944
+ const removed = this.removeWithTenant(tenantId, key);
13837
14945
  if (removed) {
13838
14946
  const store = this.getStore();
13839
14947
  if (store) {
13840
14948
  try {
13841
- await store.deleteSkill(key);
14949
+ await store.deleteSkill(tenantId, key);
13842
14950
  } catch (error) {
13843
14951
  console.warn(
13844
14952
  `Failed to remove skill ${key} from store:`,
@@ -13849,6 +14957,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13849
14957
  }
13850
14958
  return removed;
13851
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
+ }
13852
14968
  /**
13853
14969
  * Clear all Lattices
13854
14970
  */
@@ -13946,7 +15062,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13946
15062
  if (!store) {
13947
15063
  throw new Error("No store configured. Call configureStore() first.");
13948
15064
  }
13949
- const skills = await store.getAllSkills();
15065
+ const skills = await store.getAllSkills(this.getDefaultTenantId());
13950
15066
  for (const skill of skills) {
13951
15067
  const skillLattice = {
13952
15068
  key: skill.id,
@@ -13983,7 +15099,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
13983
15099
  ...updates
13984
15100
  };
13985
15101
  skillLattice.config = updatedConfig;
13986
- await store.updateSkill(key, {
15102
+ await store.updateSkill(this.getDefaultTenantId(), key, {
13987
15103
  name: updatedConfig.name,
13988
15104
  description: updatedConfig.description,
13989
15105
  license: updatedConfig.license,
@@ -14207,6 +15323,7 @@ export {
14207
15323
  QueueLatticeManager,
14208
15324
  SandboxFilesystem,
14209
15325
  SandboxLatticeManager,
15326
+ SandboxSkillStore,
14210
15327
  ScheduleLatticeManager,
14211
15328
  SemanticMetricsClient,
14212
15329
  SkillLatticeManager,
@@ -14254,7 +15371,6 @@ export {
14254
15371
  formatReadResponse,
14255
15372
  getAgentClient,
14256
15373
  getAgentConfig,
14257
- getAgentLattice,
14258
15374
  getAllAgentConfigs,
14259
15375
  getAllToolDefinitions,
14260
15376
  getCheckpointSaver,
@@ -14291,6 +15407,7 @@ export {
14291
15407
  performStringReplacement,
14292
15408
  queueLatticeManager,
14293
15409
  registerAgentLattice,
15410
+ registerAgentLatticeWithTenant,
14294
15411
  registerAgentLattices,
14295
15412
  registerCheckpointSaver,
14296
15413
  registerChunkBuffer,