@axiom-lattice/core 2.1.32 → 2.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +575 -123
- package/dist/index.d.ts +575 -123
- package/dist/index.js +1527 -410
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1525 -409
- 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,11 +3277,11 @@ ${serverKeys.map(
|
|
|
2936
3277
|
if (!customSql || customSql.trim().length === 0) {
|
|
2937
3278
|
return "Error: customSql parameter is required and cannot be empty.";
|
|
2938
3279
|
}
|
|
2939
|
-
const config = metricsServerManager.getConfig(serverKey);
|
|
3280
|
+
const config = metricsServerManager.getConfig(tenantId, serverKey);
|
|
2940
3281
|
if (config.type !== "semantic") {
|
|
2941
3282
|
return `Error: Server "${serverKey}" is not a semantic metrics server. This tool only works with semantic servers.`;
|
|
2942
3283
|
}
|
|
2943
|
-
const client = metricsServerManager.getClient(serverKey);
|
|
3284
|
+
const client = metricsServerManager.getClient(tenantId, serverKey);
|
|
2944
3285
|
const result = await client.executeSqlQuery({
|
|
2945
3286
|
datasourceId,
|
|
2946
3287
|
customSql,
|
|
@@ -4702,104 +5043,137 @@ import { createMiddleware as createMiddleware4 } from "langchain";
|
|
|
4702
5043
|
// src/store_lattice/InMemoryThreadStore.ts
|
|
4703
5044
|
var InMemoryThreadStore = class {
|
|
4704
5045
|
constructor() {
|
|
4705
|
-
// Map<assistantId, Map<threadId, Thread
|
|
5046
|
+
// Map<tenantId, Map<assistantId, Map<threadId, Thread>>>
|
|
4706
5047
|
this.threads = /* @__PURE__ */ new Map();
|
|
4707
5048
|
}
|
|
4708
5049
|
/**
|
|
4709
|
-
* Get all threads for a specific assistant
|
|
5050
|
+
* Get all threads for a specific tenant and assistant
|
|
4710
5051
|
*/
|
|
4711
|
-
async getThreadsByAssistantId(assistantId) {
|
|
4712
|
-
const
|
|
5052
|
+
async getThreadsByAssistantId(tenantId, assistantId) {
|
|
5053
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5054
|
+
if (!tenantThreads) {
|
|
5055
|
+
return [];
|
|
5056
|
+
}
|
|
5057
|
+
const assistantThreads = tenantThreads.get(assistantId);
|
|
4713
5058
|
if (!assistantThreads) {
|
|
4714
5059
|
return [];
|
|
4715
5060
|
}
|
|
4716
5061
|
return Array.from(assistantThreads.values());
|
|
4717
5062
|
}
|
|
4718
5063
|
/**
|
|
4719
|
-
* Get a thread by ID for a specific
|
|
5064
|
+
* Get a thread by ID for a specific tenant
|
|
4720
5065
|
*/
|
|
4721
|
-
async getThreadById(
|
|
4722
|
-
const
|
|
4723
|
-
if (!
|
|
5066
|
+
async getThreadById(tenantId, threadId) {
|
|
5067
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5068
|
+
if (!tenantThreads) {
|
|
4724
5069
|
return void 0;
|
|
4725
5070
|
}
|
|
4726
|
-
|
|
5071
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5072
|
+
const thread = assistantThreads.get(threadId);
|
|
5073
|
+
if (thread) {
|
|
5074
|
+
return thread;
|
|
5075
|
+
}
|
|
5076
|
+
}
|
|
5077
|
+
return void 0;
|
|
4727
5078
|
}
|
|
4728
5079
|
/**
|
|
4729
|
-
* Create a new thread for
|
|
5080
|
+
* Create a new thread for a tenant and assistant
|
|
4730
5081
|
*/
|
|
4731
|
-
async createThread(assistantId, threadId, data) {
|
|
5082
|
+
async createThread(tenantId, assistantId, threadId, data) {
|
|
4732
5083
|
const now = /* @__PURE__ */ new Date();
|
|
4733
5084
|
const thread = {
|
|
4734
5085
|
id: threadId,
|
|
5086
|
+
tenantId,
|
|
4735
5087
|
assistantId,
|
|
4736
5088
|
metadata: data.metadata || {},
|
|
4737
5089
|
createdAt: now,
|
|
4738
5090
|
updatedAt: now
|
|
4739
5091
|
};
|
|
4740
|
-
if (!this.threads.has(
|
|
4741
|
-
this.threads.set(
|
|
5092
|
+
if (!this.threads.has(tenantId)) {
|
|
5093
|
+
this.threads.set(tenantId, /* @__PURE__ */ new Map());
|
|
5094
|
+
}
|
|
5095
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5096
|
+
if (!tenantThreads.has(assistantId)) {
|
|
5097
|
+
tenantThreads.set(assistantId, /* @__PURE__ */ new Map());
|
|
4742
5098
|
}
|
|
4743
|
-
const assistantThreads =
|
|
5099
|
+
const assistantThreads = tenantThreads.get(assistantId);
|
|
4744
5100
|
assistantThreads.set(threadId, thread);
|
|
4745
5101
|
return thread;
|
|
4746
5102
|
}
|
|
4747
5103
|
/**
|
|
4748
5104
|
* Update an existing thread
|
|
4749
5105
|
*/
|
|
4750
|
-
async updateThread(
|
|
4751
|
-
const
|
|
4752
|
-
if (!
|
|
5106
|
+
async updateThread(tenantId, threadId, updates) {
|
|
5107
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5108
|
+
if (!tenantThreads) {
|
|
4753
5109
|
return null;
|
|
4754
5110
|
}
|
|
4755
|
-
const
|
|
4756
|
-
|
|
4757
|
-
|
|
5111
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5112
|
+
const existing = assistantThreads.get(threadId);
|
|
5113
|
+
if (existing) {
|
|
5114
|
+
const updated = {
|
|
5115
|
+
...existing,
|
|
5116
|
+
metadata: {
|
|
5117
|
+
...existing.metadata,
|
|
5118
|
+
...updates.metadata || {}
|
|
5119
|
+
},
|
|
5120
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
5121
|
+
};
|
|
5122
|
+
assistantThreads.set(threadId, updated);
|
|
5123
|
+
return updated;
|
|
5124
|
+
}
|
|
4758
5125
|
}
|
|
4759
|
-
|
|
4760
|
-
...existing,
|
|
4761
|
-
metadata: {
|
|
4762
|
-
...existing.metadata,
|
|
4763
|
-
...updates.metadata || {}
|
|
4764
|
-
},
|
|
4765
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
4766
|
-
};
|
|
4767
|
-
assistantThreads.set(threadId, updated);
|
|
4768
|
-
return updated;
|
|
5126
|
+
return null;
|
|
4769
5127
|
}
|
|
4770
5128
|
/**
|
|
4771
5129
|
* Delete a thread by ID
|
|
4772
5130
|
*/
|
|
4773
|
-
async deleteThread(
|
|
4774
|
-
const
|
|
4775
|
-
if (!
|
|
5131
|
+
async deleteThread(tenantId, threadId) {
|
|
5132
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5133
|
+
if (!tenantThreads) {
|
|
4776
5134
|
return false;
|
|
4777
5135
|
}
|
|
4778
|
-
|
|
5136
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5137
|
+
if (assistantThreads.has(threadId)) {
|
|
5138
|
+
return assistantThreads.delete(threadId);
|
|
5139
|
+
}
|
|
5140
|
+
}
|
|
5141
|
+
return false;
|
|
4779
5142
|
}
|
|
4780
5143
|
/**
|
|
4781
5144
|
* Check if thread exists
|
|
4782
5145
|
*/
|
|
4783
|
-
async hasThread(
|
|
4784
|
-
const
|
|
4785
|
-
if (!
|
|
5146
|
+
async hasThread(tenantId, threadId) {
|
|
5147
|
+
const tenantThreads = this.threads.get(tenantId);
|
|
5148
|
+
if (!tenantThreads) {
|
|
4786
5149
|
return false;
|
|
4787
5150
|
}
|
|
4788
|
-
|
|
5151
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5152
|
+
if (assistantThreads.has(threadId)) {
|
|
5153
|
+
return true;
|
|
5154
|
+
}
|
|
5155
|
+
}
|
|
5156
|
+
return false;
|
|
4789
5157
|
}
|
|
4790
5158
|
/**
|
|
4791
|
-
* Clear all threads (useful for testing)
|
|
5159
|
+
* Clear all threads for a tenant (useful for testing)
|
|
4792
5160
|
*/
|
|
4793
|
-
clear() {
|
|
4794
|
-
|
|
5161
|
+
clear(tenantId) {
|
|
5162
|
+
if (tenantId) {
|
|
5163
|
+
this.threads.delete(tenantId);
|
|
5164
|
+
} else {
|
|
5165
|
+
this.threads.clear();
|
|
5166
|
+
}
|
|
4795
5167
|
}
|
|
4796
5168
|
/**
|
|
4797
5169
|
* Get all threads for all assistants (useful for debugging)
|
|
4798
5170
|
*/
|
|
4799
5171
|
getAllThreads() {
|
|
4800
5172
|
const allThreads = [];
|
|
4801
|
-
for (const
|
|
4802
|
-
|
|
5173
|
+
for (const tenantThreads of this.threads.values()) {
|
|
5174
|
+
for (const assistantThreads of tenantThreads.values()) {
|
|
5175
|
+
allThreads.push(...Array.from(assistantThreads.values()));
|
|
5176
|
+
}
|
|
4803
5177
|
}
|
|
4804
5178
|
return allThreads;
|
|
4805
5179
|
}
|
|
@@ -4811,38 +5185,50 @@ var InMemoryAssistantStore = class {
|
|
|
4811
5185
|
this.assistants = /* @__PURE__ */ new Map();
|
|
4812
5186
|
}
|
|
4813
5187
|
/**
|
|
4814
|
-
* Get all assistants
|
|
5188
|
+
* Get all assistants for a tenant
|
|
4815
5189
|
*/
|
|
4816
|
-
async getAllAssistants() {
|
|
4817
|
-
|
|
5190
|
+
async getAllAssistants(tenantId) {
|
|
5191
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5192
|
+
if (!tenantAssistants) return [];
|
|
5193
|
+
return Array.from(tenantAssistants.values());
|
|
4818
5194
|
}
|
|
4819
5195
|
/**
|
|
4820
5196
|
* Get assistant by ID
|
|
4821
5197
|
*/
|
|
4822
|
-
async getAssistantById(id) {
|
|
4823
|
-
|
|
5198
|
+
async getAssistantById(tenantId, id) {
|
|
5199
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5200
|
+
if (!tenantAssistants) return null;
|
|
5201
|
+
return tenantAssistants.get(id) || null;
|
|
4824
5202
|
}
|
|
4825
5203
|
/**
|
|
4826
5204
|
* Create a new assistant
|
|
4827
5205
|
*/
|
|
4828
|
-
async createAssistant(id, data) {
|
|
5206
|
+
async createAssistant(tenantId, id, data) {
|
|
5207
|
+
if (!this.assistants.has(tenantId)) {
|
|
5208
|
+
this.assistants.set(tenantId, /* @__PURE__ */ new Map());
|
|
5209
|
+
}
|
|
4829
5210
|
const now = /* @__PURE__ */ new Date();
|
|
4830
5211
|
const assistant = {
|
|
4831
5212
|
id,
|
|
5213
|
+
tenantId,
|
|
4832
5214
|
name: data.name,
|
|
4833
5215
|
description: data.description,
|
|
4834
5216
|
graphDefinition: data.graphDefinition,
|
|
4835
5217
|
createdAt: now,
|
|
4836
5218
|
updatedAt: now
|
|
4837
5219
|
};
|
|
4838
|
-
this.assistants.set(id, assistant);
|
|
5220
|
+
this.assistants.get(tenantId).set(id, assistant);
|
|
4839
5221
|
return assistant;
|
|
4840
5222
|
}
|
|
4841
5223
|
/**
|
|
4842
5224
|
* Update an existing assistant
|
|
4843
5225
|
*/
|
|
4844
|
-
async updateAssistant(id, updates) {
|
|
4845
|
-
const
|
|
5226
|
+
async updateAssistant(tenantId, id, updates) {
|
|
5227
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5228
|
+
if (!tenantAssistants) {
|
|
5229
|
+
return null;
|
|
5230
|
+
}
|
|
5231
|
+
const existing = tenantAssistants.get(id);
|
|
4846
5232
|
if (!existing) {
|
|
4847
5233
|
return null;
|
|
4848
5234
|
}
|
|
@@ -4851,26 +5237,38 @@ var InMemoryAssistantStore = class {
|
|
|
4851
5237
|
...updates,
|
|
4852
5238
|
updatedAt: /* @__PURE__ */ new Date()
|
|
4853
5239
|
};
|
|
4854
|
-
|
|
5240
|
+
tenantAssistants.set(id, updated);
|
|
4855
5241
|
return updated;
|
|
4856
5242
|
}
|
|
4857
5243
|
/**
|
|
4858
5244
|
* Delete an assistant by ID
|
|
4859
5245
|
*/
|
|
4860
|
-
async deleteAssistant(id) {
|
|
4861
|
-
|
|
5246
|
+
async deleteAssistant(tenantId, id) {
|
|
5247
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5248
|
+
if (!tenantAssistants) {
|
|
5249
|
+
return false;
|
|
5250
|
+
}
|
|
5251
|
+
return tenantAssistants.delete(id);
|
|
4862
5252
|
}
|
|
4863
5253
|
/**
|
|
4864
5254
|
* Check if assistant exists
|
|
4865
5255
|
*/
|
|
4866
|
-
async hasAssistant(id) {
|
|
4867
|
-
|
|
5256
|
+
async hasAssistant(tenantId, id) {
|
|
5257
|
+
const tenantAssistants = this.assistants.get(tenantId);
|
|
5258
|
+
if (!tenantAssistants) {
|
|
5259
|
+
return false;
|
|
5260
|
+
}
|
|
5261
|
+
return tenantAssistants.has(id);
|
|
4868
5262
|
}
|
|
4869
5263
|
/**
|
|
4870
|
-
* Clear all assistants (useful for testing)
|
|
5264
|
+
* Clear all assistants for a tenant (useful for testing)
|
|
4871
5265
|
*/
|
|
4872
|
-
clear() {
|
|
4873
|
-
|
|
5266
|
+
clear(tenantId) {
|
|
5267
|
+
if (tenantId) {
|
|
5268
|
+
this.assistants.delete(tenantId);
|
|
5269
|
+
} else {
|
|
5270
|
+
this.assistants.clear();
|
|
5271
|
+
}
|
|
4874
5272
|
}
|
|
4875
5273
|
};
|
|
4876
5274
|
|
|
@@ -5116,6 +5514,8 @@ var FileSystemSkillStore = class {
|
|
|
5116
5514
|
return {
|
|
5117
5515
|
id: name,
|
|
5118
5516
|
// id equals name (name is used for path addressing)
|
|
5517
|
+
tenantId: "default",
|
|
5518
|
+
// FileSystemSkillStore uses default tenant
|
|
5119
5519
|
name: frontmatter.name,
|
|
5120
5520
|
description: frontmatter.description,
|
|
5121
5521
|
license: frontmatter.license,
|
|
@@ -5163,9 +5563,11 @@ ${body}` : `${frontmatter}
|
|
|
5163
5563
|
await fs.writeFile(filePath, content, "utf-8");
|
|
5164
5564
|
}
|
|
5165
5565
|
/**
|
|
5166
|
-
* Get all skills
|
|
5566
|
+
* Get all skills for a tenant
|
|
5567
|
+
* Note: FileSystemSkillStore uses a flat structure. TenantId is accepted for protocol compliance
|
|
5568
|
+
* but all skills are returned regardless of tenant.
|
|
5167
5569
|
*/
|
|
5168
|
-
async getAllSkills() {
|
|
5570
|
+
async getAllSkills(_tenantId) {
|
|
5169
5571
|
await this.ensureDirectoryExists();
|
|
5170
5572
|
try {
|
|
5171
5573
|
const entries = await fs.readdir(this.rootDir, { withFileTypes: true });
|
|
@@ -5202,17 +5604,19 @@ ${body}` : `${frontmatter}
|
|
|
5202
5604
|
}
|
|
5203
5605
|
}
|
|
5204
5606
|
/**
|
|
5205
|
-
* Get skill by ID
|
|
5607
|
+
* Get skill by ID for a tenant
|
|
5206
5608
|
* ID should equal name (name is used for path addressing)
|
|
5609
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5207
5610
|
*/
|
|
5208
|
-
async getSkillById(id) {
|
|
5611
|
+
async getSkillById(_tenantId, id) {
|
|
5209
5612
|
return this.readSkillFile(id);
|
|
5210
5613
|
}
|
|
5211
5614
|
/**
|
|
5212
|
-
* Create a new skill
|
|
5615
|
+
* Create a new skill for a tenant
|
|
5213
5616
|
* id should equal name (name is used for path addressing)
|
|
5617
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5214
5618
|
*/
|
|
5215
|
-
async createSkill(id, data) {
|
|
5619
|
+
async createSkill(_tenantId, id, data) {
|
|
5216
5620
|
await this.ensureDirectoryExists();
|
|
5217
5621
|
validateSkillName(data.name);
|
|
5218
5622
|
if (id !== data.name) {
|
|
@@ -5220,14 +5624,15 @@ ${body}` : `${frontmatter}
|
|
|
5220
5624
|
`Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
|
|
5221
5625
|
);
|
|
5222
5626
|
}
|
|
5223
|
-
const existing = await this.getSkillById(id);
|
|
5627
|
+
const existing = await this.getSkillById(_tenantId, id);
|
|
5224
5628
|
if (existing) {
|
|
5225
|
-
return this.updateSkill(id, data);
|
|
5629
|
+
return this.updateSkill(_tenantId, id, data);
|
|
5226
5630
|
}
|
|
5227
5631
|
const now = /* @__PURE__ */ new Date();
|
|
5228
5632
|
const skill = {
|
|
5229
5633
|
id: data.name,
|
|
5230
5634
|
// id equals name
|
|
5635
|
+
tenantId: _tenantId,
|
|
5231
5636
|
name: data.name,
|
|
5232
5637
|
description: data.description,
|
|
5233
5638
|
license: data.license,
|
|
@@ -5242,9 +5647,10 @@ ${body}` : `${frontmatter}
|
|
|
5242
5647
|
return skill;
|
|
5243
5648
|
}
|
|
5244
5649
|
/**
|
|
5245
|
-
* Update an existing skill
|
|
5650
|
+
* Update an existing skill for a tenant
|
|
5651
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5246
5652
|
*/
|
|
5247
|
-
async updateSkill(id, updates) {
|
|
5653
|
+
async updateSkill(_tenantId, id, updates) {
|
|
5248
5654
|
const skill = await this.readSkillFile(id);
|
|
5249
5655
|
if (!skill) {
|
|
5250
5656
|
return null;
|
|
@@ -5268,6 +5674,7 @@ ${body}` : `${frontmatter}
|
|
|
5268
5674
|
name: updates.name ?? skill.name,
|
|
5269
5675
|
id: updates.name ?? skill.id,
|
|
5270
5676
|
// id equals name
|
|
5677
|
+
tenantId: _tenantId,
|
|
5271
5678
|
description: updates.description ?? skill.description,
|
|
5272
5679
|
license: updates.license ?? skill.license,
|
|
5273
5680
|
compatibility: updates.compatibility ?? skill.compatibility,
|
|
@@ -5280,10 +5687,11 @@ ${body}` : `${frontmatter}
|
|
|
5280
5687
|
return updatedSkill;
|
|
5281
5688
|
}
|
|
5282
5689
|
/**
|
|
5283
|
-
* Delete a skill by ID
|
|
5690
|
+
* Delete a skill by ID for a tenant
|
|
5284
5691
|
* Deletes the entire directory (name is the directory name)
|
|
5692
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5285
5693
|
*/
|
|
5286
|
-
async deleteSkill(id) {
|
|
5694
|
+
async deleteSkill(_tenantId, id) {
|
|
5287
5695
|
await this.ensureDirectoryExists();
|
|
5288
5696
|
const skillDir = this.getSkillDirectoryPath(id);
|
|
5289
5697
|
try {
|
|
@@ -5297,50 +5705,55 @@ ${body}` : `${frontmatter}
|
|
|
5297
5705
|
}
|
|
5298
5706
|
}
|
|
5299
5707
|
/**
|
|
5300
|
-
* Check if skill exists
|
|
5708
|
+
* Check if skill exists for a tenant
|
|
5709
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5301
5710
|
*/
|
|
5302
|
-
async hasSkill(id) {
|
|
5303
|
-
const skill = await this.getSkillById(id);
|
|
5711
|
+
async hasSkill(_tenantId, id) {
|
|
5712
|
+
const skill = await this.getSkillById(_tenantId, id);
|
|
5304
5713
|
return skill !== null;
|
|
5305
5714
|
}
|
|
5306
5715
|
/**
|
|
5307
|
-
* Search skills by metadata
|
|
5716
|
+
* Search skills by metadata within a tenant
|
|
5717
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5308
5718
|
*/
|
|
5309
|
-
async searchByMetadata(metadataKey, metadataValue) {
|
|
5310
|
-
const allSkills = await this.getAllSkills();
|
|
5719
|
+
async searchByMetadata(_tenantId, metadataKey, metadataValue) {
|
|
5720
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5311
5721
|
return allSkills.filter((skill) => {
|
|
5312
5722
|
return skill.metadata && skill.metadata[metadataKey] === metadataValue;
|
|
5313
5723
|
});
|
|
5314
5724
|
}
|
|
5315
5725
|
/**
|
|
5316
|
-
* Filter skills by compatibility
|
|
5726
|
+
* Filter skills by compatibility within a tenant
|
|
5727
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5317
5728
|
*/
|
|
5318
|
-
async filterByCompatibility(compatibility) {
|
|
5319
|
-
const allSkills = await this.getAllSkills();
|
|
5729
|
+
async filterByCompatibility(_tenantId, compatibility) {
|
|
5730
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5320
5731
|
return allSkills.filter((skill) => {
|
|
5321
5732
|
return skill.compatibility === compatibility;
|
|
5322
5733
|
});
|
|
5323
5734
|
}
|
|
5324
5735
|
/**
|
|
5325
|
-
* Filter skills by license
|
|
5736
|
+
* Filter skills by license within a tenant
|
|
5737
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5326
5738
|
*/
|
|
5327
|
-
async filterByLicense(license) {
|
|
5328
|
-
const allSkills = await this.getAllSkills();
|
|
5739
|
+
async filterByLicense(_tenantId, license) {
|
|
5740
|
+
const allSkills = await this.getAllSkills(_tenantId);
|
|
5329
5741
|
return allSkills.filter((skill) => {
|
|
5330
5742
|
return skill.license === license;
|
|
5331
5743
|
});
|
|
5332
5744
|
}
|
|
5333
5745
|
/**
|
|
5334
|
-
* Get sub-skills of a parent skill
|
|
5746
|
+
* Get sub-skills of a parent skill within a tenant
|
|
5747
|
+
* Note: tenantId is accepted for protocol compliance but FileSystemSkillStore uses flat structure
|
|
5335
5748
|
*/
|
|
5336
|
-
async getSubSkills(parentSkillName) {
|
|
5337
|
-
const parentSkill = await this.getSkillById(parentSkillName);
|
|
5749
|
+
async getSubSkills(_tenantId, parentSkillName) {
|
|
5750
|
+
const parentSkill = await this.getSkillById(_tenantId, parentSkillName);
|
|
5338
5751
|
if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
|
|
5339
5752
|
return [];
|
|
5340
5753
|
}
|
|
5341
5754
|
const subSkills = [];
|
|
5342
5755
|
for (const subSkillName of parentSkill.subSkills) {
|
|
5343
|
-
const subSkill = await this.getSkillById(subSkillName);
|
|
5756
|
+
const subSkill = await this.getSkillById(_tenantId, subSkillName);
|
|
5344
5757
|
if (subSkill) {
|
|
5345
5758
|
subSkills.push(subSkill);
|
|
5346
5759
|
}
|
|
@@ -5349,10 +5762,11 @@ ${body}` : `${frontmatter}
|
|
|
5349
5762
|
}
|
|
5350
5763
|
/**
|
|
5351
5764
|
* List all resources in a skill's resources directory
|
|
5765
|
+
* @param tenantId The tenant identifier (accepted for protocol compliance)
|
|
5352
5766
|
* @param skillName The skill name
|
|
5353
5767
|
* @returns Array of resource paths relative to resources/ directory
|
|
5354
5768
|
*/
|
|
5355
|
-
async listSkillResources(skillName) {
|
|
5769
|
+
async listSkillResources(_tenantId, skillName) {
|
|
5356
5770
|
const skillDir = this.getSkillDirectoryPath(skillName);
|
|
5357
5771
|
const resourcesDir = path3.join(skillDir, "resources");
|
|
5358
5772
|
try {
|
|
@@ -5375,11 +5789,12 @@ ${body}` : `${frontmatter}
|
|
|
5375
5789
|
}
|
|
5376
5790
|
/**
|
|
5377
5791
|
* Load a specific resource from a skill's resources directory
|
|
5792
|
+
* @param tenantId The tenant identifier (accepted for protocol compliance)
|
|
5378
5793
|
* @param skillName The skill name
|
|
5379
5794
|
* @param resourcePath Path to the resource relative to resources/ directory
|
|
5380
5795
|
* @returns The resource content as string
|
|
5381
5796
|
*/
|
|
5382
|
-
async loadSkillResource(skillName, resourcePath) {
|
|
5797
|
+
async loadSkillResource(_tenantId, skillName, resourcePath) {
|
|
5383
5798
|
const skillDir = this.getSkillDirectoryPath(skillName);
|
|
5384
5799
|
const resourcesDir = path3.join(skillDir, "resources");
|
|
5385
5800
|
const fullPath = path3.join(resourcesDir, resourcePath);
|
|
@@ -6116,93 +6531,520 @@ var StoreLatticeManager = class _StoreLatticeManager extends BaseLatticeManager
|
|
|
6116
6531
|
return storeLattice;
|
|
6117
6532
|
}
|
|
6118
6533
|
/**
|
|
6119
|
-
* Get StoreLattice without type checking (for backward compatibility)
|
|
6120
|
-
* @param key Lattice key name
|
|
6121
|
-
* @param type Store type
|
|
6122
|
-
* @returns StoreLattice (type may be unknown)
|
|
6534
|
+
* Get StoreLattice without type checking (for backward compatibility)
|
|
6535
|
+
* @param key Lattice key name
|
|
6536
|
+
* @param type Store type
|
|
6537
|
+
* @returns StoreLattice (type may be unknown)
|
|
6538
|
+
*/
|
|
6539
|
+
getStoreLatticeUnsafe(key, type) {
|
|
6540
|
+
const compositeKey = this.getCompositeKey(key, type);
|
|
6541
|
+
const storeLattice = this.get(compositeKey);
|
|
6542
|
+
if (!storeLattice) {
|
|
6543
|
+
throw new Error(`StoreLattice ${key}:${type} not found`);
|
|
6544
|
+
}
|
|
6545
|
+
return storeLattice;
|
|
6546
|
+
}
|
|
6547
|
+
/**
|
|
6548
|
+
* Get all Lattices
|
|
6549
|
+
*/
|
|
6550
|
+
getAllLattices() {
|
|
6551
|
+
return this.getAll();
|
|
6552
|
+
}
|
|
6553
|
+
/**
|
|
6554
|
+
* Check if Lattice exists
|
|
6555
|
+
* Uses composite key (key + type) to check existence
|
|
6556
|
+
* @param key Lattice key name
|
|
6557
|
+
* @param type Store type
|
|
6558
|
+
*/
|
|
6559
|
+
hasLattice(key, type) {
|
|
6560
|
+
const compositeKey = this.getCompositeKey(key, type);
|
|
6561
|
+
return this.has(compositeKey);
|
|
6562
|
+
}
|
|
6563
|
+
/**
|
|
6564
|
+
* Remove Lattice
|
|
6565
|
+
* Uses composite key (key + type) to remove the store
|
|
6566
|
+
* @param key Lattice key name
|
|
6567
|
+
* @param type Store type
|
|
6568
|
+
*/
|
|
6569
|
+
removeLattice(key, type) {
|
|
6570
|
+
const compositeKey = this.getCompositeKey(key, type);
|
|
6571
|
+
return this.remove(compositeKey);
|
|
6572
|
+
}
|
|
6573
|
+
/**
|
|
6574
|
+
* Clear all Lattices
|
|
6575
|
+
*/
|
|
6576
|
+
clearLattices() {
|
|
6577
|
+
this.clear();
|
|
6578
|
+
}
|
|
6579
|
+
/**
|
|
6580
|
+
* Get Lattice count
|
|
6581
|
+
*/
|
|
6582
|
+
getLatticeCount() {
|
|
6583
|
+
return this.count();
|
|
6584
|
+
}
|
|
6585
|
+
/**
|
|
6586
|
+
* Get Lattice key list
|
|
6587
|
+
*/
|
|
6588
|
+
getLatticeKeys() {
|
|
6589
|
+
return this.keys();
|
|
6590
|
+
}
|
|
6591
|
+
};
|
|
6592
|
+
var storeLatticeManager = StoreLatticeManager.getInstance();
|
|
6593
|
+
var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
|
|
6594
|
+
var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
|
|
6595
|
+
var defaultThreadStore = new InMemoryThreadStore();
|
|
6596
|
+
var defaultAssistantStore = new InMemoryAssistantStore();
|
|
6597
|
+
var defaultSkillStore = new FileSystemSkillStore();
|
|
6598
|
+
var defaultWorkspaceStore = new InMemoryWorkspaceStore();
|
|
6599
|
+
var defaultProjectStore = new InMemoryProjectStore();
|
|
6600
|
+
var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
|
|
6601
|
+
var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
|
|
6602
|
+
var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
|
|
6603
|
+
storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
|
|
6604
|
+
storeLatticeManager.registerLattice(
|
|
6605
|
+
"default",
|
|
6606
|
+
"assistant",
|
|
6607
|
+
defaultAssistantStore
|
|
6608
|
+
);
|
|
6609
|
+
storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
|
|
6610
|
+
storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
|
|
6611
|
+
storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
|
|
6612
|
+
storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
|
|
6613
|
+
storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
|
|
6614
|
+
storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
|
|
6615
|
+
var defaultUserStore = new InMemoryUserStore();
|
|
6616
|
+
var defaultTenantStore = new InMemoryTenantStore();
|
|
6617
|
+
var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
|
|
6618
|
+
storeLatticeManager.registerLattice("default", "user", defaultUserStore);
|
|
6619
|
+
storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
|
|
6620
|
+
storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
|
|
6621
|
+
|
|
6622
|
+
// src/store_lattice/SandboxSkillStore.ts
|
|
6623
|
+
function parseFrontmatter2(content) {
|
|
6624
|
+
const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n?([\s\S]*)$/;
|
|
6625
|
+
const match = content.match(frontmatterRegex);
|
|
6626
|
+
if (!match) {
|
|
6627
|
+
return { frontmatter: {}, body: content };
|
|
6628
|
+
}
|
|
6629
|
+
const frontmatterText = match[1];
|
|
6630
|
+
const body = match[2] || "";
|
|
6631
|
+
const frontmatter = {};
|
|
6632
|
+
const lines = frontmatterText.split("\n");
|
|
6633
|
+
let currentKey = null;
|
|
6634
|
+
let metadataIndent = 0;
|
|
6635
|
+
for (let i = 0; i < lines.length; i++) {
|
|
6636
|
+
const line = lines[i];
|
|
6637
|
+
const trimmed = line.trim();
|
|
6638
|
+
if (!trimmed || trimmed.startsWith("#")) {
|
|
6639
|
+
continue;
|
|
6640
|
+
}
|
|
6641
|
+
const indentMatch = line.match(/^(\s*)/);
|
|
6642
|
+
const indent = indentMatch ? indentMatch[1].length : 0;
|
|
6643
|
+
if (currentKey === "metadata" && indent > metadataIndent) {
|
|
6644
|
+
const colonIndex2 = trimmed.indexOf(":");
|
|
6645
|
+
if (colonIndex2 !== -1) {
|
|
6646
|
+
const key2 = trimmed.substring(0, colonIndex2).trim();
|
|
6647
|
+
let value2 = trimmed.substring(colonIndex2 + 1).trim();
|
|
6648
|
+
if (value2.startsWith('"') && value2.endsWith('"') || value2.startsWith("'") && value2.endsWith("'")) {
|
|
6649
|
+
value2 = value2.slice(1, -1);
|
|
6650
|
+
}
|
|
6651
|
+
if (!frontmatter.metadata) {
|
|
6652
|
+
frontmatter.metadata = {};
|
|
6653
|
+
}
|
|
6654
|
+
frontmatter.metadata[key2] = value2;
|
|
6655
|
+
}
|
|
6656
|
+
continue;
|
|
6657
|
+
}
|
|
6658
|
+
if (currentKey === "subSkills" && indent > metadataIndent) {
|
|
6659
|
+
if (trimmed.startsWith("-")) {
|
|
6660
|
+
let value2 = trimmed.substring(1).trim();
|
|
6661
|
+
if (value2.startsWith('"') && value2.endsWith('"') || value2.startsWith("'") && value2.endsWith("'")) {
|
|
6662
|
+
value2 = value2.slice(1, -1);
|
|
6663
|
+
}
|
|
6664
|
+
if (!frontmatter.subSkills) {
|
|
6665
|
+
frontmatter.subSkills = [];
|
|
6666
|
+
}
|
|
6667
|
+
frontmatter.subSkills.push(value2);
|
|
6668
|
+
}
|
|
6669
|
+
continue;
|
|
6670
|
+
}
|
|
6671
|
+
if ((currentKey === "metadata" || currentKey === "subSkills") && indent <= metadataIndent) {
|
|
6672
|
+
currentKey = null;
|
|
6673
|
+
metadataIndent = 0;
|
|
6674
|
+
}
|
|
6675
|
+
const colonIndex = trimmed.indexOf(":");
|
|
6676
|
+
if (colonIndex === -1) {
|
|
6677
|
+
continue;
|
|
6678
|
+
}
|
|
6679
|
+
const key = trimmed.substring(0, colonIndex).trim();
|
|
6680
|
+
let value = trimmed.substring(colonIndex + 1).trim();
|
|
6681
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
6682
|
+
value = value.slice(1, -1);
|
|
6683
|
+
}
|
|
6684
|
+
if (key === "metadata") {
|
|
6685
|
+
if (value === "" || value === "{}") {
|
|
6686
|
+
if (i + 1 < lines.length) {
|
|
6687
|
+
const nextLine = lines[i + 1];
|
|
6688
|
+
const nextIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;
|
|
6689
|
+
if (nextIndent > indent) {
|
|
6690
|
+
currentKey = "metadata";
|
|
6691
|
+
metadataIndent = indent;
|
|
6692
|
+
frontmatter.metadata = {};
|
|
6693
|
+
continue;
|
|
6694
|
+
}
|
|
6695
|
+
}
|
|
6696
|
+
frontmatter[key] = {};
|
|
6697
|
+
} else if (value.startsWith("{")) {
|
|
6698
|
+
try {
|
|
6699
|
+
frontmatter[key] = JSON.parse(value);
|
|
6700
|
+
} catch {
|
|
6701
|
+
frontmatter[key] = {};
|
|
6702
|
+
}
|
|
6703
|
+
} else {
|
|
6704
|
+
frontmatter[key] = {};
|
|
6705
|
+
}
|
|
6706
|
+
} else if (key === "subSkills") {
|
|
6707
|
+
if (value === "" || value === "[]") {
|
|
6708
|
+
if (i + 1 < lines.length) {
|
|
6709
|
+
const nextLine = lines[i + 1];
|
|
6710
|
+
const nextIndent = nextLine.match(/^(\s*)/)?.[1].length || 0;
|
|
6711
|
+
if (nextIndent > indent && nextLine.trim().startsWith("-")) {
|
|
6712
|
+
currentKey = "subSkills";
|
|
6713
|
+
metadataIndent = indent;
|
|
6714
|
+
frontmatter.subSkills = [];
|
|
6715
|
+
continue;
|
|
6716
|
+
}
|
|
6717
|
+
}
|
|
6718
|
+
frontmatter[key] = [];
|
|
6719
|
+
} else if (value.startsWith("[")) {
|
|
6720
|
+
try {
|
|
6721
|
+
frontmatter[key] = JSON.parse(value);
|
|
6722
|
+
} catch {
|
|
6723
|
+
frontmatter[key] = [];
|
|
6724
|
+
}
|
|
6725
|
+
} else {
|
|
6726
|
+
frontmatter[key] = [];
|
|
6727
|
+
}
|
|
6728
|
+
} else {
|
|
6729
|
+
frontmatter[key] = value;
|
|
6730
|
+
}
|
|
6731
|
+
}
|
|
6732
|
+
return { frontmatter, body };
|
|
6733
|
+
}
|
|
6734
|
+
function generateFrontmatter2(data) {
|
|
6735
|
+
const lines = ["---"];
|
|
6736
|
+
lines.push(`name: ${data.name}`);
|
|
6737
|
+
lines.push(`description: ${data.description}`);
|
|
6738
|
+
if (data.license) {
|
|
6739
|
+
lines.push(`license: ${data.license}`);
|
|
6740
|
+
}
|
|
6741
|
+
if (data.compatibility) {
|
|
6742
|
+
lines.push(`compatibility: ${data.compatibility}`);
|
|
6743
|
+
}
|
|
6744
|
+
if (data.metadata && Object.keys(data.metadata).length > 0) {
|
|
6745
|
+
lines.push("metadata:");
|
|
6746
|
+
for (const [key, value] of Object.entries(data.metadata)) {
|
|
6747
|
+
lines.push(` ${key}: ${value}`);
|
|
6748
|
+
}
|
|
6749
|
+
}
|
|
6750
|
+
if (data.subSkills && data.subSkills.length > 0) {
|
|
6751
|
+
lines.push("subSkills:");
|
|
6752
|
+
for (const subSkill of data.subSkills) {
|
|
6753
|
+
lines.push(` - ${subSkill}`);
|
|
6754
|
+
}
|
|
6755
|
+
}
|
|
6756
|
+
lines.push("---");
|
|
6757
|
+
return lines.join("\n");
|
|
6758
|
+
}
|
|
6759
|
+
var SandboxSkillStore = class {
|
|
6760
|
+
constructor(options = {}) {
|
|
6761
|
+
this.sandboxManager = options.sandboxManager;
|
|
6762
|
+
this.basePath = options.basePath || "/home/gem/tenants";
|
|
6763
|
+
}
|
|
6764
|
+
/**
|
|
6765
|
+
* Get sandbox manager for a tenant
|
|
6766
|
+
*/
|
|
6767
|
+
async getSandboxManager() {
|
|
6768
|
+
if (this.sandboxManager) {
|
|
6769
|
+
return this.sandboxManager;
|
|
6770
|
+
}
|
|
6771
|
+
return getSandBoxManager();
|
|
6772
|
+
}
|
|
6773
|
+
/**
|
|
6774
|
+
* Get skill directory path in sandbox
|
|
6775
|
+
*/
|
|
6776
|
+
getSkillDirectoryPath(tenantId, name) {
|
|
6777
|
+
if (name.includes("..") || name.includes("/") || name.includes("\\")) {
|
|
6778
|
+
throw new Error(`Invalid skill name: ${name} (contains invalid characters)`);
|
|
6779
|
+
}
|
|
6780
|
+
return `${this.basePath}/${tenantId}/skills/${name}`;
|
|
6781
|
+
}
|
|
6782
|
+
/**
|
|
6783
|
+
* Get skill file path in sandbox
|
|
6784
|
+
*/
|
|
6785
|
+
getSkillFilePath(tenantId, name) {
|
|
6786
|
+
return `${this.getSkillDirectoryPath(tenantId, name)}/SKILL.md`;
|
|
6787
|
+
}
|
|
6788
|
+
/**
|
|
6789
|
+
* Read skill from sandbox
|
|
6790
|
+
*/
|
|
6791
|
+
async readSkillFile(tenantId, name) {
|
|
6792
|
+
try {
|
|
6793
|
+
const sandboxManager = await this.getSandboxManager();
|
|
6794
|
+
const sandbox = await sandboxManager.createSandbox("global");
|
|
6795
|
+
const filePath = this.getSkillFilePath(tenantId, name);
|
|
6796
|
+
const result = await sandbox.file.readFile({ file: filePath });
|
|
6797
|
+
if (!result.ok) {
|
|
6798
|
+
return null;
|
|
6799
|
+
}
|
|
6800
|
+
let content;
|
|
6801
|
+
if (typeof result.body === "string") {
|
|
6802
|
+
content = result.body;
|
|
6803
|
+
} else if (result.body && typeof result.body === "object") {
|
|
6804
|
+
const body = result.body;
|
|
6805
|
+
content = body.content || body.data?.content || JSON.stringify(body);
|
|
6806
|
+
} else {
|
|
6807
|
+
content = String(result.body);
|
|
6808
|
+
}
|
|
6809
|
+
const { frontmatter, body: skillBody } = parseFrontmatter2(content);
|
|
6810
|
+
if (!frontmatter.name || !frontmatter.description) {
|
|
6811
|
+
console.warn(`Invalid skill file ${name}: missing required fields`);
|
|
6812
|
+
return null;
|
|
6813
|
+
}
|
|
6814
|
+
return {
|
|
6815
|
+
id: name,
|
|
6816
|
+
tenantId,
|
|
6817
|
+
name: frontmatter.name,
|
|
6818
|
+
description: frontmatter.description,
|
|
6819
|
+
license: frontmatter.license,
|
|
6820
|
+
compatibility: frontmatter.compatibility,
|
|
6821
|
+
metadata: frontmatter.metadata || {},
|
|
6822
|
+
content: skillBody.trim() || void 0,
|
|
6823
|
+
subSkills: Array.isArray(frontmatter.subSkills) ? frontmatter.subSkills : void 0,
|
|
6824
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
6825
|
+
// Sandbox doesn't provide file stats easily
|
|
6826
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
6827
|
+
};
|
|
6828
|
+
} catch (error) {
|
|
6829
|
+
console.error(`Error reading skill ${name} from sandbox:`, error);
|
|
6830
|
+
return null;
|
|
6831
|
+
}
|
|
6832
|
+
}
|
|
6833
|
+
/**
|
|
6834
|
+
* Write skill to sandbox
|
|
6835
|
+
*/
|
|
6836
|
+
async writeSkillFile(skill) {
|
|
6837
|
+
const sandboxManager = await this.getSandboxManager();
|
|
6838
|
+
const sandbox = await sandboxManager.createSandbox("global");
|
|
6839
|
+
const filePath = this.getSkillFilePath(skill.tenantId, skill.name);
|
|
6840
|
+
const frontmatter = generateFrontmatter2({
|
|
6841
|
+
name: skill.name,
|
|
6842
|
+
description: skill.description,
|
|
6843
|
+
license: skill.license,
|
|
6844
|
+
compatibility: skill.compatibility,
|
|
6845
|
+
metadata: skill.metadata,
|
|
6846
|
+
subSkills: skill.subSkills
|
|
6847
|
+
});
|
|
6848
|
+
const body = skill.content || "";
|
|
6849
|
+
const content = body ? `${frontmatter}
|
|
6850
|
+
${body}` : `${frontmatter}
|
|
6851
|
+
`;
|
|
6852
|
+
const result = await sandbox.file.writeFile({
|
|
6853
|
+
file: filePath,
|
|
6854
|
+
content,
|
|
6855
|
+
encoding: "utf-8",
|
|
6856
|
+
append: false
|
|
6857
|
+
});
|
|
6858
|
+
if (!result.ok) {
|
|
6859
|
+
throw new Error(`Failed to write skill to sandbox: ${JSON.stringify(result.error)}`);
|
|
6860
|
+
}
|
|
6861
|
+
}
|
|
6862
|
+
/**
|
|
6863
|
+
* Get all skills for a tenant
|
|
6864
|
+
*/
|
|
6865
|
+
async getAllSkills(tenantId) {
|
|
6866
|
+
try {
|
|
6867
|
+
const sandboxManager = await this.getSandboxManager();
|
|
6868
|
+
const sandbox = await sandboxManager.createSandbox("global");
|
|
6869
|
+
const skillsDir = `${this.basePath}/${tenantId}/skills`;
|
|
6870
|
+
const result = await sandbox.file.listPath({
|
|
6871
|
+
path: skillsDir,
|
|
6872
|
+
recursive: false,
|
|
6873
|
+
show_hidden: false
|
|
6874
|
+
});
|
|
6875
|
+
if (!result.ok || !result.body) {
|
|
6876
|
+
return [];
|
|
6877
|
+
}
|
|
6878
|
+
const files = result.body?.data?.files || [];
|
|
6879
|
+
const skills = [];
|
|
6880
|
+
for (const entry of files) {
|
|
6881
|
+
if (entry.is_directory) {
|
|
6882
|
+
const pathParts = entry.path.split("/");
|
|
6883
|
+
const skillName = pathParts[pathParts.length - 1];
|
|
6884
|
+
if (!skillName) continue;
|
|
6885
|
+
try {
|
|
6886
|
+
const skill = await this.readSkillFile(tenantId, skillName);
|
|
6887
|
+
if (skill) {
|
|
6888
|
+
skills.push(skill);
|
|
6889
|
+
}
|
|
6890
|
+
} catch (error) {
|
|
6891
|
+
console.error(`Error loading skill "${skillName}":`, error);
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
}
|
|
6895
|
+
return skills.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
6896
|
+
} catch (error) {
|
|
6897
|
+
console.error(`Error listing skills for tenant ${tenantId}:`, error);
|
|
6898
|
+
return [];
|
|
6899
|
+
}
|
|
6900
|
+
}
|
|
6901
|
+
/**
|
|
6902
|
+
* Get skill by ID
|
|
6903
|
+
*/
|
|
6904
|
+
async getSkillById(tenantId, id) {
|
|
6905
|
+
return this.readSkillFile(tenantId, id);
|
|
6906
|
+
}
|
|
6907
|
+
/**
|
|
6908
|
+
* Create a new skill
|
|
6909
|
+
*/
|
|
6910
|
+
async createSkill(tenantId, id, data) {
|
|
6911
|
+
validateSkillName(data.name);
|
|
6912
|
+
if (id !== data.name) {
|
|
6913
|
+
throw new Error(
|
|
6914
|
+
`Skill id "${id}" must equal name "${data.name}" (name is used for path addressing)`
|
|
6915
|
+
);
|
|
6916
|
+
}
|
|
6917
|
+
const existing = await this.getSkillById(tenantId, id);
|
|
6918
|
+
if (existing) {
|
|
6919
|
+
return this.updateSkill(tenantId, id, data);
|
|
6920
|
+
}
|
|
6921
|
+
const now = /* @__PURE__ */ new Date();
|
|
6922
|
+
const skill = {
|
|
6923
|
+
id: data.name,
|
|
6924
|
+
tenantId,
|
|
6925
|
+
name: data.name,
|
|
6926
|
+
description: data.description,
|
|
6927
|
+
license: data.license,
|
|
6928
|
+
compatibility: data.compatibility,
|
|
6929
|
+
metadata: data.metadata || {},
|
|
6930
|
+
content: data.content,
|
|
6931
|
+
subSkills: data.subSkills,
|
|
6932
|
+
createdAt: now,
|
|
6933
|
+
updatedAt: now
|
|
6934
|
+
};
|
|
6935
|
+
await this.writeSkillFile(skill);
|
|
6936
|
+
return skill;
|
|
6937
|
+
}
|
|
6938
|
+
/**
|
|
6939
|
+
* Update an existing skill
|
|
6123
6940
|
*/
|
|
6124
|
-
|
|
6125
|
-
const
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
throw new Error(`StoreLattice ${key}:${type} not found`);
|
|
6941
|
+
async updateSkill(tenantId, id, updates) {
|
|
6942
|
+
const skill = await this.readSkillFile(tenantId, id);
|
|
6943
|
+
if (!skill) {
|
|
6944
|
+
return null;
|
|
6129
6945
|
}
|
|
6130
|
-
|
|
6946
|
+
if (updates.name !== void 0) {
|
|
6947
|
+
validateSkillName(updates.name);
|
|
6948
|
+
if (updates.name !== skill.name) {
|
|
6949
|
+
const newSkill = {
|
|
6950
|
+
...skill,
|
|
6951
|
+
name: updates.name,
|
|
6952
|
+
id: updates.name,
|
|
6953
|
+
description: updates.description ?? skill.description,
|
|
6954
|
+
license: updates.license ?? skill.license,
|
|
6955
|
+
compatibility: updates.compatibility ?? skill.compatibility,
|
|
6956
|
+
metadata: updates.metadata ?? skill.metadata,
|
|
6957
|
+
content: updates.content !== void 0 ? updates.content : skill.content,
|
|
6958
|
+
subSkills: updates.subSkills !== void 0 ? updates.subSkills : skill.subSkills,
|
|
6959
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
6960
|
+
};
|
|
6961
|
+
await this.writeSkillFile(newSkill);
|
|
6962
|
+
await this.deleteSkill(tenantId, id);
|
|
6963
|
+
return newSkill;
|
|
6964
|
+
}
|
|
6965
|
+
}
|
|
6966
|
+
const updatedSkill = {
|
|
6967
|
+
...skill,
|
|
6968
|
+
name: updates.name ?? skill.name,
|
|
6969
|
+
description: updates.description ?? skill.description,
|
|
6970
|
+
license: updates.license ?? skill.license,
|
|
6971
|
+
compatibility: updates.compatibility ?? skill.compatibility,
|
|
6972
|
+
metadata: updates.metadata ?? skill.metadata,
|
|
6973
|
+
content: updates.content !== void 0 ? updates.content : skill.content,
|
|
6974
|
+
subSkills: updates.subSkills !== void 0 ? updates.subSkills : skill.subSkills,
|
|
6975
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
6976
|
+
};
|
|
6977
|
+
await this.writeSkillFile(updatedSkill);
|
|
6978
|
+
return updatedSkill;
|
|
6131
6979
|
}
|
|
6132
6980
|
/**
|
|
6133
|
-
*
|
|
6981
|
+
* Delete a skill by ID
|
|
6134
6982
|
*/
|
|
6135
|
-
|
|
6136
|
-
|
|
6983
|
+
async deleteSkill(tenantId, id) {
|
|
6984
|
+
try {
|
|
6985
|
+
const sandboxManager = await this.getSandboxManager();
|
|
6986
|
+
const sandbox = await sandboxManager.createSandbox("global");
|
|
6987
|
+
const filePath = this.getSkillFilePath(tenantId, id);
|
|
6988
|
+
const deleteResult = await sandbox.shell.execCommand({
|
|
6989
|
+
command: `rm -f "${filePath}"`
|
|
6990
|
+
});
|
|
6991
|
+
if (!deleteResult.ok) {
|
|
6992
|
+
return false;
|
|
6993
|
+
}
|
|
6994
|
+
return true;
|
|
6995
|
+
} catch (error) {
|
|
6996
|
+
console.error(`Error deleting skill ${id}:`, error);
|
|
6997
|
+
return false;
|
|
6998
|
+
}
|
|
6137
6999
|
}
|
|
6138
7000
|
/**
|
|
6139
|
-
* Check if
|
|
6140
|
-
* Uses composite key (key + type) to check existence
|
|
6141
|
-
* @param key Lattice key name
|
|
6142
|
-
* @param type Store type
|
|
7001
|
+
* Check if skill exists
|
|
6143
7002
|
*/
|
|
6144
|
-
|
|
6145
|
-
const
|
|
6146
|
-
return
|
|
7003
|
+
async hasSkill(tenantId, id) {
|
|
7004
|
+
const skill = await this.getSkillById(tenantId, id);
|
|
7005
|
+
return skill !== null;
|
|
6147
7006
|
}
|
|
6148
7007
|
/**
|
|
6149
|
-
*
|
|
6150
|
-
* Uses composite key (key + type) to remove the store
|
|
6151
|
-
* @param key Lattice key name
|
|
6152
|
-
* @param type Store type
|
|
7008
|
+
* Search skills by metadata within a tenant
|
|
6153
7009
|
*/
|
|
6154
|
-
|
|
6155
|
-
const
|
|
6156
|
-
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
|
+
);
|
|
6157
7015
|
}
|
|
6158
7016
|
/**
|
|
6159
|
-
*
|
|
7017
|
+
* Filter skills by compatibility within a tenant
|
|
6160
7018
|
*/
|
|
6161
|
-
|
|
6162
|
-
this.
|
|
7019
|
+
async filterByCompatibility(tenantId, compatibility) {
|
|
7020
|
+
const allSkills = await this.getAllSkills(tenantId);
|
|
7021
|
+
return allSkills.filter((skill) => skill.compatibility === compatibility);
|
|
6163
7022
|
}
|
|
6164
7023
|
/**
|
|
6165
|
-
*
|
|
7024
|
+
* Filter skills by license within a tenant
|
|
6166
7025
|
*/
|
|
6167
|
-
|
|
6168
|
-
|
|
7026
|
+
async filterByLicense(tenantId, license) {
|
|
7027
|
+
const allSkills = await this.getAllSkills(tenantId);
|
|
7028
|
+
return allSkills.filter((skill) => skill.license === license);
|
|
6169
7029
|
}
|
|
6170
7030
|
/**
|
|
6171
|
-
* Get
|
|
7031
|
+
* Get sub-skills of a parent skill within a tenant
|
|
6172
7032
|
*/
|
|
6173
|
-
|
|
6174
|
-
|
|
7033
|
+
async getSubSkills(tenantId, parentSkillName) {
|
|
7034
|
+
const parentSkill = await this.getSkillById(tenantId, parentSkillName);
|
|
7035
|
+
if (!parentSkill || !parentSkill.subSkills || parentSkill.subSkills.length === 0) {
|
|
7036
|
+
return [];
|
|
7037
|
+
}
|
|
7038
|
+
const subSkills = [];
|
|
7039
|
+
for (const subSkillName of parentSkill.subSkills) {
|
|
7040
|
+
const subSkill = await this.getSkillById(tenantId, subSkillName);
|
|
7041
|
+
if (subSkill) {
|
|
7042
|
+
subSkills.push(subSkill);
|
|
7043
|
+
}
|
|
7044
|
+
}
|
|
7045
|
+
return subSkills;
|
|
6175
7046
|
}
|
|
6176
7047
|
};
|
|
6177
|
-
var storeLatticeManager = StoreLatticeManager.getInstance();
|
|
6178
|
-
var registerStoreLattice = (key, type, store) => storeLatticeManager.registerLattice(key, type, store);
|
|
6179
|
-
var getStoreLattice = (key, type) => storeLatticeManager.getStoreLattice(key, type);
|
|
6180
|
-
var defaultThreadStore = new InMemoryThreadStore();
|
|
6181
|
-
var defaultAssistantStore = new InMemoryAssistantStore();
|
|
6182
|
-
var defaultSkillStore = new FileSystemSkillStore();
|
|
6183
|
-
var defaultWorkspaceStore = new InMemoryWorkspaceStore();
|
|
6184
|
-
var defaultProjectStore = new InMemoryProjectStore();
|
|
6185
|
-
var defaultDatabaseConfigStore = new InMemoryDatabaseConfigStore();
|
|
6186
|
-
var defaultMetricsServerConfigStore = new InMemoryMetricsServerConfigStore();
|
|
6187
|
-
var defaultMcpServerConfigStore = new InMemoryMcpServerConfigStore();
|
|
6188
|
-
storeLatticeManager.registerLattice("default", "thread", defaultThreadStore);
|
|
6189
|
-
storeLatticeManager.registerLattice(
|
|
6190
|
-
"default",
|
|
6191
|
-
"assistant",
|
|
6192
|
-
defaultAssistantStore
|
|
6193
|
-
);
|
|
6194
|
-
storeLatticeManager.registerLattice("default", "skill", defaultSkillStore);
|
|
6195
|
-
storeLatticeManager.registerLattice("default", "workspace", defaultWorkspaceStore);
|
|
6196
|
-
storeLatticeManager.registerLattice("default", "project", defaultProjectStore);
|
|
6197
|
-
storeLatticeManager.registerLattice("default", "database", defaultDatabaseConfigStore);
|
|
6198
|
-
storeLatticeManager.registerLattice("default", "metrics", defaultMetricsServerConfigStore);
|
|
6199
|
-
storeLatticeManager.registerLattice("default", "mcp", defaultMcpServerConfigStore);
|
|
6200
|
-
var defaultUserStore = new InMemoryUserStore();
|
|
6201
|
-
var defaultTenantStore = new InMemoryTenantStore();
|
|
6202
|
-
var defaultUserTenantLinkStore = new InMemoryUserTenantLinkStore();
|
|
6203
|
-
storeLatticeManager.registerLattice("default", "user", defaultUserStore);
|
|
6204
|
-
storeLatticeManager.registerLattice("default", "tenant", defaultTenantStore);
|
|
6205
|
-
storeLatticeManager.registerLattice("default", "userTenantLink", defaultUserTenantLinkStore);
|
|
6206
7048
|
|
|
6207
7049
|
// src/tool_lattice/skill/load_skills.ts
|
|
6208
7050
|
import z40 from "zod";
|
|
@@ -6241,9 +7083,11 @@ var createLoadSkillContentTool = () => {
|
|
|
6241
7083
|
try {
|
|
6242
7084
|
const storeLattice = getStoreLattice("default", "skill");
|
|
6243
7085
|
const skillStore = storeLattice.store;
|
|
6244
|
-
const
|
|
7086
|
+
const runConfig = _exe_config?.configurable?.runConfig || {};
|
|
7087
|
+
const tenantId = runConfig.tenantId || "default";
|
|
7088
|
+
const skill = await skillStore.getSkillById(tenantId, input.skill_name);
|
|
6245
7089
|
if (!skill) {
|
|
6246
|
-
const allSkills = await skillStore.getAllSkills();
|
|
7090
|
+
const allSkills = await skillStore.getAllSkills(tenantId);
|
|
6247
7091
|
const availableSkills = allSkills.map((s) => s.name).join(", ");
|
|
6248
7092
|
return `Skill "${input.skill_name}" not found. Available skills: ${availableSkills}`;
|
|
6249
7093
|
}
|
|
@@ -6275,7 +7119,7 @@ ${content}`;
|
|
|
6275
7119
|
const fsStore = skillStore;
|
|
6276
7120
|
if (fsStore.listSkillResources) {
|
|
6277
7121
|
try {
|
|
6278
|
-
const resources = await fsStore.listSkillResources(input.skill_name);
|
|
7122
|
+
const resources = await fsStore.listSkillResources(tenantId, input.skill_name);
|
|
6279
7123
|
if (resources.length > 0) {
|
|
6280
7124
|
result += "\n\n---\n\n**Resources** (use `load_skill_resource` tool to access):\n";
|
|
6281
7125
|
resources.forEach((resource) => {
|
|
@@ -6309,7 +7153,8 @@ var createLoadSkillResourceTool = () => {
|
|
|
6309
7153
|
return tool41(
|
|
6310
7154
|
async (input, _exe_config) => {
|
|
6311
7155
|
try {
|
|
6312
|
-
const
|
|
7156
|
+
const tenantId = _exe_config?.configurable?.runConfig?.tenantId || "default";
|
|
7157
|
+
const storeLattice = getStoreLattice(tenantId, "skill");
|
|
6313
7158
|
const skillStore = storeLattice.store;
|
|
6314
7159
|
const fsStore = skillStore;
|
|
6315
7160
|
if (!fsStore.loadSkillResource) {
|
|
@@ -6349,15 +7194,16 @@ function createSkillMiddleware(params = {}) {
|
|
|
6349
7194
|
createLoadSkillContentTool(),
|
|
6350
7195
|
createLoadSkillResourceTool()
|
|
6351
7196
|
],
|
|
6352
|
-
beforeAgent: async () => {
|
|
7197
|
+
beforeAgent: async (state, runtime) => {
|
|
6353
7198
|
try {
|
|
6354
7199
|
const storeLattice = getStoreLattice("default", "skill");
|
|
6355
7200
|
const skillStore = storeLattice?.store;
|
|
7201
|
+
const tenantId = runtime?.context?.tenantId || state?.tenantId || "default";
|
|
6356
7202
|
if (readAll) {
|
|
6357
|
-
latestSkills = await skillStore.getAllSkills();
|
|
7203
|
+
latestSkills = await skillStore.getAllSkills(tenantId);
|
|
6358
7204
|
} else if (skills && skills.length > 0) {
|
|
6359
7205
|
const skillLatticePromises = skills.map(
|
|
6360
|
-
(skillId) => skillStore.getSkillById(skillId)
|
|
7206
|
+
(skillId) => skillStore.getSkillById(tenantId, skillId)
|
|
6361
7207
|
);
|
|
6362
7208
|
const skillLattices = await Promise.all(skillLatticePromises);
|
|
6363
7209
|
latestSkills = skillLattices.filter((skill) => skill !== void 0);
|
|
@@ -7243,19 +8089,20 @@ ${systemPrompt}` : systemPrompt;
|
|
|
7243
8089
|
import { createMiddleware as createMiddleware6 } from "langchain";
|
|
7244
8090
|
function createMetricsMiddleware(params) {
|
|
7245
8091
|
const { serverKeys, serverDescriptions, connectAll } = params;
|
|
7246
|
-
|
|
7247
|
-
if (connectAll) {
|
|
7248
|
-
effectiveServerKeys = metricsServerManager.getServerKeys().map((s) => s.key);
|
|
7249
|
-
}
|
|
7250
|
-
if (!effectiveServerKeys || effectiveServerKeys.length === 0) {
|
|
8092
|
+
if (!serverKeys || serverKeys.length === 0) {
|
|
7251
8093
|
return createMiddleware6({
|
|
7252
8094
|
name: "metricsMiddleware",
|
|
7253
8095
|
tools: []
|
|
7254
8096
|
});
|
|
7255
8097
|
}
|
|
7256
8098
|
const toolParams = {
|
|
7257
|
-
serverKeys
|
|
7258
|
-
serverDescriptions
|
|
8099
|
+
serverKeys,
|
|
8100
|
+
serverDescriptions,
|
|
8101
|
+
// When connectAll is true, tools will dynamically get all servers for the tenant at runtime
|
|
8102
|
+
connectAll,
|
|
8103
|
+
// getTenantId will be called at runtime by each tool
|
|
8104
|
+
getTenantId: void 0
|
|
8105
|
+
// Tools will extract tenantId from _exeConfig.configurable.runConfig
|
|
7259
8106
|
};
|
|
7260
8107
|
return createMiddleware6({
|
|
7261
8108
|
name: "metricsMiddleware",
|
|
@@ -7388,7 +8235,7 @@ function createAskUserClarifyMiddleware() {
|
|
|
7388
8235
|
}
|
|
7389
8236
|
|
|
7390
8237
|
// src/agent_lattice/builders/commonMiddleware.ts
|
|
7391
|
-
function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
8238
|
+
async function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
7392
8239
|
const middlewares = [];
|
|
7393
8240
|
const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
|
|
7394
8241
|
if (filesystemConfig?.enabled && filesystemBackend) {
|
|
@@ -7443,14 +8290,16 @@ function createCommonMiddlewares(middlewareConfigs, filesystemBackend) {
|
|
|
7443
8290
|
|
|
7444
8291
|
// src/agent_lattice/builders/ReActAgentGraphBuilder.ts
|
|
7445
8292
|
var ReActAgentGraphBuilder = class {
|
|
7446
|
-
createFilesystemBackendFactory(middlewareConfigs) {
|
|
8293
|
+
createFilesystemBackendFactory(middlewareConfigs, agentLattice) {
|
|
7447
8294
|
const filesystemConfig = middlewareConfigs.find((m) => m.type === "filesystem");
|
|
7448
8295
|
if (!filesystemConfig || !filesystemConfig.enabled) {
|
|
7449
8296
|
return void 0;
|
|
7450
8297
|
}
|
|
7451
8298
|
const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
|
|
7452
|
-
|
|
7453
|
-
|
|
8299
|
+
const agentTenantId = agentLattice.config.tenantId;
|
|
8300
|
+
return async (stateAndStore) => {
|
|
8301
|
+
const { tenantId: runtimeTenantId, workspaceId, projectId } = stateAndStore;
|
|
8302
|
+
const tenantId = runtimeTenantId || agentTenantId;
|
|
7454
8303
|
let sandboxName = "global";
|
|
7455
8304
|
if (isolatedLevel === "agent") {
|
|
7456
8305
|
sandboxName = "agent";
|
|
@@ -7461,14 +8310,22 @@ var ReActAgentGraphBuilder = class {
|
|
|
7461
8310
|
if (!sandboxManager) {
|
|
7462
8311
|
throw new Error("Sandbox manager not found");
|
|
7463
8312
|
}
|
|
8313
|
+
let workingDirectory = "/";
|
|
8314
|
+
if (workspaceId && projectId) {
|
|
8315
|
+
if (tenantId) {
|
|
8316
|
+
workingDirectory = `/tenants/${tenantId}/${workspaceId}/${projectId}`;
|
|
8317
|
+
} else {
|
|
8318
|
+
workingDirectory = `/${workspaceId}/${projectId}`;
|
|
8319
|
+
}
|
|
8320
|
+
}
|
|
7464
8321
|
return new SandboxFilesystem({
|
|
7465
8322
|
sandboxInstance: await sandboxManager.createSandbox(sandboxName),
|
|
7466
|
-
workingDirectory
|
|
8323
|
+
workingDirectory
|
|
7467
8324
|
});
|
|
7468
8325
|
};
|
|
7469
8326
|
}
|
|
7470
|
-
createMiddlewares(middlewareConfigs) {
|
|
7471
|
-
return createCommonMiddlewares(middlewareConfigs);
|
|
8327
|
+
async createMiddlewares(middlewareConfigs) {
|
|
8328
|
+
return await createCommonMiddlewares(middlewareConfigs);
|
|
7472
8329
|
}
|
|
7473
8330
|
/**
|
|
7474
8331
|
* 构建ReAct Agent Graph
|
|
@@ -7477,15 +8334,15 @@ var ReActAgentGraphBuilder = class {
|
|
|
7477
8334
|
* @param params Agent构建参数
|
|
7478
8335
|
* @returns 返回CompiledGraph对象
|
|
7479
8336
|
*/
|
|
7480
|
-
build(agentLattice, params) {
|
|
8337
|
+
async build(agentLattice, params) {
|
|
7481
8338
|
const tools = params.tools.map((t) => {
|
|
7482
8339
|
const tool48 = getToolClient(t.key);
|
|
7483
8340
|
return tool48;
|
|
7484
8341
|
}).filter((tool48) => tool48 !== void 0);
|
|
7485
8342
|
const stateSchema2 = createReactAgentSchema(params.stateSchema);
|
|
7486
8343
|
const middlewareConfigs = params.middleware || [];
|
|
7487
|
-
const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs);
|
|
7488
|
-
const middlewares = createCommonMiddlewares(middlewareConfigs, filesystemBackend);
|
|
8344
|
+
const filesystemBackend = this.createFilesystemBackendFactory(middlewareConfigs, agentLattice);
|
|
8345
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs, filesystemBackend);
|
|
7489
8346
|
return createAgent({
|
|
7490
8347
|
model: params.model,
|
|
7491
8348
|
tools,
|
|
@@ -8328,14 +9185,18 @@ var StoreBackend = class {
|
|
|
8328
9185
|
/**
|
|
8329
9186
|
* Get the namespace for store operations.
|
|
8330
9187
|
*
|
|
8331
|
-
* If
|
|
8332
|
-
* [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"].
|
|
8333
9191
|
* Otherwise return ["filesystem"].
|
|
8334
9192
|
*/
|
|
8335
9193
|
getNamespace() {
|
|
8336
9194
|
const namespace = "filesystem";
|
|
9195
|
+
const tenantId = this.stateAndStore.tenantId;
|
|
8337
9196
|
const assistantId = this.stateAndStore.assistantId;
|
|
8338
|
-
if (assistantId) {
|
|
9197
|
+
if (tenantId && assistantId) {
|
|
9198
|
+
return [tenantId, assistantId, namespace];
|
|
9199
|
+
} else if (assistantId) {
|
|
8339
9200
|
return [assistantId, namespace];
|
|
8340
9201
|
}
|
|
8341
9202
|
return [namespace];
|
|
@@ -9762,8 +10623,8 @@ function createFilesystemBackendFactory(middlewareConfigs) {
|
|
|
9762
10623
|
return void 0;
|
|
9763
10624
|
}
|
|
9764
10625
|
const isolatedLevel = filesystemConfig.config?.isolatedLevel || "global";
|
|
9765
|
-
return async (
|
|
9766
|
-
const { workspaceId, projectId } =
|
|
10626
|
+
return async (stateAndStore) => {
|
|
10627
|
+
const { tenantId, workspaceId, projectId } = stateAndStore;
|
|
9767
10628
|
let sandboxName = "global";
|
|
9768
10629
|
if (isolatedLevel === "agent") {
|
|
9769
10630
|
sandboxName = "agent";
|
|
@@ -9774,9 +10635,17 @@ function createFilesystemBackendFactory(middlewareConfigs) {
|
|
|
9774
10635
|
if (!sandboxManager) {
|
|
9775
10636
|
throw new Error("Sandbox manager not found");
|
|
9776
10637
|
}
|
|
10638
|
+
let workingDirectory = "/";
|
|
10639
|
+
if (workspaceId && projectId) {
|
|
10640
|
+
if (tenantId) {
|
|
10641
|
+
workingDirectory = `/tenants/${tenantId}/workspaces/${workspaceId}/${projectId}`;
|
|
10642
|
+
} else {
|
|
10643
|
+
workingDirectory = `/workspaces/${workspaceId}/${projectId}`;
|
|
10644
|
+
}
|
|
10645
|
+
}
|
|
9777
10646
|
return new SandboxFilesystem({
|
|
9778
10647
|
sandboxInstance: await sandboxManager.createSandbox(sandboxName),
|
|
9779
|
-
workingDirectory
|
|
10648
|
+
workingDirectory
|
|
9780
10649
|
});
|
|
9781
10650
|
};
|
|
9782
10651
|
}
|
|
@@ -9786,8 +10655,8 @@ var DeepAgentGraphBuilder = class {
|
|
|
9786
10655
|
/**
|
|
9787
10656
|
* 根据 middleware 配置创建 middlewares
|
|
9788
10657
|
*/
|
|
9789
|
-
createMiddlewares(middlewareConfigs) {
|
|
9790
|
-
return createCommonMiddlewares(middlewareConfigs);
|
|
10658
|
+
async createMiddlewares(middlewareConfigs) {
|
|
10659
|
+
return await createCommonMiddlewares(middlewareConfigs);
|
|
9791
10660
|
}
|
|
9792
10661
|
/**
|
|
9793
10662
|
* 构建Deep Agent Graph
|
|
@@ -9796,12 +10665,12 @@ var DeepAgentGraphBuilder = class {
|
|
|
9796
10665
|
* @param params Agent构建参数
|
|
9797
10666
|
* @returns 返回CompiledGraph对象
|
|
9798
10667
|
*/
|
|
9799
|
-
build(agentLattice, params) {
|
|
10668
|
+
async build(agentLattice, params) {
|
|
9800
10669
|
const tools = params.tools.map((t) => {
|
|
9801
10670
|
const toolClient = getToolClient(t.key);
|
|
9802
10671
|
return toolClient;
|
|
9803
10672
|
}).filter((tool48) => tool48 !== void 0);
|
|
9804
|
-
const subagents = params.subAgents.map((sa) => {
|
|
10673
|
+
const subagents = await Promise.all(params.subAgents.map(async (sa) => {
|
|
9805
10674
|
if (sa.client) {
|
|
9806
10675
|
return {
|
|
9807
10676
|
key: sa.config.key,
|
|
@@ -9810,7 +10679,7 @@ var DeepAgentGraphBuilder = class {
|
|
|
9810
10679
|
runnable: sa.client
|
|
9811
10680
|
};
|
|
9812
10681
|
} else {
|
|
9813
|
-
const subagentClient = createAgentClientFromAgentLattice({
|
|
10682
|
+
const subagentClient = await createAgentClientFromAgentLattice({
|
|
9814
10683
|
config: sa.config
|
|
9815
10684
|
});
|
|
9816
10685
|
return {
|
|
@@ -9820,10 +10689,10 @@ var DeepAgentGraphBuilder = class {
|
|
|
9820
10689
|
runnable: subagentClient
|
|
9821
10690
|
};
|
|
9822
10691
|
}
|
|
9823
|
-
});
|
|
10692
|
+
}));
|
|
9824
10693
|
const middlewareConfigs = params.middleware || [];
|
|
9825
10694
|
const filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
9826
|
-
const middlewares = this.createMiddlewares(middlewareConfigs);
|
|
10695
|
+
const middlewares = await this.createMiddlewares(middlewareConfigs);
|
|
9827
10696
|
const deepAgent = createDeepAgent({
|
|
9828
10697
|
tools,
|
|
9829
10698
|
model: params.model,
|
|
@@ -11399,7 +12268,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
11399
12268
|
* @param params - Build params with resolved tools and model
|
|
11400
12269
|
* @returns AgentClient (the TeamLead ReactAgent)
|
|
11401
12270
|
*/
|
|
11402
|
-
build(agentLattice, params) {
|
|
12271
|
+
async build(agentLattice, params) {
|
|
11403
12272
|
const config = agentLattice.config;
|
|
11404
12273
|
if (!isTeamAgentConfig(config)) {
|
|
11405
12274
|
throw new Error(
|
|
@@ -11422,7 +12291,7 @@ var TeamAgentGraphBuilder = class {
|
|
|
11422
12291
|
});
|
|
11423
12292
|
const middlewareConfigs = params.middleware || [];
|
|
11424
12293
|
let filesystemBackend = createFilesystemBackendFactory(middlewareConfigs);
|
|
11425
|
-
const middlewares = createCommonMiddlewares(middlewareConfigs);
|
|
12294
|
+
const middlewares = await createCommonMiddlewares(middlewareConfigs);
|
|
11426
12295
|
if (!filesystemBackend) {
|
|
11427
12296
|
filesystemBackend = async (config2) => {
|
|
11428
12297
|
return new StateBackend(config2);
|
|
@@ -11605,6 +12474,31 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11605
12474
|
this.initialized = false;
|
|
11606
12475
|
this.subscribeToAssistantEvents();
|
|
11607
12476
|
}
|
|
12477
|
+
/**
|
|
12478
|
+
* 从store异步加载单个AgentLattice
|
|
12479
|
+
* 实现BaseLatticeManager的可选方法,支持从assistant store加载单个agent
|
|
12480
|
+
* @param tenantId 租户ID
|
|
12481
|
+
* @param key Agent键名
|
|
12482
|
+
* @returns AgentLattice或undefined
|
|
12483
|
+
*/
|
|
12484
|
+
async loadItemFromStore(tenantId, key) {
|
|
12485
|
+
try {
|
|
12486
|
+
const storeLattice = getStoreLattice("default", "assistant");
|
|
12487
|
+
const assistant = await storeLattice.store.getAssistantById(tenantId, key);
|
|
12488
|
+
if (!assistant) {
|
|
12489
|
+
return void 0;
|
|
12490
|
+
}
|
|
12491
|
+
const config = assistantToConfig(assistant);
|
|
12492
|
+
const agentLattice = {
|
|
12493
|
+
config,
|
|
12494
|
+
client: void 0
|
|
12495
|
+
};
|
|
12496
|
+
return agentLattice;
|
|
12497
|
+
} catch (error) {
|
|
12498
|
+
console.error(`Failed to load agent from store [tenant: ${tenantId}, key: ${key}]:`, error);
|
|
12499
|
+
return void 0;
|
|
12500
|
+
}
|
|
12501
|
+
}
|
|
11608
12502
|
/**
|
|
11609
12503
|
* 获取AgentLatticeManager单例实例
|
|
11610
12504
|
*/
|
|
@@ -11614,11 +12508,15 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11614
12508
|
}
|
|
11615
12509
|
return _AgentLatticeManager._instance;
|
|
11616
12510
|
}
|
|
12511
|
+
/**
|
|
12512
|
+
* @deprecated This method loads assistants only for the "default" tenant.
|
|
12513
|
+
* Use initializeStoredAssistantsForTenant(tenantId) for proper tenant isolation.
|
|
12514
|
+
*/
|
|
11617
12515
|
async initializeStoredAssistants() {
|
|
11618
12516
|
if (this.initialized) return;
|
|
11619
12517
|
try {
|
|
11620
12518
|
const storeLattice = getStoreLattice("default", "assistant");
|
|
11621
|
-
const assistants = await storeLattice.store.getAllAssistants();
|
|
12519
|
+
const assistants = await storeLattice.store.getAllAssistants("default");
|
|
11622
12520
|
for (const assistant of assistants) {
|
|
11623
12521
|
if (this.has(assistant.id)) continue;
|
|
11624
12522
|
const config = assistantToConfig(assistant);
|
|
@@ -11631,33 +12529,33 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11631
12529
|
}
|
|
11632
12530
|
subscribeToAssistantEvents() {
|
|
11633
12531
|
event_bus_default.subscribe("assistant:created", (data) => {
|
|
11634
|
-
this.handleAssistantChange(data.id);
|
|
12532
|
+
this.handleAssistantChange(data.id, data.tenantId ?? "default");
|
|
11635
12533
|
});
|
|
11636
12534
|
event_bus_default.subscribe("assistant:updated", (data) => {
|
|
11637
|
-
this.handleAssistantChange(data.id);
|
|
12535
|
+
this.handleAssistantChange(data.id, data.tenantId ?? "default");
|
|
11638
12536
|
});
|
|
11639
12537
|
event_bus_default.subscribe("assistant:deleted", (data) => {
|
|
11640
|
-
this.handleAssistantDelete(data.id);
|
|
12538
|
+
this.handleAssistantDelete(data.id, data.tenantId ?? "default");
|
|
11641
12539
|
});
|
|
11642
12540
|
}
|
|
11643
|
-
async handleAssistantChange(assistantId) {
|
|
12541
|
+
async handleAssistantChange(assistantId, tenantId = "default") {
|
|
11644
12542
|
try {
|
|
11645
12543
|
const storeLattice = getStoreLattice("default", "assistant");
|
|
11646
|
-
const assistant = await storeLattice.store.getAssistantById(assistantId);
|
|
12544
|
+
const assistant = await storeLattice.store.getAssistantById(tenantId, assistantId);
|
|
11647
12545
|
if (assistant) {
|
|
11648
|
-
if (this.
|
|
11649
|
-
this.
|
|
12546
|
+
if (this.hasWithTenant(tenantId, assistantId)) {
|
|
12547
|
+
this.removeWithTenant(tenantId, assistantId);
|
|
11650
12548
|
}
|
|
11651
12549
|
const config = assistantToConfig(assistant);
|
|
11652
|
-
this.
|
|
12550
|
+
this.registerLatticeWithTenant(tenantId, config);
|
|
11653
12551
|
}
|
|
11654
12552
|
} catch (error) {
|
|
11655
|
-
console.error(`Failed to handle assistant change for ${assistantId}:`, error);
|
|
12553
|
+
console.error(`Failed to handle assistant change for ${assistantId} (tenant: ${tenantId}):`, error);
|
|
11656
12554
|
}
|
|
11657
12555
|
}
|
|
11658
|
-
handleAssistantDelete(assistantId) {
|
|
11659
|
-
if (this.
|
|
11660
|
-
this.
|
|
12556
|
+
handleAssistantDelete(assistantId, tenantId = "default") {
|
|
12557
|
+
if (this.hasWithTenant(tenantId, assistantId)) {
|
|
12558
|
+
this.removeWithTenant(tenantId, assistantId);
|
|
11661
12559
|
}
|
|
11662
12560
|
}
|
|
11663
12561
|
/**
|
|
@@ -11666,8 +12564,96 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11666
12564
|
getLatticeType() {
|
|
11667
12565
|
return "agents";
|
|
11668
12566
|
}
|
|
12567
|
+
// ========== 带租户的新API ==========
|
|
12568
|
+
/**
|
|
12569
|
+
* 带租户注册Agent Lattice
|
|
12570
|
+
* @param tenantId 租户ID
|
|
12571
|
+
* @param config Agent配置
|
|
12572
|
+
*/
|
|
12573
|
+
registerLatticeWithTenant(tenantId, config) {
|
|
12574
|
+
const agentLattice = {
|
|
12575
|
+
config: { ...config, tenantId },
|
|
12576
|
+
client: void 0
|
|
12577
|
+
// 客户端将在需要时由initializeClient创建
|
|
12578
|
+
};
|
|
12579
|
+
this.registerWithTenant(tenantId, config.key, agentLattice);
|
|
12580
|
+
}
|
|
12581
|
+
/**
|
|
12582
|
+
* 带租户获取AgentLattice
|
|
12583
|
+
* @param tenantId 租户ID
|
|
12584
|
+
* @param key Lattice键名
|
|
12585
|
+
*/
|
|
12586
|
+
getAgentLatticeWithTenant(tenantId, key) {
|
|
12587
|
+
return this.getWithTenant(tenantId, key);
|
|
12588
|
+
}
|
|
12589
|
+
/**
|
|
12590
|
+
* 带租户检查Lattice是否存在
|
|
12591
|
+
* @param tenantId 租户ID
|
|
12592
|
+
* @param key Lattice键名
|
|
12593
|
+
*/
|
|
12594
|
+
hasAgentLatticeWithTenant(tenantId, key) {
|
|
12595
|
+
return this.hasWithTenant(tenantId, key);
|
|
12596
|
+
}
|
|
12597
|
+
/**
|
|
12598
|
+
* 带租户移除Lattice
|
|
12599
|
+
* @param tenantId 租户ID
|
|
12600
|
+
* @param key Lattice键名
|
|
12601
|
+
*/
|
|
12602
|
+
removeAgentLatticeWithTenant(tenantId, key) {
|
|
12603
|
+
return this.removeWithTenant(tenantId, key);
|
|
12604
|
+
}
|
|
12605
|
+
/**
|
|
12606
|
+
* 获取指定租户的所有Agent Lattice
|
|
12607
|
+
* @param tenantId 租户ID
|
|
12608
|
+
*/
|
|
12609
|
+
getAllAgentLatticesByTenant(tenantId) {
|
|
12610
|
+
return this.getAllByTenant(tenantId);
|
|
12611
|
+
}
|
|
12612
|
+
/**
|
|
12613
|
+
* 清空指定租户的所有Agent Lattice
|
|
12614
|
+
* @param tenantId 租户ID
|
|
12615
|
+
*/
|
|
12616
|
+
clearAgentLatticesByTenant(tenantId) {
|
|
12617
|
+
this.clearByTenant(tenantId);
|
|
12618
|
+
}
|
|
12619
|
+
/**
|
|
12620
|
+
* 带租户获取Agent配置
|
|
12621
|
+
* @param tenantId 租户ID
|
|
12622
|
+
* @param key Lattice键名
|
|
12623
|
+
*/
|
|
12624
|
+
getAgentConfigWithTenant(tenantId, key) {
|
|
12625
|
+
return this.getAgentLatticeWithTenant(tenantId, key)?.config;
|
|
12626
|
+
}
|
|
12627
|
+
/**
|
|
12628
|
+
* 获取指定租户的所有Agent配置
|
|
12629
|
+
* 先从数据库加载该租户的 assistants,然后返回所有配置
|
|
12630
|
+
* @param tenantId 租户ID
|
|
12631
|
+
*/
|
|
12632
|
+
async getAllAgentConfigsByTenant(tenantId) {
|
|
12633
|
+
await this.initializeStoredAssistantsForTenant(tenantId);
|
|
12634
|
+
return this.getAllAgentLatticesByTenant(tenantId).map((lattice) => lattice.config);
|
|
12635
|
+
}
|
|
12636
|
+
/**
|
|
12637
|
+
* 从数据库加载指定租户的存储助手
|
|
12638
|
+
* @param tenantId 租户ID
|
|
12639
|
+
*/
|
|
12640
|
+
async initializeStoredAssistantsForTenant(tenantId) {
|
|
12641
|
+
try {
|
|
12642
|
+
const storeLattice = getStoreLattice("default", "assistant");
|
|
12643
|
+
const assistants = await storeLattice.store.getAllAssistants(tenantId);
|
|
12644
|
+
for (const assistant of assistants) {
|
|
12645
|
+
if (this.hasAgentLatticeWithTenant(tenantId, assistant.id)) continue;
|
|
12646
|
+
const config = assistantToConfig(assistant);
|
|
12647
|
+
this.registerLatticeWithTenant(tenantId, config);
|
|
12648
|
+
}
|
|
12649
|
+
} catch (error) {
|
|
12650
|
+
console.error(`Failed to initialize stored assistants for tenant ${tenantId}:`, error);
|
|
12651
|
+
}
|
|
12652
|
+
}
|
|
12653
|
+
// ========== 向后兼容的旧API(使用 default 租户) ==========
|
|
11669
12654
|
/**
|
|
11670
|
-
* 注册Agent Lattice
|
|
12655
|
+
* 注册Agent Lattice(向后兼容,使用 "default" 租户)
|
|
12656
|
+
* @deprecated Use registerLatticeWithTenant(tenantId, config) instead
|
|
11671
12657
|
* @param config Agent配置
|
|
11672
12658
|
*/
|
|
11673
12659
|
registerLattice(config) {
|
|
@@ -11705,7 +12691,8 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11705
12691
|
return this.remove(key);
|
|
11706
12692
|
}
|
|
11707
12693
|
/**
|
|
11708
|
-
* 获取AgentLattice
|
|
12694
|
+
* 获取AgentLattice(向后兼容,使用 "default" 租户)
|
|
12695
|
+
* @deprecated Use getAgentLatticeWithTenant(tenantId, key) instead
|
|
11709
12696
|
* @param key Lattice键名
|
|
11710
12697
|
*/
|
|
11711
12698
|
getAgentLattice(key) {
|
|
@@ -11718,25 +12705,28 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11718
12705
|
return this.getAll();
|
|
11719
12706
|
}
|
|
11720
12707
|
/**
|
|
11721
|
-
* 检查Lattice
|
|
12708
|
+
* 检查Lattice是否存在(向后兼容,使用 "default" 租户)
|
|
12709
|
+
* @deprecated Use hasAgentLatticeWithTenant(tenantId, key) instead
|
|
11722
12710
|
* @param key Lattice键名
|
|
11723
12711
|
*/
|
|
11724
12712
|
hasLattice(key) {
|
|
11725
12713
|
return this.has(key);
|
|
11726
12714
|
}
|
|
11727
12715
|
/**
|
|
11728
|
-
* 移除Lattice
|
|
12716
|
+
* 移除Lattice(向后兼容,使用 "default" 租户)
|
|
12717
|
+
* @deprecated Use removeAgentLatticeWithTenant(tenantId, key) instead
|
|
11729
12718
|
* @param key Lattice键名
|
|
11730
12719
|
*/
|
|
11731
12720
|
removeLattice(key) {
|
|
11732
12721
|
return this.remove(key);
|
|
11733
12722
|
}
|
|
11734
12723
|
/**
|
|
11735
|
-
* 获取Agent
|
|
12724
|
+
* 获取Agent配置(向后兼容,使用 "default" 租户)
|
|
12725
|
+
* @deprecated Use getAgentConfigWithTenant(tenantId, key) instead
|
|
11736
12726
|
* @param key Lattice键名
|
|
11737
12727
|
*/
|
|
11738
12728
|
getAgentConfig(key) {
|
|
11739
|
-
return this.
|
|
12729
|
+
return this.getAgentLatticeWithTenant("default", key)?.config;
|
|
11740
12730
|
}
|
|
11741
12731
|
/**
|
|
11742
12732
|
* 获取所有Agent配置
|
|
@@ -11757,8 +12747,9 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11757
12747
|
return false;
|
|
11758
12748
|
}
|
|
11759
12749
|
try {
|
|
11760
|
-
|
|
11761
|
-
|
|
12750
|
+
const config = agentLattice.config;
|
|
12751
|
+
if ("schema" in config && config.schema) {
|
|
12752
|
+
config.schema.parse(input);
|
|
11762
12753
|
}
|
|
11763
12754
|
return true;
|
|
11764
12755
|
} catch {
|
|
@@ -11806,9 +12797,10 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11806
12797
|
* @returns 返回Agent构建参数
|
|
11807
12798
|
*/
|
|
11808
12799
|
buildAgentParams(agentLattice, options) {
|
|
12800
|
+
const tenantId = agentLattice.config.tenantId || "default";
|
|
11809
12801
|
const paramsBuilder = new AgentParamsBuilder((key) => {
|
|
11810
|
-
this.initializeClient(key);
|
|
11811
|
-
return this.
|
|
12802
|
+
this.initializeClient(tenantId, key);
|
|
12803
|
+
return this.getAgentLatticeWithTenant(tenantId, key);
|
|
11812
12804
|
});
|
|
11813
12805
|
return paramsBuilder.buildParams(agentLattice, options);
|
|
11814
12806
|
}
|
|
@@ -11819,7 +12811,7 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11819
12811
|
* @param options Build options
|
|
11820
12812
|
* @returns AgentClient instance
|
|
11821
12813
|
*/
|
|
11822
|
-
createAgentClientFromConfig(agentLattice, options) {
|
|
12814
|
+
async createAgentClientFromConfig(agentLattice, options) {
|
|
11823
12815
|
const resolvedConfig = this.resolveInheritedConfig(agentLattice.config);
|
|
11824
12816
|
const resolvedLattice = {
|
|
11825
12817
|
...agentLattice,
|
|
@@ -11828,26 +12820,50 @@ var AgentLatticeManager = class _AgentLatticeManager extends BaseLatticeManager
|
|
|
11828
12820
|
const factory = AgentGraphBuilderFactory.getInstance();
|
|
11829
12821
|
const builder = factory.getBuilder(resolvedConfig.type);
|
|
11830
12822
|
const params = this.buildAgentParams(resolvedLattice, options);
|
|
11831
|
-
return builder.build(resolvedLattice, params);
|
|
12823
|
+
return await builder.build(resolvedLattice, params);
|
|
11832
12824
|
}
|
|
11833
12825
|
/**
|
|
11834
12826
|
* 初始化Agent客户端
|
|
11835
12827
|
*
|
|
11836
12828
|
* 使用AgentGraphBuilderFactory构建Graph并设置为客户端
|
|
11837
12829
|
*
|
|
12830
|
+
* @param tenantId 租户ID
|
|
11838
12831
|
* @param key Lattice键名
|
|
11839
12832
|
* @param options 构建选项
|
|
11840
12833
|
* @returns 返回CompiledGraph对象
|
|
11841
12834
|
*/
|
|
11842
|
-
initializeClient(key, options) {
|
|
11843
|
-
const agentLattice = this.
|
|
12835
|
+
async initializeClient(tenantId, key, options) {
|
|
12836
|
+
const agentLattice = this.getAgentLatticeWithTenant(tenantId, key);
|
|
12837
|
+
if (!agentLattice) {
|
|
12838
|
+
throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
|
|
12839
|
+
}
|
|
12840
|
+
if (agentLattice.client) {
|
|
12841
|
+
return agentLattice.client;
|
|
12842
|
+
}
|
|
12843
|
+
const graph = await this.createAgentClientFromConfig(agentLattice, options);
|
|
12844
|
+
agentLattice.client = graph;
|
|
12845
|
+
return graph;
|
|
12846
|
+
}
|
|
12847
|
+
/**
|
|
12848
|
+
* 异步初始化Agent客户端(支持从store加载)
|
|
12849
|
+
*
|
|
12850
|
+
* 如果内存中不存在,会尝试从store加载
|
|
12851
|
+
* 使用AgentGraphBuilderFactory构建Graph并设置为客户端
|
|
12852
|
+
*
|
|
12853
|
+
* @param tenantId 租户ID
|
|
12854
|
+
* @param key Lattice键名
|
|
12855
|
+
* @param options 构建选项
|
|
12856
|
+
* @returns 返回CompiledGraph对象
|
|
12857
|
+
*/
|
|
12858
|
+
async initializeClientAsync(tenantId, key, options) {
|
|
12859
|
+
const agentLattice = await this.getOrLoadWithTenant(tenantId, key);
|
|
11844
12860
|
if (!agentLattice) {
|
|
11845
|
-
throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728`);
|
|
12861
|
+
throw new Error(`Agent Lattice "${key}" \u4E0D\u5B58\u5728 (tenant: ${tenantId})`);
|
|
11846
12862
|
}
|
|
11847
12863
|
if (agentLattice.client) {
|
|
11848
12864
|
return agentLattice.client;
|
|
11849
12865
|
}
|
|
11850
|
-
const graph = this.createAgentClientFromConfig(agentLattice, options);
|
|
12866
|
+
const graph = await this.createAgentClientFromConfig(agentLattice, options);
|
|
11851
12867
|
agentLattice.client = graph;
|
|
11852
12868
|
return graph;
|
|
11853
12869
|
}
|
|
@@ -11856,19 +12872,24 @@ var agentLatticeManager = AgentLatticeManager.getInstance();
|
|
|
11856
12872
|
var registerAgentLattice = (config) => {
|
|
11857
12873
|
agentLatticeManager.registerLattice(config);
|
|
11858
12874
|
};
|
|
11859
|
-
var
|
|
12875
|
+
var registerAgentLatticeWithTenant = (tenantId, config) => {
|
|
12876
|
+
agentLatticeManager.registerLatticeWithTenant(tenantId, config);
|
|
12877
|
+
};
|
|
12878
|
+
var registerAgentLattices = (tenantId, configs) => {
|
|
12879
|
+
if (!tenantId) {
|
|
12880
|
+
throw new Error("tenantId is required");
|
|
12881
|
+
}
|
|
11860
12882
|
configs.forEach((config) => {
|
|
11861
|
-
agentLatticeManager.
|
|
12883
|
+
agentLatticeManager.registerLatticeWithTenant(tenantId, config);
|
|
11862
12884
|
});
|
|
11863
12885
|
};
|
|
11864
|
-
var getAgentLattice = (key) => agentLatticeManager.getAgentLattice(key);
|
|
11865
12886
|
var getAgentConfig = (key) => agentLatticeManager.getAgentConfig(key);
|
|
11866
12887
|
var getAllAgentConfigs = () => agentLatticeManager.getAllAgentConfigs();
|
|
11867
12888
|
var validateAgentInput = (key, input) => agentLatticeManager.validateAgentInput(key, input);
|
|
11868
12889
|
var registerTeammateAgent = (key, client) => agentLatticeManager.registerTeammateAgent(key, client);
|
|
11869
12890
|
var unregisterTeammateAgent = (key) => agentLatticeManager.unregisterTeammateAgent(key);
|
|
11870
|
-
var getAgentClient = (key, options) => agentLatticeManager.initializeClient(key, options);
|
|
11871
|
-
var createAgentClientFromAgentLattice = (agentLattice, options) => agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
|
|
12891
|
+
var getAgentClient = (tenantId, key, options) => agentLatticeManager.initializeClient(tenantId, key, options);
|
|
12892
|
+
var createAgentClientFromAgentLattice = async (agentLattice, options) => await agentLatticeManager.createAgentClientFromConfig(agentLattice, options);
|
|
11872
12893
|
|
|
11873
12894
|
// src/chunk_buffer_lattice/ChunkBuffer.ts
|
|
11874
12895
|
var ChunkBuffer = class {
|
|
@@ -11950,6 +12971,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
11950
12971
|
buffer = {
|
|
11951
12972
|
threadId,
|
|
11952
12973
|
chunks$: new ReplaySubject(this.config.maxChunks),
|
|
12974
|
+
chunks: [],
|
|
11953
12975
|
status: "active" /* ACTIVE */,
|
|
11954
12976
|
createdAt: now,
|
|
11955
12977
|
updatedAt: now,
|
|
@@ -11960,14 +12982,27 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
11960
12982
|
if (buffer.status !== "active" /* ACTIVE */) {
|
|
11961
12983
|
buffer.status = "active" /* ACTIVE */;
|
|
11962
12984
|
buffer.chunks$ = new ReplaySubject(this.config.maxChunks);
|
|
12985
|
+
buffer.chunks = [];
|
|
11963
12986
|
buffer.updatedAt = Date.now();
|
|
11964
12987
|
buffer.expiresAt = Date.now() + this.config.ttl;
|
|
11965
12988
|
}
|
|
11966
12989
|
return buffer;
|
|
11967
12990
|
}
|
|
11968
|
-
async addChunk(threadId,
|
|
12991
|
+
async addChunk(threadId, arg2, arg3) {
|
|
11969
12992
|
const buffer = this.getOrCreateBuffer(threadId);
|
|
11970
|
-
|
|
12993
|
+
let chunk;
|
|
12994
|
+
if (typeof arg2 === "string" && arg3 !== void 0) {
|
|
12995
|
+
chunk = {
|
|
12996
|
+
type: "message_chunk",
|
|
12997
|
+
data: {
|
|
12998
|
+
id: arg2,
|
|
12999
|
+
content: arg3
|
|
13000
|
+
}
|
|
13001
|
+
};
|
|
13002
|
+
} else {
|
|
13003
|
+
chunk = arg2;
|
|
13004
|
+
}
|
|
13005
|
+
buffer.chunks.push(chunk);
|
|
11971
13006
|
buffer.chunks$.next(chunk);
|
|
11972
13007
|
buffer.updatedAt = Date.now();
|
|
11973
13008
|
buffer.expiresAt = Date.now() + this.config.ttl;
|
|
@@ -11999,7 +13034,25 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
11999
13034
|
async getThreadBuffer(threadId) {
|
|
12000
13035
|
const buffer = this.getBufferIfValid(threadId);
|
|
12001
13036
|
if (!buffer) return void 0;
|
|
12002
|
-
return
|
|
13037
|
+
return {
|
|
13038
|
+
...buffer,
|
|
13039
|
+
chunks: [...buffer.chunks]
|
|
13040
|
+
};
|
|
13041
|
+
}
|
|
13042
|
+
async getChunks(threadId) {
|
|
13043
|
+
const buffer = this.getBufferIfValid(threadId);
|
|
13044
|
+
if (!buffer) return [];
|
|
13045
|
+
return [...buffer.chunks];
|
|
13046
|
+
}
|
|
13047
|
+
async getAccumulatedContent(threadId) {
|
|
13048
|
+
const buffer = this.getBufferIfValid(threadId);
|
|
13049
|
+
if (!buffer) return "";
|
|
13050
|
+
return buffer.chunks.map((chunk) => chunk.data?.content || "").join("");
|
|
13051
|
+
}
|
|
13052
|
+
async getChunksByMessageId(threadId, messageId) {
|
|
13053
|
+
const buffer = this.getBufferIfValid(threadId);
|
|
13054
|
+
if (!buffer) return [];
|
|
13055
|
+
return buffer.chunks.filter((chunk) => chunk.data?.id === messageId);
|
|
12003
13056
|
}
|
|
12004
13057
|
async clearThread(threadId) {
|
|
12005
13058
|
this.buffers.delete(threadId);
|
|
@@ -12129,6 +13182,7 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12129
13182
|
let activeCount = 0;
|
|
12130
13183
|
let completedCount = 0;
|
|
12131
13184
|
let abortedCount = 0;
|
|
13185
|
+
let totalChunkCount = 0;
|
|
12132
13186
|
const validBuffers = [];
|
|
12133
13187
|
for (const [threadId, buffer] of this.buffers.entries()) {
|
|
12134
13188
|
if (this.isExpired(buffer)) {
|
|
@@ -12149,12 +13203,14 @@ var InMemoryChunkBuffer = class extends ChunkBuffer {
|
|
|
12149
13203
|
abortedCount++;
|
|
12150
13204
|
break;
|
|
12151
13205
|
}
|
|
13206
|
+
totalChunkCount += buffer.chunks.length;
|
|
12152
13207
|
}
|
|
12153
13208
|
return {
|
|
12154
13209
|
totalThreads: validBuffers.length,
|
|
12155
13210
|
activeThreads: activeCount,
|
|
12156
13211
|
completedThreads: completedCount,
|
|
12157
13212
|
abortedThreads: abortedCount,
|
|
13213
|
+
totalChunks: totalChunkCount,
|
|
12158
13214
|
config: this.config
|
|
12159
13215
|
};
|
|
12160
13216
|
}
|
|
@@ -12322,6 +13378,9 @@ var MemoryScheduleStorage = class {
|
|
|
12322
13378
|
let result = [];
|
|
12323
13379
|
for (const task of this.tasks.values()) {
|
|
12324
13380
|
let match = true;
|
|
13381
|
+
if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
|
|
13382
|
+
match = false;
|
|
13383
|
+
}
|
|
12325
13384
|
if (filters?.status !== void 0 && task.status !== filters.status) {
|
|
12326
13385
|
match = false;
|
|
12327
13386
|
}
|
|
@@ -12358,6 +13417,9 @@ var MemoryScheduleStorage = class {
|
|
|
12358
13417
|
let count = 0;
|
|
12359
13418
|
for (const task of this.tasks.values()) {
|
|
12360
13419
|
let match = true;
|
|
13420
|
+
if (filters?.tenantId !== void 0 && task.tenantId !== filters.tenantId) {
|
|
13421
|
+
match = false;
|
|
13422
|
+
}
|
|
12361
13423
|
if (filters?.status !== void 0 && task.status !== filters.status) {
|
|
12362
13424
|
match = false;
|
|
12363
13425
|
}
|
|
@@ -13697,6 +14759,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13697
14759
|
getLatticeType() {
|
|
13698
14760
|
return "skills";
|
|
13699
14761
|
}
|
|
14762
|
+
/**
|
|
14763
|
+
* Default tenant ID for store operations
|
|
14764
|
+
* Note: SkillLatticeManager operates without explicit tenant context.
|
|
14765
|
+
* Store methods require tenantId for protocol compliance.
|
|
14766
|
+
*/
|
|
14767
|
+
getDefaultTenantId() {
|
|
14768
|
+
return "default";
|
|
14769
|
+
}
|
|
13700
14770
|
/**
|
|
13701
14771
|
* Configure store for persistence
|
|
13702
14772
|
* @param storeKey Store key name registered in StoreLatticeManager
|
|
@@ -13737,12 +14807,13 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13737
14807
|
client.store = store;
|
|
13738
14808
|
}
|
|
13739
14809
|
/**
|
|
13740
|
-
* Register a skill Lattice
|
|
14810
|
+
* Register a skill Lattice with tenant
|
|
14811
|
+
* @param tenantId Tenant ID
|
|
13741
14812
|
* @param key Lattice key name
|
|
13742
14813
|
* @param config Skill configuration
|
|
13743
14814
|
* @param client Optional skill client implementation
|
|
13744
14815
|
*/
|
|
13745
|
-
async
|
|
14816
|
+
async registerLatticeWithTenant(tenantId, key, config, client) {
|
|
13746
14817
|
if (!config.name) {
|
|
13747
14818
|
throw new Error("Skill name is required");
|
|
13748
14819
|
}
|
|
@@ -13764,10 +14835,10 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13764
14835
|
config,
|
|
13765
14836
|
client: client ?? null
|
|
13766
14837
|
};
|
|
13767
|
-
this.
|
|
14838
|
+
this.registerWithTenant(tenantId, key, skillLattice);
|
|
13768
14839
|
if (store) {
|
|
13769
14840
|
try {
|
|
13770
|
-
await store.createSkill(key, {
|
|
14841
|
+
await store.createSkill(tenantId, key, {
|
|
13771
14842
|
name: config.name,
|
|
13772
14843
|
description: config.description,
|
|
13773
14844
|
license: config.license,
|
|
@@ -13785,24 +14856,43 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13785
14856
|
}
|
|
13786
14857
|
}
|
|
13787
14858
|
/**
|
|
13788
|
-
*
|
|
14859
|
+
* Register a skill Lattice (backward compatible, uses "default" tenant)
|
|
14860
|
+
* @deprecated Use registerLatticeWithTenant(tenantId, key, config, client) instead
|
|
14861
|
+
* @param key Lattice key name
|
|
14862
|
+
* @param config Skill configuration
|
|
14863
|
+
* @param client Optional skill client implementation
|
|
14864
|
+
*/
|
|
14865
|
+
async registerLattice(key, config, client) {
|
|
14866
|
+
return this.registerLatticeWithTenant(this.getDefaultTenantId(), key, config, client);
|
|
14867
|
+
}
|
|
14868
|
+
/**
|
|
14869
|
+
* Get skill Lattice by key with tenant
|
|
14870
|
+
* @param tenantId Tenant ID
|
|
14871
|
+
* @param key Lattice key name
|
|
14872
|
+
*/
|
|
14873
|
+
getSkillLatticeWithTenant(tenantId, key) {
|
|
14874
|
+
return this.getWithTenant(tenantId, key);
|
|
14875
|
+
}
|
|
14876
|
+
/**
|
|
14877
|
+
* Get skill Lattice by key (backward compatible, uses "default" tenant)
|
|
14878
|
+
* @deprecated Use getSkillLatticeWithTenant(tenantId, key) instead
|
|
13789
14879
|
* @param key Lattice key name
|
|
13790
14880
|
*/
|
|
13791
14881
|
getSkillLattice(key) {
|
|
13792
|
-
return this.
|
|
14882
|
+
return this.getWithTenant(this.getDefaultTenantId(), key);
|
|
13793
14883
|
}
|
|
13794
14884
|
/**
|
|
13795
|
-
* Get all skill Lattices from store
|
|
13796
|
-
*
|
|
14885
|
+
* Get all skill Lattices from store with tenant
|
|
14886
|
+
* @param tenantId Tenant ID
|
|
13797
14887
|
*/
|
|
13798
|
-
async
|
|
14888
|
+
async getAllLatticesWithTenant(tenantId) {
|
|
13799
14889
|
const store = this.getStore();
|
|
13800
14890
|
if (!store) {
|
|
13801
|
-
return this.
|
|
14891
|
+
return this.getAllByTenant(tenantId);
|
|
13802
14892
|
}
|
|
13803
|
-
const skills = await store.getAllSkills();
|
|
14893
|
+
const skills = await store.getAllSkills(tenantId);
|
|
13804
14894
|
return skills.map((skill) => {
|
|
13805
|
-
const memoryLattice = this.
|
|
14895
|
+
const memoryLattice = this.getWithTenant(tenantId, skill.id);
|
|
13806
14896
|
const client = memoryLattice?.client || null;
|
|
13807
14897
|
if (client && store) {
|
|
13808
14898
|
this.injectStoreIntoClient(client, store);
|
|
@@ -13823,23 +14913,40 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13823
14913
|
});
|
|
13824
14914
|
}
|
|
13825
14915
|
/**
|
|
13826
|
-
*
|
|
14916
|
+
* Get all skill Lattices from store (backward compatible, uses "default" tenant)
|
|
14917
|
+
* @deprecated Use getAllLatticesWithTenant(tenantId) instead
|
|
14918
|
+
*/
|
|
14919
|
+
async getAllLattices() {
|
|
14920
|
+
return this.getAllLatticesWithTenant(this.getDefaultTenantId());
|
|
14921
|
+
}
|
|
14922
|
+
/**
|
|
14923
|
+
* Check if Lattice exists with tenant
|
|
14924
|
+
* @param tenantId Tenant ID
|
|
14925
|
+
* @param key Lattice key name
|
|
14926
|
+
*/
|
|
14927
|
+
hasLatticeWithTenant(tenantId, key) {
|
|
14928
|
+
return this.hasWithTenant(tenantId, key);
|
|
14929
|
+
}
|
|
14930
|
+
/**
|
|
14931
|
+
* Check if Lattice exists (backward compatible, uses "default" tenant)
|
|
14932
|
+
* @deprecated Use hasLatticeWithTenant(tenantId, key) instead
|
|
13827
14933
|
* @param key Lattice key name
|
|
13828
14934
|
*/
|
|
13829
14935
|
hasLattice(key) {
|
|
13830
|
-
return this.
|
|
14936
|
+
return this.hasWithTenant(this.getDefaultTenantId(), key);
|
|
13831
14937
|
}
|
|
13832
14938
|
/**
|
|
13833
|
-
* Remove Lattice
|
|
14939
|
+
* Remove Lattice with tenant
|
|
14940
|
+
* @param tenantId Tenant ID
|
|
13834
14941
|
* @param key Lattice key name
|
|
13835
14942
|
*/
|
|
13836
|
-
async
|
|
13837
|
-
const removed = this.
|
|
14943
|
+
async removeLatticeWithTenant(tenantId, key) {
|
|
14944
|
+
const removed = this.removeWithTenant(tenantId, key);
|
|
13838
14945
|
if (removed) {
|
|
13839
14946
|
const store = this.getStore();
|
|
13840
14947
|
if (store) {
|
|
13841
14948
|
try {
|
|
13842
|
-
await store.deleteSkill(key);
|
|
14949
|
+
await store.deleteSkill(tenantId, key);
|
|
13843
14950
|
} catch (error) {
|
|
13844
14951
|
console.warn(
|
|
13845
14952
|
`Failed to remove skill ${key} from store:`,
|
|
@@ -13850,6 +14957,14 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13850
14957
|
}
|
|
13851
14958
|
return removed;
|
|
13852
14959
|
}
|
|
14960
|
+
/**
|
|
14961
|
+
* Remove Lattice (backward compatible, uses "default" tenant)
|
|
14962
|
+
* @deprecated Use removeLatticeWithTenant(tenantId, key) instead
|
|
14963
|
+
* @param key Lattice key name
|
|
14964
|
+
*/
|
|
14965
|
+
async removeLattice(key) {
|
|
14966
|
+
return this.removeLatticeWithTenant(this.getDefaultTenantId(), key);
|
|
14967
|
+
}
|
|
13853
14968
|
/**
|
|
13854
14969
|
* Clear all Lattices
|
|
13855
14970
|
*/
|
|
@@ -13947,7 +15062,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13947
15062
|
if (!store) {
|
|
13948
15063
|
throw new Error("No store configured. Call configureStore() first.");
|
|
13949
15064
|
}
|
|
13950
|
-
const skills = await store.getAllSkills();
|
|
15065
|
+
const skills = await store.getAllSkills(this.getDefaultTenantId());
|
|
13951
15066
|
for (const skill of skills) {
|
|
13952
15067
|
const skillLattice = {
|
|
13953
15068
|
key: skill.id,
|
|
@@ -13984,7 +15099,7 @@ var SkillLatticeManager = class _SkillLatticeManager extends BaseLatticeManager
|
|
|
13984
15099
|
...updates
|
|
13985
15100
|
};
|
|
13986
15101
|
skillLattice.config = updatedConfig;
|
|
13987
|
-
await store.updateSkill(key, {
|
|
15102
|
+
await store.updateSkill(this.getDefaultTenantId(), key, {
|
|
13988
15103
|
name: updatedConfig.name,
|
|
13989
15104
|
description: updatedConfig.description,
|
|
13990
15105
|
license: updatedConfig.license,
|
|
@@ -14208,6 +15323,7 @@ export {
|
|
|
14208
15323
|
QueueLatticeManager,
|
|
14209
15324
|
SandboxFilesystem,
|
|
14210
15325
|
SandboxLatticeManager,
|
|
15326
|
+
SandboxSkillStore,
|
|
14211
15327
|
ScheduleLatticeManager,
|
|
14212
15328
|
SemanticMetricsClient,
|
|
14213
15329
|
SkillLatticeManager,
|
|
@@ -14255,7 +15371,6 @@ export {
|
|
|
14255
15371
|
formatReadResponse,
|
|
14256
15372
|
getAgentClient,
|
|
14257
15373
|
getAgentConfig,
|
|
14258
|
-
getAgentLattice,
|
|
14259
15374
|
getAllAgentConfigs,
|
|
14260
15375
|
getAllToolDefinitions,
|
|
14261
15376
|
getCheckpointSaver,
|
|
@@ -14292,6 +15407,7 @@ export {
|
|
|
14292
15407
|
performStringReplacement,
|
|
14293
15408
|
queueLatticeManager,
|
|
14294
15409
|
registerAgentLattice,
|
|
15410
|
+
registerAgentLatticeWithTenant,
|
|
14295
15411
|
registerAgentLattices,
|
|
14296
15412
|
registerCheckpointSaver,
|
|
14297
15413
|
registerChunkBuffer,
|