@axiom-lattice/core 2.1.31 → 2.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +575 -123
- package/dist/index.d.ts +575 -123
- package/dist/index.js +1530 -412
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1528 -411
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.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()}
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
*
|
|
778
|
-
|
|
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.
|
|
795
|
-
|
|
796
|
-
|
|
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
|
-
|
|
805
|
-
|
|
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.
|
|
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
|
|
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(
|
|
965
|
+
throw new Error(`No default database set for tenant '${tenantId}'`);
|
|
817
966
|
}
|
|
818
|
-
const database =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
846
|
-
if (this.
|
|
847
|
-
|
|
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
|
-
|
|
856
|
-
|
|
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
|
-
|
|
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 },
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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
|
-
},
|
|
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.
|
|
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
|
-
*
|
|
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.
|
|
1773
|
-
this.
|
|
1774
|
-
|
|
1775
|
-
|
|
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
|
-
|
|
1784
|
-
|
|
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.
|
|
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
|
|
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(
|
|
2033
|
+
throw new Error(`No default metrics server set for tenant '${tenantId}'`);
|
|
1796
2034
|
}
|
|
1797
|
-
const client =
|
|
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
|
|
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(
|
|
2053
|
+
throw new Error(`No default metrics server set for tenant '${tenantId}'`);
|
|
1811
2054
|
}
|
|
1812
|
-
const config =
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
1840
|
-
this.configs.
|
|
1841
|
-
if (
|
|
1842
|
-
|
|
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
|
-
|
|
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
|
|
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 (
|
|
1938
|
-
return
|
|
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
|
|
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 ${
|
|
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: " +
|
|
2351
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2041
2352
|
}
|
|
2042
|
-
if (!
|
|
2043
|
-
return `Error: serverKey "${serverKey}" is not
|
|
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: " +
|
|
2510
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2194
2511
|
}
|
|
2195
|
-
if (!
|
|
2196
|
-
return `Error: serverKey "${serverKey}" is not
|
|
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: " +
|
|
2939
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2617
2940
|
}
|
|
2618
|
-
if (!
|
|
2619
|
-
return `Error: serverKey "${serverKey}" is not
|
|
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: " +
|
|
3023
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2695
3024
|
}
|
|
2696
|
-
if (!
|
|
2697
|
-
return `Error: serverKey "${serverKey}" is not
|
|
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: " +
|
|
3129
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2795
3130
|
}
|
|
2796
|
-
if (!
|
|
2797
|
-
return `Error: serverKey "${serverKey}" is not
|
|
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: " +
|
|
3269
|
+
return "Error: serverKey parameter is required. Available servers: " + filteredServerKeys.join(", ");
|
|
2929
3270
|
}
|
|
2930
|
-
if (!
|
|
2931
|
-
return `Error: serverKey "${serverKey}" is not
|
|
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 ||
|
|
3289
|
+
limit: limit || 100
|
|
2949
3290
|
});
|
|
2950
|
-
|
|
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
|
|
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
|
|
5064
|
+
* Get a thread by ID for a specific tenant
|
|
4719
5065
|
*/
|
|
4720
|
-
async getThreadById(
|
|
4721
|
-
const
|
|
4722
|
-
if (!
|
|
5066
|
+
async getThreadById(tenantId, threadId) {
|
|
5067
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5068
|
+
if (!tenantThreads) {
|
|
4723
5069
|
return void 0;
|
|
4724
5070
|
}
|
|
4725
|
-
|
|
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
|
|
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(
|
|
4740
|
-
this.threads.set(
|
|
5092
|
+
if (!this.threads.has(tenantId)) {
|
|
5093
|
+
this.threads.set(tenantId, /* @__PURE__ */ new Map());
|
|
4741
5094
|
}
|
|
4742
|
-
const
|
|
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(
|
|
4750
|
-
const
|
|
4751
|
-
if (!
|
|
5106
|
+
async updateThread(tenantId, threadId, updates) {
|
|
5107
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5108
|
+
if (!tenantThreads) {
|
|
4752
5109
|
return null;
|
|
4753
5110
|
}
|
|
4754
|
-
const
|
|
4755
|
-
|
|
4756
|
-
|
|
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
|
-
|
|
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(
|
|
4773
|
-
const
|
|
4774
|
-
if (!
|
|
5131
|
+
async deleteThread(tenantId, threadId) {
|
|
5132
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5133
|
+
if (!tenantThreads) {
|
|
4775
5134
|
return false;
|
|
4776
5135
|
}
|
|
4777
|
-
|
|
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(
|
|
4783
|
-
const
|
|
4784
|
-
if (!
|
|
5146
|
+
async hasThread(tenantId, threadId) {
|
|
5147
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5148
|
+
if (!tenantThreads) {
|
|
4785
5149
|
return false;
|
|
4786
5150
|
}
|
|
4787
|
-
|
|
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
|
-
|
|
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
|
|
4801
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
6124
|
-
const
|
|
6125
|
-
|
|
6126
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
6981
|
+
* Delete a skill by ID
|
|
6133
6982
|
*/
|
|
6134
|
-
|
|
6135
|
-
|
|
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
|
|
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
|
-
|
|
6144
|
-
const
|
|
6145
|
-
return
|
|
7003
|
+
async hasSkill(tenantId, id) {
|
|
7004
|
+
const skill = await this.getSkillById(tenantId, id);
|
|
7005
|
+
return skill !== null;
|
|
6146
7006
|
}
|
|
6147
7007
|
/**
|
|
6148
|
-
*
|
|
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
|
-
|
|
6154
|
-
const
|
|
6155
|
-
return
|
|
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
|
-
*
|
|
7017
|
+
* Filter skills by compatibility within a tenant
|
|
6159
7018
|
*/
|
|
6160
|
-
|
|
6161
|
-
this.
|
|
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
|
-
*
|
|
7024
|
+
* Filter skills by license within a tenant
|
|
6165
7025
|
*/
|
|
6166
|
-
|
|
6167
|
-
|
|
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
|
|
7031
|
+
* Get sub-skills of a parent skill within a tenant
|
|
6171
7032
|
*/
|
|
6172
|
-
|
|
6173
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
7452
|
-
|
|
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
|
|
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
|
|
8331
|
-
* [assistant_id, "filesystem"]
|
|
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 (
|
|
9765
|
-
const { workspaceId, projectId } =
|
|
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
|
|
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.
|
|
11648
|
-
this.
|
|
12546
|
+
if (this.hasWithTenant(tenantId, assistantId)) {
|
|
12547
|
+
this.removeWithTenant(tenantId, assistantId);
|
|
11649
12548
|
}
|
|
11650
12549
|
const config = assistantToConfig(assistant);
|
|
11651
|
-
this.
|
|
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.
|
|
11659
|
-
this.
|
|
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.
|
|
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
|
-
|
|
11760
|
-
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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,
|
|
12991
|
+
async addChunk(threadId, arg2, arg3) {
|
|
11968
12992
|
const buffer = this.getOrCreateBuffer(threadId);
|
|
11969
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
*
|
|
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.
|
|
14882
|
+
return this.getWithTenant(this.getDefaultTenantId(), key);
|
|
13792
14883
|
}
|
|
13793
14884
|
/**
|
|
13794
|
-
* Get all skill Lattices from store
|
|
13795
|
-
*
|
|
14885
|
+
* Get all skill Lattices from store with tenant
|
|
14886
|
+
* @param tenantId Tenant ID
|
|
13796
14887
|
*/
|
|
13797
|
-
async
|
|
14888
|
+
async getAllLatticesWithTenant(tenantId) {
|
|
13798
14889
|
const store = this.getStore();
|
|
13799
14890
|
if (!store) {
|
|
13800
|
-
return this.
|
|
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.
|
|
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
|
-
*
|
|
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.
|
|
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
|
|
13836
|
-
const removed = this.
|
|
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,
|