@dainprotocol/service-sdk 2.0.78 → 2.0.80
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/client/api-sdk.d.ts +5 -42
- package/dist/client/api-sdk.js +130 -261
- package/dist/client/api-sdk.js.map +1 -1
- package/dist/client/client-auth.d.ts +1 -69
- package/dist/client/client-auth.js +26 -105
- package/dist/client/client-auth.js.map +1 -1
- package/dist/client/client.d.ts +25 -116
- package/dist/client/client.js +157 -758
- package/dist/client/client.js.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/types.js +9 -14
- package/dist/client/types.js.map +1 -1
- package/dist/extensions/telegram-oauth.d.ts +6 -2
- package/dist/extensions/telegram-oauth.js +31 -333
- package/dist/extensions/telegram-oauth.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -26
- package/dist/index.js.map +1 -1
- package/dist/interfaces/index.d.ts +2 -0
- package/dist/lib/convertToVercelTool.d.ts +11 -3
- package/dist/lib/convertToVercelTool.js +0 -1
- package/dist/lib/convertToVercelTool.js.map +1 -1
- package/dist/lib/payments/index.d.ts +14 -23
- package/dist/lib/payments/index.js +33 -47
- package/dist/lib/payments/index.js.map +1 -1
- package/dist/lib/schemaConversion.d.ts +0 -14
- package/dist/lib/schemaConversion.js +26 -56
- package/dist/lib/schemaConversion.js.map +1 -1
- package/dist/lib/schemaStructure.d.ts +1 -7
- package/dist/lib/schemaStructure.js +26 -57
- package/dist/lib/schemaStructure.js.map +1 -1
- package/dist/plugins/base.d.ts +1 -29
- package/dist/plugins/base.js +1 -33
- package/dist/plugins/base.js.map +1 -1
- package/dist/plugins/citations-plugin.d.ts +6 -81
- package/dist/plugins/citations-plugin.js +46 -161
- package/dist/plugins/citations-plugin.js.map +1 -1
- package/dist/plugins/crypto-plugin.d.ts +18 -123
- package/dist/plugins/crypto-plugin.js +41 -248
- package/dist/plugins/crypto-plugin.js.map +1 -1
- package/dist/plugins/time-plugin.d.ts +8 -90
- package/dist/plugins/time-plugin.js +24 -131
- package/dist/plugins/time-plugin.js.map +1 -1
- package/dist/plugins/types.d.ts +5 -36
- package/dist/service/auth.d.ts +1 -49
- package/dist/service/auth.js +21 -99
- package/dist/service/auth.js.map +1 -1
- package/dist/service/cloudflareService.js +5 -6
- package/dist/service/cloudflareService.js.map +1 -1
- package/dist/service/core.js +23 -54
- package/dist/service/core.js.map +1 -1
- package/dist/service/denoService.js +14 -18
- package/dist/service/denoService.js.map +1 -1
- package/dist/service/nextService.d.ts +7 -10
- package/dist/service/nextService.js +18 -65
- package/dist/service/nextService.js.map +1 -1
- package/dist/service/nodeService.d.ts +1 -1
- package/dist/service/nodeService.js +18 -30
- package/dist/service/nodeService.js.map +1 -1
- package/dist/service/processes.d.ts +34 -36
- package/dist/service/processes.js +133 -285
- package/dist/service/processes.js.map +1 -1
- package/dist/service/server.d.ts +2 -9
- package/dist/service/server.js +164 -430
- package/dist/service/server.js.map +1 -1
- package/dist/service/webhooks.d.ts +15 -172
- package/dist/service/webhooks.js +52 -184
- package/dist/service/webhooks.js.map +1 -1
- package/package.json +1 -1
package/dist/client/client.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// File: src/client/client.ts
|
|
3
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
3
|
exports.DainServiceConnection = void 0;
|
|
5
4
|
const tslib_1 = require("tslib");
|
|
@@ -19,69 +18,75 @@ class DainServiceConnection {
|
|
|
19
18
|
this.baseUrl = baseUrl;
|
|
20
19
|
this.clientAuth = clientAuth;
|
|
21
20
|
this.plugins = options.plugins || [];
|
|
22
|
-
// Disable streaming by default to avoid QUIC protocol errors with tunneled connections
|
|
23
21
|
this.enableStreaming = options.enableStreaming ?? false;
|
|
24
22
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Returns the base URL of the connected service
|
|
27
|
-
* @returns The service's base URL as a string
|
|
28
|
-
*/
|
|
29
23
|
getURI() {
|
|
30
24
|
return this.baseUrl;
|
|
31
25
|
}
|
|
32
|
-
async
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const pluginData = await plugin.processInputClient(processedBody);
|
|
42
|
-
if (pluginData) {
|
|
43
|
-
processedBody.plugins[plugin.id] = pluginData;
|
|
44
|
-
}
|
|
26
|
+
async processPluginInput(body) {
|
|
27
|
+
if (this.plugins.length === 0)
|
|
28
|
+
return body;
|
|
29
|
+
const pluginsData = {};
|
|
30
|
+
for (const plugin of this.plugins) {
|
|
31
|
+
if (plugin.processInputClient) {
|
|
32
|
+
const pluginData = await plugin.processInputClient(body);
|
|
33
|
+
if (pluginData) {
|
|
34
|
+
pluginsData[plugin.id] = pluginData;
|
|
45
35
|
}
|
|
46
36
|
}
|
|
47
37
|
}
|
|
48
|
-
|
|
38
|
+
return { ...body, plugins: pluginsData };
|
|
39
|
+
}
|
|
40
|
+
async processPluginOutput(data) {
|
|
41
|
+
if (this.plugins.length === 0)
|
|
42
|
+
return data;
|
|
43
|
+
let processed = data;
|
|
44
|
+
for (const plugin of this.plugins) {
|
|
45
|
+
if (plugin.processOutputClient) {
|
|
46
|
+
processed = await plugin.processOutputClient(processed);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return processed;
|
|
50
|
+
}
|
|
51
|
+
extractDataFromPluginResponse(data, schema) {
|
|
52
|
+
if (!data || typeof data !== 'object' || !('plugins' in data)) {
|
|
53
|
+
return schema.parse(data);
|
|
54
|
+
}
|
|
55
|
+
const { plugins: _, ...rest } = data;
|
|
56
|
+
if (Object.keys(rest).length === 0) {
|
|
57
|
+
return schema.parse([]);
|
|
58
|
+
}
|
|
59
|
+
return schema.parse(Array.isArray(rest) ? rest : Object.values(rest));
|
|
60
|
+
}
|
|
61
|
+
extractSingleFromPluginResponse(data, schema) {
|
|
62
|
+
if (!data || typeof data !== 'object' || !('plugins' in data)) {
|
|
63
|
+
return schema.parse(data);
|
|
64
|
+
}
|
|
65
|
+
const { plugins: _, ...rest } = data;
|
|
66
|
+
return schema.parse(rest);
|
|
67
|
+
}
|
|
68
|
+
async makeRequest(method, path, body = {}) {
|
|
69
|
+
const processedBody = method === "POST"
|
|
70
|
+
? await this.processPluginInput(body)
|
|
71
|
+
: body;
|
|
49
72
|
try {
|
|
50
73
|
const response = await (0, axios_1.default)({
|
|
51
74
|
method,
|
|
52
|
-
url:
|
|
75
|
+
url: `${this.baseUrl}${path}`,
|
|
53
76
|
data: method === "POST" ? processedBody : undefined,
|
|
54
77
|
headers: {
|
|
55
78
|
"Content-Type": "application/json",
|
|
56
|
-
// "User-Agent": "DAIN-SERVICE-CLIENT/1.0.7",
|
|
57
79
|
...this.clientAuth.getHeaders(),
|
|
58
80
|
},
|
|
59
81
|
});
|
|
60
|
-
|
|
61
|
-
let processedResponse = response.data;
|
|
62
|
-
if (this.plugins.length > 0) {
|
|
63
|
-
for (const plugin of this.plugins) {
|
|
64
|
-
if (plugin.processOutputClient) {
|
|
65
|
-
processedResponse = await plugin.processOutputClient(processedResponse);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return processedResponse;
|
|
82
|
+
return this.processPluginOutput(response.data);
|
|
70
83
|
}
|
|
71
84
|
catch (error) {
|
|
72
85
|
if ((0, axios_1.isAxiosError)(error) && error.response) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
serverError = error.response.data;
|
|
78
|
-
}
|
|
79
|
-
else if (error.response.data?.message) {
|
|
80
|
-
serverError = error.response.data.message;
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
serverError = error.message;
|
|
84
|
-
}
|
|
86
|
+
const responseData = error.response.data;
|
|
87
|
+
const serverError = typeof responseData === 'string'
|
|
88
|
+
? responseData
|
|
89
|
+
: responseData?.message ?? error.message;
|
|
85
90
|
const customError = new Error(serverError);
|
|
86
91
|
customError.status = error.response.status;
|
|
87
92
|
throw customError;
|
|
@@ -95,56 +100,19 @@ class DainServiceConnection {
|
|
|
95
100
|
}
|
|
96
101
|
async getExampleQueries() {
|
|
97
102
|
try {
|
|
98
|
-
|
|
99
|
-
let requestBody = {};
|
|
100
|
-
if (this.plugins.length > 0) {
|
|
101
|
-
const pluginsData = {};
|
|
102
|
-
// Let each plugin process the input
|
|
103
|
-
for (const plugin of this.plugins) {
|
|
104
|
-
if (plugin.processInputClient) {
|
|
105
|
-
const pluginData = await plugin.processInputClient({});
|
|
106
|
-
if (pluginData) {
|
|
107
|
-
pluginsData[plugin.id] = pluginData;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
// Add plugins data to request body
|
|
112
|
-
requestBody = { plugins: pluginsData };
|
|
113
|
-
}
|
|
114
|
-
// Try POST first for better plugin support
|
|
103
|
+
const requestBody = await this.processPluginInput({});
|
|
115
104
|
try {
|
|
116
105
|
const data = await this.makeRequest("POST", "/exampleQueries", requestBody);
|
|
117
|
-
|
|
118
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && 'plugins' in data) {
|
|
119
|
-
// Process the plugin data if it exists
|
|
120
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
121
|
-
for (const plugin of this.plugins) {
|
|
122
|
-
if (plugin.processOutputClient) {
|
|
123
|
-
await plugin.processOutputClient(data);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
// The actual queries array is the original response (without the plugins property)
|
|
128
|
-
// Clone the data and delete the plugins property to get the original array
|
|
129
|
-
const queriesData = { ...data };
|
|
130
|
-
delete queriesData.plugins;
|
|
131
|
-
// If there are no properties left other than plugins, then the response was empty
|
|
132
|
-
if (Object.keys(queriesData).length === 0) {
|
|
133
|
-
return [];
|
|
134
|
-
}
|
|
135
|
-
// Try to parse what's left as an array of queries
|
|
136
|
-
return types_1.ExampleQueriesSchema.parse(Array.isArray(queriesData) ? queriesData : Object.values(queriesData));
|
|
137
|
-
}
|
|
138
|
-
return types_1.ExampleQueriesSchema.parse(data);
|
|
106
|
+
return this.extractDataFromPluginResponse(data, types_1.ExampleQueriesSchema);
|
|
139
107
|
}
|
|
140
|
-
catch
|
|
141
|
-
// Fall back to GET if POST fails
|
|
108
|
+
catch {
|
|
142
109
|
const data = await this.makeRequest("GET", "/exampleQueries");
|
|
143
110
|
return types_1.ExampleQueriesSchema.parse(data);
|
|
144
111
|
}
|
|
145
112
|
}
|
|
146
113
|
catch (error) {
|
|
147
|
-
|
|
114
|
+
const err = error;
|
|
115
|
+
if (err?.response?.status === 404) {
|
|
148
116
|
return [];
|
|
149
117
|
}
|
|
150
118
|
throw error;
|
|
@@ -173,336 +141,59 @@ class DainServiceConnection {
|
|
|
173
141
|
async getContexts() {
|
|
174
142
|
return this.listContexts();
|
|
175
143
|
}
|
|
176
|
-
/**
|
|
177
|
-
* List contexts using POST to send plugins data in request body
|
|
178
|
-
* This is the primary method to get context data, especially when using plugins
|
|
179
|
-
*/
|
|
180
144
|
async listContexts() {
|
|
181
|
-
|
|
182
|
-
let requestBody = {};
|
|
183
|
-
if (this.plugins.length > 0) {
|
|
184
|
-
const pluginsData = {};
|
|
185
|
-
// Let each plugin process the input
|
|
186
|
-
for (const plugin of this.plugins) {
|
|
187
|
-
if (plugin.processInputClient) {
|
|
188
|
-
const pluginData = await plugin.processInputClient({});
|
|
189
|
-
if (pluginData) {
|
|
190
|
-
pluginsData[plugin.id] = pluginData;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
// Add plugins data to request body
|
|
195
|
-
requestBody = { plugins: pluginsData };
|
|
196
|
-
}
|
|
145
|
+
const requestBody = await this.processPluginInput({});
|
|
197
146
|
const data = await this.makeRequest("POST", `/contexts/list`, requestBody);
|
|
198
147
|
return zod_1.z.array(types_1.ServiceContextSchema).parse(data);
|
|
199
148
|
}
|
|
200
|
-
/**
|
|
201
|
-
* Get all context data using POST to send plugins data in request body
|
|
202
|
-
* This is the primary method to get all context data, especially when using plugins
|
|
203
|
-
*/
|
|
204
149
|
async postAllContexts() {
|
|
205
|
-
|
|
206
|
-
let requestBody = {};
|
|
207
|
-
if (this.plugins.length > 0) {
|
|
208
|
-
const pluginsData = {};
|
|
209
|
-
// Let each plugin process the input
|
|
210
|
-
for (const plugin of this.plugins) {
|
|
211
|
-
if (plugin.processInputClient) {
|
|
212
|
-
const pluginData = await plugin.processInputClient({});
|
|
213
|
-
if (pluginData) {
|
|
214
|
-
pluginsData[plugin.id] = pluginData;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
// Add plugins data to request body
|
|
219
|
-
requestBody = { plugins: pluginsData };
|
|
220
|
-
}
|
|
150
|
+
const requestBody = await this.processPluginInput({});
|
|
221
151
|
const data = await this.makeRequest("POST", `/contexts`, requestBody);
|
|
222
|
-
|
|
223
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && 'plugins' in data) {
|
|
224
|
-
// Process the plugin data if it exists
|
|
225
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
226
|
-
for (const plugin of this.plugins) {
|
|
227
|
-
if (plugin.processOutputClient) {
|
|
228
|
-
await plugin.processOutputClient(data);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
// The actual contexts array is the original response (without the plugins property)
|
|
233
|
-
// Clone the data and delete the plugins property to get the original array
|
|
234
|
-
const contextData = { ...data };
|
|
235
|
-
delete contextData.plugins;
|
|
236
|
-
// If there are no properties left other than plugins, then the response was empty
|
|
237
|
-
if (Object.keys(contextData).length === 0) {
|
|
238
|
-
return [];
|
|
239
|
-
}
|
|
240
|
-
// Try to parse what's left as an array of contexts
|
|
241
|
-
return zod_1.z.array(types_1.ServiceContextWithDataSchema).parse(Array.isArray(contextData) ? contextData : Object.values(contextData));
|
|
242
|
-
}
|
|
243
|
-
// Otherwise, try to parse the whole response as an array of contexts
|
|
244
|
-
return zod_1.z.array(types_1.ServiceContextWithDataSchema).parse(data);
|
|
152
|
+
return this.extractDataFromPluginResponse(data, zod_1.z.array(types_1.ServiceContextWithDataSchema));
|
|
245
153
|
}
|
|
246
|
-
/**
|
|
247
|
-
* Get context data using POST to send plugins data in request body
|
|
248
|
-
* This is the primary method to get context data, especially when using plugins
|
|
249
|
-
*/
|
|
250
154
|
async getContext(contextId) {
|
|
251
|
-
|
|
252
|
-
let requestBody = {};
|
|
253
|
-
if (this.plugins.length > 0) {
|
|
254
|
-
const pluginsData = {};
|
|
255
|
-
// Let each plugin process the input
|
|
256
|
-
for (const plugin of this.plugins) {
|
|
257
|
-
if (plugin.processInputClient) {
|
|
258
|
-
const pluginData = await plugin.processInputClient({});
|
|
259
|
-
if (pluginData) {
|
|
260
|
-
pluginsData[plugin.id] = pluginData;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
// Add plugins data to request body
|
|
265
|
-
requestBody = { plugins: pluginsData };
|
|
266
|
-
}
|
|
155
|
+
const requestBody = await this.processPluginInput({});
|
|
267
156
|
const data = await this.makeRequest("POST", `/contexts/${contextId}`, requestBody);
|
|
268
|
-
|
|
269
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && 'plugins' in data) {
|
|
270
|
-
// Process the plugin data if it exists
|
|
271
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
272
|
-
for (const plugin of this.plugins) {
|
|
273
|
-
if (plugin.processOutputClient) {
|
|
274
|
-
await plugin.processOutputClient(data);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
// The actual context object is the original response (without the plugins property)
|
|
279
|
-
// Clone the data and delete the plugins property to get the original object
|
|
280
|
-
const contextData = { ...data };
|
|
281
|
-
delete contextData.plugins;
|
|
282
|
-
// Try to parse what's left as a context object
|
|
283
|
-
return types_1.ServiceContextWithDataSchema.parse(contextData);
|
|
284
|
-
}
|
|
285
|
-
// Otherwise, try to parse the whole response as a context
|
|
286
|
-
return types_1.ServiceContextWithDataSchema.parse(data);
|
|
157
|
+
return this.extractSingleFromPluginResponse(data, types_1.ServiceContextWithDataSchema);
|
|
287
158
|
}
|
|
288
159
|
async getAllContexts() {
|
|
289
|
-
// Use the POST implementation
|
|
290
160
|
return this.postAllContexts();
|
|
291
161
|
}
|
|
292
|
-
/**
|
|
293
|
-
* Get widget IDs for the current user using POST to send plugins data in request body
|
|
294
|
-
* This is the primary method to get widget IDs, especially when using plugins
|
|
295
|
-
*/
|
|
296
162
|
async getWidgets() {
|
|
297
|
-
|
|
298
|
-
let requestBody = {};
|
|
299
|
-
if (this.plugins.length > 0) {
|
|
300
|
-
const pluginsData = {};
|
|
301
|
-
// Let each plugin process the input
|
|
302
|
-
for (const plugin of this.plugins) {
|
|
303
|
-
if (plugin.processInputClient) {
|
|
304
|
-
const pluginData = await plugin.processInputClient({});
|
|
305
|
-
if (pluginData) {
|
|
306
|
-
pluginsData[plugin.id] = pluginData;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
// Add plugins data to request body
|
|
311
|
-
requestBody = { plugins: pluginsData };
|
|
312
|
-
}
|
|
163
|
+
const requestBody = await this.processPluginInput({});
|
|
313
164
|
const data = await this.makeRequest("POST", `/widgets`, requestBody);
|
|
314
|
-
|
|
315
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && 'plugins' in data) {
|
|
316
|
-
// Process the plugin data if it exists
|
|
317
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
318
|
-
for (const plugin of this.plugins) {
|
|
319
|
-
if (plugin.processOutputClient) {
|
|
320
|
-
await plugin.processOutputClient(data);
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
// The actual widget IDs array is the original response (without the plugins property)
|
|
325
|
-
// Clone the data and delete the plugins property to get the original array
|
|
326
|
-
const widgetData = { ...data };
|
|
327
|
-
delete widgetData.plugins;
|
|
328
|
-
// If there are no properties left other than plugins, then the response was empty
|
|
329
|
-
if (Object.keys(widgetData).length === 0) {
|
|
330
|
-
return [];
|
|
331
|
-
}
|
|
332
|
-
// Try to parse what's left as an array of widget IDs
|
|
333
|
-
return zod_1.z.array(zod_1.z.string()).parse(Array.isArray(widgetData) ? widgetData : Object.values(widgetData));
|
|
334
|
-
}
|
|
335
|
-
return zod_1.z.array(zod_1.z.string()).parse(data);
|
|
165
|
+
return this.extractDataFromPluginResponse(data, zod_1.z.array(zod_1.z.string()));
|
|
336
166
|
}
|
|
337
|
-
/**
|
|
338
|
-
* Get widget data using POST to send plugins data in request body
|
|
339
|
-
* This is the primary method to get widget data, especially when using plugins
|
|
340
|
-
*/
|
|
341
167
|
async getWidget(widgetId) {
|
|
342
|
-
|
|
343
|
-
let requestBody = {};
|
|
344
|
-
if (this.plugins.length > 0) {
|
|
345
|
-
const pluginsData = {};
|
|
346
|
-
// Let each plugin process the input
|
|
347
|
-
for (const plugin of this.plugins) {
|
|
348
|
-
if (plugin.processInputClient) {
|
|
349
|
-
const pluginData = await plugin.processInputClient({});
|
|
350
|
-
if (pluginData) {
|
|
351
|
-
pluginsData[plugin.id] = pluginData;
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
// Add plugins data to request body
|
|
356
|
-
requestBody = { plugins: pluginsData };
|
|
357
|
-
}
|
|
168
|
+
const requestBody = await this.processPluginInput({});
|
|
358
169
|
const data = await this.makeRequest("POST", `/widgets/${widgetId}`, requestBody);
|
|
359
|
-
|
|
360
|
-
if (data && typeof data === 'object' && 'plugins' in data) {
|
|
361
|
-
// Process the plugin data if it exists
|
|
362
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
363
|
-
for (const plugin of this.plugins) {
|
|
364
|
-
if (plugin.processOutputClient) {
|
|
365
|
-
await plugin.processOutputClient(data);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
// The actual widget object is the original response (without the plugins property)
|
|
370
|
-
// Clone the data and delete the plugins property to get the original object
|
|
371
|
-
const widgetData = { ...data };
|
|
372
|
-
delete widgetData.plugins;
|
|
373
|
-
// Try to parse what's left as a widget object
|
|
374
|
-
return types_1.ServiceWidgetWithDataSchema.parse(widgetData);
|
|
375
|
-
}
|
|
376
|
-
// Otherwise, try to parse the whole response as a widget
|
|
377
|
-
return types_1.ServiceWidgetWithDataSchema.parse(data);
|
|
170
|
+
return this.extractSingleFromPluginResponse(data, types_1.ServiceWidgetWithDataSchema);
|
|
378
171
|
}
|
|
379
|
-
/**
|
|
380
|
-
* Get all widgets with data using POST to send plugins data in request body
|
|
381
|
-
* This is the primary method to get all widgets with data, especially when using plugins
|
|
382
|
-
*/
|
|
383
172
|
async getAllWidgets() {
|
|
384
|
-
// Use the POST implementation
|
|
385
173
|
return this.postAllWidgets();
|
|
386
174
|
}
|
|
387
|
-
/**
|
|
388
|
-
* Get all widgets with their data using POST to send plugins data in request body
|
|
389
|
-
* This is the primary method to get widget data, especially when using plugins
|
|
390
|
-
*/
|
|
391
175
|
async postAllWidgets() {
|
|
392
|
-
|
|
393
|
-
let requestBody = {};
|
|
394
|
-
if (this.plugins.length > 0) {
|
|
395
|
-
const pluginsData = {};
|
|
396
|
-
// Let each plugin process the input
|
|
397
|
-
for (const plugin of this.plugins) {
|
|
398
|
-
if (plugin.processInputClient) {
|
|
399
|
-
const pluginData = await plugin.processInputClient({});
|
|
400
|
-
if (pluginData) {
|
|
401
|
-
pluginsData[plugin.id] = pluginData;
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
// Add plugins data to request body
|
|
406
|
-
requestBody = { plugins: pluginsData };
|
|
407
|
-
}
|
|
176
|
+
const requestBody = await this.processPluginInput({});
|
|
408
177
|
const data = await this.makeRequest("POST", `/widgets/all`, requestBody);
|
|
409
|
-
|
|
410
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && 'plugins' in data) {
|
|
411
|
-
// Process the plugin data if it exists
|
|
412
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
413
|
-
for (const plugin of this.plugins) {
|
|
414
|
-
if (plugin.processOutputClient) {
|
|
415
|
-
await plugin.processOutputClient(data);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
// The actual widgets array is the original response (without the plugins property)
|
|
420
|
-
// Clone the data and delete the plugins property to get the original array
|
|
421
|
-
const widgetsData = { ...data };
|
|
422
|
-
delete widgetsData.plugins;
|
|
423
|
-
// If there are no properties left other than plugins, then the response was empty
|
|
424
|
-
if (Object.keys(widgetsData).length === 0) {
|
|
425
|
-
return [];
|
|
426
|
-
}
|
|
427
|
-
// Try to parse what's left as an array of widgets
|
|
428
|
-
return zod_1.z.array(types_1.ServiceWidgetWithDataSchema).parse(Array.isArray(widgetsData) ? widgetsData : Object.values(widgetsData));
|
|
429
|
-
}
|
|
430
|
-
// Otherwise, try to parse the whole response as an array of widgets
|
|
431
|
-
return zod_1.z.array(types_1.ServiceWidgetWithDataSchema).parse(data);
|
|
178
|
+
return this.extractDataFromPluginResponse(data, zod_1.z.array(types_1.ServiceWidgetWithDataSchema));
|
|
432
179
|
}
|
|
433
|
-
/**
|
|
434
|
-
* Get the home UI widget ID for the current user
|
|
435
|
-
* Returns null if no home UI is configured
|
|
436
|
-
*/
|
|
437
180
|
async getHomeUI() {
|
|
438
|
-
|
|
439
|
-
let requestBody = {};
|
|
440
|
-
if (this.plugins.length > 0) {
|
|
441
|
-
const pluginsData = {};
|
|
442
|
-
// Let each plugin process the input
|
|
443
|
-
for (const plugin of this.plugins) {
|
|
444
|
-
if (plugin.processInputClient) {
|
|
445
|
-
const pluginData = await plugin.processInputClient({});
|
|
446
|
-
if (pluginData) {
|
|
447
|
-
pluginsData[plugin.id] = pluginData;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
requestBody = { plugins: pluginsData };
|
|
452
|
-
}
|
|
181
|
+
const requestBody = await this.processPluginInput({});
|
|
453
182
|
const response = await this.makeRequest("POST", "/homeUI", requestBody);
|
|
454
|
-
|
|
455
|
-
if (!response.widgetId) {
|
|
456
|
-
return null;
|
|
457
|
-
}
|
|
458
|
-
return response.widgetId;
|
|
183
|
+
return response?.widgetId ?? null;
|
|
459
184
|
}
|
|
460
|
-
/**
|
|
461
|
-
* Get all tools as JSON schema using POST to send plugins data in request body
|
|
462
|
-
* This is the primary method to get all tools as JSON schema, especially when using plugins
|
|
463
|
-
*/
|
|
464
185
|
async getAllToolsAsJsonSchema() {
|
|
465
|
-
|
|
466
|
-
let requestBody = {};
|
|
467
|
-
if (this.plugins.length > 0) {
|
|
468
|
-
const pluginsData = {};
|
|
469
|
-
// Let each plugin process the input
|
|
470
|
-
for (const plugin of this.plugins) {
|
|
471
|
-
if (plugin.processInputClient) {
|
|
472
|
-
const pluginData = await plugin.processInputClient({});
|
|
473
|
-
if (pluginData) {
|
|
474
|
-
pluginsData[plugin.id] = pluginData;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
// Add plugins data to request body
|
|
479
|
-
requestBody = { plugins: pluginsData };
|
|
480
|
-
}
|
|
186
|
+
const requestBody = await this.processPluginInput({});
|
|
481
187
|
const data = await this.makeRequest("POST", "/getAllToolsAsJsonSchema", requestBody);
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
if (this.plugins.length > 0) {
|
|
486
|
-
for (const plugin of this.plugins) {
|
|
487
|
-
if (plugin.processOutputClient) {
|
|
488
|
-
await plugin.processOutputClient(data);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
// The actual tools schema is the original response (without the plugins property)
|
|
493
|
-
// Clone the data and delete the plugins property to get the original object
|
|
494
|
-
const toolsData = { ...data };
|
|
495
|
-
delete toolsData.plugins;
|
|
496
|
-
// If the object has both tools and reccomendedPrompts properties, assume it's a valid response
|
|
497
|
-
if ('tools' in toolsData && 'reccomendedPrompts' in toolsData &&
|
|
498
|
-
Array.isArray(toolsData.tools) && Array.isArray(toolsData.reccomendedPrompts)) {
|
|
188
|
+
if (data && typeof data === 'object' && 'plugins' in data) {
|
|
189
|
+
const { plugins: _, tools, reccomendedPrompts, ...rest } = data;
|
|
190
|
+
if (Array.isArray(tools) && Array.isArray(reccomendedPrompts)) {
|
|
499
191
|
return {
|
|
500
|
-
tools:
|
|
501
|
-
reccomendedPrompts:
|
|
192
|
+
tools: tools,
|
|
193
|
+
reccomendedPrompts: reccomendedPrompts
|
|
502
194
|
};
|
|
503
195
|
}
|
|
504
196
|
}
|
|
505
|
-
// Otherwise, try to parse the whole response
|
|
506
197
|
const returned = types_1.GetAllToolsAsJsonSchemaResponseSchema.parse(data);
|
|
507
198
|
return {
|
|
508
199
|
tools: returned.tools,
|
|
@@ -534,63 +225,24 @@ class DainServiceConnection {
|
|
|
534
225
|
});
|
|
535
226
|
}
|
|
536
227
|
async callTool(toolId, params, options) {
|
|
537
|
-
|
|
538
|
-
let processedParams = { ...params };
|
|
539
|
-
if (this.plugins.length > 0) {
|
|
540
|
-
// Add plugins data container
|
|
541
|
-
processedParams.plugins = processedParams.plugins || {};
|
|
542
|
-
// Let each plugin process the input
|
|
543
|
-
for (const plugin of this.plugins) {
|
|
544
|
-
if (plugin.processInputClient) {
|
|
545
|
-
const pluginData = await plugin.processInputClient(processedParams);
|
|
546
|
-
if (pluginData) {
|
|
547
|
-
processedParams.plugins[plugin.id] = pluginData;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
// Use streaming when explicitly enabled (callbacks are optional)
|
|
228
|
+
const processedParams = await this.processPluginInput(params);
|
|
553
229
|
if (this.enableStreaming) {
|
|
554
230
|
const streamedResult = await this._callToolWithStreaming(toolId, processedParams, `/tools/${toolId}`, options);
|
|
555
231
|
return this.sanitizeToolResponse(streamedResult, options);
|
|
556
232
|
}
|
|
557
|
-
// Use regular JSON request (default behavior)
|
|
558
233
|
const response = await this.makeRequest("POST", `/tools/${toolId}`, processedParams);
|
|
559
234
|
return this.sanitizeToolResponse(response, options);
|
|
560
235
|
}
|
|
561
236
|
async callToolAndGetNewContext(toolId, params, options) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
if (this.plugins.length > 0) {
|
|
565
|
-
// Add plugins data container
|
|
566
|
-
processedParams.plugins = processedParams.plugins || {};
|
|
567
|
-
// Let each plugin process the input
|
|
568
|
-
for (const plugin of this.plugins) {
|
|
569
|
-
if (plugin.processInputClient) {
|
|
570
|
-
const pluginData = await plugin.processInputClient(processedParams);
|
|
571
|
-
if (pluginData) {
|
|
572
|
-
processedParams.plugins[plugin.id] = pluginData;
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
}
|
|
577
|
-
// Use streaming when explicitly enabled (callbacks are optional)
|
|
237
|
+
const processedParams = await this.processPluginInput(params);
|
|
238
|
+
const endpoint = `/tools/${toolId}/executeAndGetNewContext`;
|
|
578
239
|
if (this.enableStreaming) {
|
|
579
|
-
const streamedResult = await this._callToolWithStreaming(toolId, processedParams,
|
|
580
|
-
return this.sanitizeToolResponse(streamedResult, options, {
|
|
581
|
-
stripToolResultSuccess: true,
|
|
582
|
-
});
|
|
240
|
+
const streamedResult = await this._callToolWithStreaming(toolId, processedParams, endpoint, options);
|
|
241
|
+
return this.sanitizeToolResponse(streamedResult, options, { stripToolResultSuccess: true });
|
|
583
242
|
}
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
return this.sanitizeToolResponse(response, options, {
|
|
587
|
-
stripToolResultSuccess: true,
|
|
588
|
-
});
|
|
243
|
+
const response = await this.makeRequest("POST", endpoint, processedParams);
|
|
244
|
+
return this.sanitizeToolResponse(response, options, { stripToolResultSuccess: true });
|
|
589
245
|
}
|
|
590
|
-
/**
|
|
591
|
-
* Shared implementation for streaming tool calls
|
|
592
|
-
* @private
|
|
593
|
-
*/
|
|
594
246
|
async _callToolWithStreaming(toolId, params, endpoint, options = {}) {
|
|
595
247
|
const abortController = new AbortController();
|
|
596
248
|
const response = await fetch(`${this.baseUrl}${endpoint}`, {
|
|
@@ -604,21 +256,10 @@ class DainServiceConnection {
|
|
|
604
256
|
signal: abortController.signal,
|
|
605
257
|
});
|
|
606
258
|
const contentType = response.headers.get('content-type') || '';
|
|
607
|
-
// If server doesn't support streaming, it will respond with regular JSON
|
|
608
259
|
if (contentType.includes('application/json')) {
|
|
609
260
|
const data = await response.json();
|
|
610
|
-
|
|
611
|
-
let processedResponse = data;
|
|
612
|
-
if (this.plugins.length > 0) {
|
|
613
|
-
for (const plugin of this.plugins) {
|
|
614
|
-
if (plugin.processOutputClient) {
|
|
615
|
-
processedResponse = await plugin.processOutputClient(processedResponse);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
return processedResponse;
|
|
261
|
+
return this.processPluginOutput(data);
|
|
620
262
|
}
|
|
621
|
-
// Check for error responses
|
|
622
263
|
if (!response.ok) {
|
|
623
264
|
if (contentType.includes('application/json')) {
|
|
624
265
|
const errorData = await response.json();
|
|
@@ -627,19 +268,16 @@ class DainServiceConnection {
|
|
|
627
268
|
throw new Error(`HTTP error: ${response.status} ${response.statusText}`);
|
|
628
269
|
}
|
|
629
270
|
const reader = response.body?.getReader();
|
|
630
|
-
const decoder = new TextDecoder();
|
|
631
|
-
let buffer = '';
|
|
632
271
|
if (!reader)
|
|
633
272
|
throw new Error('No response body');
|
|
634
|
-
|
|
273
|
+
const decoder = new TextDecoder();
|
|
274
|
+
let buffer = '';
|
|
635
275
|
let receivedResult = false;
|
|
636
276
|
let receivedAnyChunk = false;
|
|
637
277
|
let receivedAnyEvent = false;
|
|
638
|
-
// SSE parsing state - MUST persist across processSSEEvents calls
|
|
639
|
-
// because event: and data: lines may arrive in different TCP packets
|
|
640
278
|
let currentEvent = null;
|
|
641
279
|
let currentDataLines = [];
|
|
642
|
-
const stripFieldValue = (value) =>
|
|
280
|
+
const stripFieldValue = (value) => value.startsWith(' ') ? value.slice(1) : value;
|
|
643
281
|
const normalizeProgressUpdate = (data) => {
|
|
644
282
|
if (typeof data === 'string')
|
|
645
283
|
return { text: data };
|
|
@@ -651,6 +289,31 @@ class DainServiceConnection {
|
|
|
651
289
|
}
|
|
652
290
|
return { text: String(data ?? '') };
|
|
653
291
|
};
|
|
292
|
+
const processEventData = async (eventType, data) => {
|
|
293
|
+
const processedData = eventType === 'result'
|
|
294
|
+
? await this.processPluginOutput(data)
|
|
295
|
+
: data;
|
|
296
|
+
switch (eventType) {
|
|
297
|
+
case 'uipage-update':
|
|
298
|
+
options.onUIUpdate?.(processedData);
|
|
299
|
+
break;
|
|
300
|
+
case 'process-created': {
|
|
301
|
+
const processId = typeof processedData === 'string'
|
|
302
|
+
? processedData
|
|
303
|
+
: processedData?.processId;
|
|
304
|
+
if (processId)
|
|
305
|
+
options.onProcess?.(processId);
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
case 'progress':
|
|
309
|
+
options.onProgress?.(normalizeProgressUpdate(processedData));
|
|
310
|
+
break;
|
|
311
|
+
case 'result':
|
|
312
|
+
receivedResult = true;
|
|
313
|
+
return processedData;
|
|
314
|
+
}
|
|
315
|
+
return null;
|
|
316
|
+
};
|
|
654
317
|
const handleEvent = async (eventType, rawData) => {
|
|
655
318
|
receivedAnyEvent = true;
|
|
656
319
|
let wrappedData = rawData;
|
|
@@ -668,67 +331,23 @@ class DainServiceConnection {
|
|
|
668
331
|
: wrappedData?.message || rawData || 'Unknown SSE error';
|
|
669
332
|
throw new Error(`SSE error: ${message}`);
|
|
670
333
|
}
|
|
671
|
-
const isSignedPayload = wrappedData &&
|
|
334
|
+
const isSignedPayload = wrappedData &&
|
|
335
|
+
typeof wrappedData === 'object' &&
|
|
336
|
+
'_signature' in wrappedData;
|
|
672
337
|
if (isSignedPayload) {
|
|
673
|
-
const
|
|
338
|
+
const signedData = wrappedData;
|
|
339
|
+
const { signature, timestamp, address } = signedData._signature || {};
|
|
674
340
|
const shouldVerify = eventType === 'result' || eventType === 'process-created';
|
|
675
|
-
if (shouldVerify) {
|
|
676
|
-
const dataString = JSON.stringify(
|
|
341
|
+
if (shouldVerify && signature && timestamp && address) {
|
|
342
|
+
const dataString = JSON.stringify(signedData.data);
|
|
677
343
|
const isSignatureValid = this.clientAuth.verifyEventSignature(dataString, signature, timestamp, address);
|
|
678
344
|
if (!isSignatureValid) {
|
|
679
345
|
console.warn(`SSE event signature verification failed for ${eventType}`);
|
|
680
346
|
}
|
|
681
347
|
}
|
|
682
|
-
|
|
683
|
-
if (eventType === 'result' && this.plugins.length > 0) {
|
|
684
|
-
for (const plugin of this.plugins) {
|
|
685
|
-
if (plugin.processOutputClient) {
|
|
686
|
-
data = await plugin.processOutputClient(data);
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
if (eventType === 'uipage-update' && options.onUIUpdate) {
|
|
691
|
-
options.onUIUpdate(data);
|
|
692
|
-
}
|
|
693
|
-
else if (eventType === 'process-created' && options.onProcess) {
|
|
694
|
-
const processId = typeof data === 'string' ? data : data?.processId;
|
|
695
|
-
if (processId)
|
|
696
|
-
options.onProcess(processId);
|
|
697
|
-
}
|
|
698
|
-
else if (eventType === 'progress' && options.onProgress) {
|
|
699
|
-
options.onProgress(normalizeProgressUpdate(data));
|
|
700
|
-
}
|
|
701
|
-
else if (eventType === 'result') {
|
|
702
|
-
receivedResult = true;
|
|
703
|
-
return data;
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
else {
|
|
707
|
-
let data = wrappedData;
|
|
708
|
-
if (eventType === 'result' && this.plugins.length > 0) {
|
|
709
|
-
for (const plugin of this.plugins) {
|
|
710
|
-
if (plugin.processOutputClient) {
|
|
711
|
-
data = await plugin.processOutputClient(data);
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
if (eventType === 'uipage-update' && options.onUIUpdate) {
|
|
716
|
-
options.onUIUpdate(data);
|
|
717
|
-
}
|
|
718
|
-
else if (eventType === 'process-created' && options.onProcess) {
|
|
719
|
-
const processId = typeof data === 'string' ? data : data?.processId;
|
|
720
|
-
if (processId)
|
|
721
|
-
options.onProcess(processId);
|
|
722
|
-
}
|
|
723
|
-
else if (eventType === 'progress' && options.onProgress) {
|
|
724
|
-
options.onProgress(normalizeProgressUpdate(data));
|
|
725
|
-
}
|
|
726
|
-
else if (eventType === 'result') {
|
|
727
|
-
receivedResult = true;
|
|
728
|
-
return data;
|
|
729
|
-
}
|
|
348
|
+
return processEventData(eventType, signedData.data);
|
|
730
349
|
}
|
|
731
|
-
return
|
|
350
|
+
return processEventData(eventType, wrappedData);
|
|
732
351
|
};
|
|
733
352
|
const flushEvent = async () => {
|
|
734
353
|
if (!currentEvent && currentDataLines.length === 0)
|
|
@@ -760,9 +379,7 @@ class DainServiceConnection {
|
|
|
760
379
|
return null;
|
|
761
380
|
};
|
|
762
381
|
const readWithTimeout = async () => {
|
|
763
|
-
const timeoutId = setTimeout(() =>
|
|
764
|
-
abortController.abort();
|
|
765
|
-
}, this.streamIdleTimeoutMs);
|
|
382
|
+
const timeoutId = setTimeout(() => abortController.abort(), this.streamIdleTimeoutMs);
|
|
766
383
|
try {
|
|
767
384
|
return await reader.read();
|
|
768
385
|
}
|
|
@@ -815,6 +432,8 @@ class DainServiceConnection {
|
|
|
815
432
|
}
|
|
816
433
|
throw new Error('Stream ended without result');
|
|
817
434
|
}
|
|
435
|
+
// Should be unreachable - receivedResult is true means we returned from processEventData
|
|
436
|
+
throw new Error('Unexpected state: received result but did not return');
|
|
818
437
|
}
|
|
819
438
|
createVercelAIToolWithoutExecute(toolInfo) {
|
|
820
439
|
return (0, ai_1.tool)({
|
|
@@ -825,20 +444,26 @@ class DainServiceConnection {
|
|
|
825
444
|
async getProcessStatus(processId) {
|
|
826
445
|
try {
|
|
827
446
|
const data = await this.makeRequest("GET", `/processes/${processId}/status`);
|
|
828
|
-
// Convert createdAt strings to Date objects
|
|
829
447
|
if (data.updates) {
|
|
830
|
-
|
|
831
|
-
...
|
|
832
|
-
|
|
833
|
-
|
|
448
|
+
return {
|
|
449
|
+
...data,
|
|
450
|
+
updates: data.updates.map(update => ({
|
|
451
|
+
...update,
|
|
452
|
+
createdAt: new Date(update.createdAt),
|
|
453
|
+
})),
|
|
454
|
+
};
|
|
834
455
|
}
|
|
835
|
-
return
|
|
456
|
+
return {
|
|
457
|
+
...data,
|
|
458
|
+
updates: [],
|
|
459
|
+
};
|
|
836
460
|
}
|
|
837
461
|
catch (error) {
|
|
838
|
-
|
|
462
|
+
const err = error;
|
|
463
|
+
if (err?.response?.status === 404) {
|
|
839
464
|
return null;
|
|
840
465
|
}
|
|
841
|
-
if (
|
|
466
|
+
if (err?.response?.status === 403) {
|
|
842
467
|
throw new Error("Unauthorized access to process");
|
|
843
468
|
}
|
|
844
469
|
throw error;
|
|
@@ -848,10 +473,6 @@ class DainServiceConnection {
|
|
|
848
473
|
const data = await this.makeRequest("GET", "/oauth2/providers");
|
|
849
474
|
return zod_1.z.array(types_1.OAuth2ProviderInfoSchema).parse(data);
|
|
850
475
|
}
|
|
851
|
-
/**
|
|
852
|
-
* Get all authentication providers (OAuth2 + Direct)
|
|
853
|
-
* Returns unified provider information with type discrimination
|
|
854
|
-
*/
|
|
855
476
|
async getAuthenticationProviders() {
|
|
856
477
|
const data = await this.makeRequest("GET", "/oauth2/authentication-providers");
|
|
857
478
|
return zod_1.z.array(types_1.ProviderInfoSchema).parse(data);
|
|
@@ -860,26 +481,16 @@ class DainServiceConnection {
|
|
|
860
481
|
const data = await this.makeRequest("GET", `/oauth2/connect/${provider}`);
|
|
861
482
|
return zod_1.z.object({ authUrl: zod_1.z.string() }).parse(data).authUrl;
|
|
862
483
|
}
|
|
863
|
-
/**
|
|
864
|
-
* Get direct auth setup status for a provider (RFC 8628 Device Authorization Grant)
|
|
865
|
-
* Used to poll for completion when user completes auth on external device (e.g., Telegram)
|
|
866
|
-
*
|
|
867
|
-
* @param provider - Provider name (e.g., 'telegram')
|
|
868
|
-
* @returns Setup status with completion info or pending state
|
|
869
|
-
*/
|
|
870
484
|
async getDirectAuthStatus(provider) {
|
|
871
485
|
const data = await this.makeRequest("GET", `/oauth2/direct-setup-status/${provider}`);
|
|
872
486
|
return types_1.DirectAuthStatusSchema.parse(data);
|
|
873
487
|
}
|
|
874
|
-
// Get all human actions for a process
|
|
875
488
|
async getProcessHumanActions(processId) {
|
|
876
489
|
return this.makeRequest("GET", `/processes/${processId}/human-actions`);
|
|
877
490
|
}
|
|
878
|
-
// Get specific human action
|
|
879
491
|
async getHumanAction(processId, stepId) {
|
|
880
492
|
return this.makeRequest("GET", `/processes/${processId}/human-actions/${stepId}`);
|
|
881
493
|
}
|
|
882
|
-
// Respond to human action
|
|
883
494
|
async respondToHumanAction(processId, stepId, actionId, responseText, data) {
|
|
884
495
|
return this.makeRequest("POST", `/processes/${processId}/human-actions/${stepId}/respond`, {
|
|
885
496
|
actionId,
|
|
@@ -888,275 +499,63 @@ class DainServiceConnection {
|
|
|
888
499
|
});
|
|
889
500
|
}
|
|
890
501
|
async getToolConfirmation(toolId, input) {
|
|
891
|
-
|
|
892
|
-
return response;
|
|
502
|
+
return this.makeRequest("POST", `/tools/${toolId}/confirmation`, input);
|
|
893
503
|
}
|
|
894
|
-
/**
|
|
895
|
-
* List datasources using POST to send plugins data in request body
|
|
896
|
-
* This is the primary method to get datasource data, especially when using plugins
|
|
897
|
-
*/
|
|
898
504
|
async listDatasources() {
|
|
899
|
-
|
|
900
|
-
let requestBody = {};
|
|
901
|
-
if (this.plugins.length > 0) {
|
|
902
|
-
const pluginsData = {};
|
|
903
|
-
// Let each plugin process the input
|
|
904
|
-
for (const plugin of this.plugins) {
|
|
905
|
-
if (plugin.processInputClient) {
|
|
906
|
-
const pluginData = await plugin.processInputClient({});
|
|
907
|
-
if (pluginData) {
|
|
908
|
-
pluginsData[plugin.id] = pluginData;
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
// Add plugins data to request body
|
|
913
|
-
requestBody = { plugins: pluginsData };
|
|
914
|
-
}
|
|
505
|
+
const requestBody = await this.processPluginInput({});
|
|
915
506
|
const data = await this.makeRequest("POST", `/datasources/list`, requestBody);
|
|
916
|
-
|
|
917
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && 'plugins' in data) {
|
|
918
|
-
// Process the plugin data if it exists
|
|
919
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
920
|
-
for (const plugin of this.plugins) {
|
|
921
|
-
if (plugin.processOutputClient) {
|
|
922
|
-
await plugin.processOutputClient(data);
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
// The actual datasources array is the original response (without the plugins property)
|
|
927
|
-
// Clone the data and delete the plugins property to get the original array
|
|
928
|
-
const datasourcesData = { ...data };
|
|
929
|
-
delete datasourcesData.plugins;
|
|
930
|
-
// If there are no properties left other than plugins, then the response was empty
|
|
931
|
-
if (Object.keys(datasourcesData).length === 0) {
|
|
932
|
-
return [];
|
|
933
|
-
}
|
|
934
|
-
// Try to parse what's left as an array of datasources
|
|
935
|
-
return zod_1.z.array(types_1.ServiceDatasourceSchema).parse(Array.isArray(datasourcesData) ? datasourcesData : Object.values(datasourcesData));
|
|
936
|
-
}
|
|
937
|
-
return zod_1.z.array(types_1.ServiceDatasourceSchema).parse(data);
|
|
507
|
+
return this.extractDataFromPluginResponse(data, zod_1.z.array(types_1.ServiceDatasourceSchema));
|
|
938
508
|
}
|
|
939
|
-
/**
|
|
940
|
-
* Get data from a datasource using POST to send params and plugin data
|
|
941
|
-
* This is the primary method for accessing datasources
|
|
942
|
-
*/
|
|
943
509
|
async getDatasource(datasourceId, params) {
|
|
944
|
-
|
|
945
|
-
let requestBody = { ...params };
|
|
946
|
-
if (this.plugins.length > 0) {
|
|
947
|
-
const pluginsData = {};
|
|
948
|
-
// Let each plugin process the input
|
|
949
|
-
for (const plugin of this.plugins) {
|
|
950
|
-
if (plugin.processInputClient) {
|
|
951
|
-
const pluginData = await plugin.processInputClient(requestBody);
|
|
952
|
-
if (pluginData) {
|
|
953
|
-
pluginsData[plugin.id] = pluginData;
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
// Add plugins data to request body
|
|
958
|
-
requestBody.plugins = pluginsData;
|
|
959
|
-
}
|
|
510
|
+
const requestBody = await this.processPluginInput(params);
|
|
960
511
|
const data = await this.makeRequest("POST", `/datasources/${datasourceId}`, requestBody);
|
|
961
|
-
|
|
962
|
-
if (data && typeof data === 'object' && 'plugins' in data) {
|
|
963
|
-
// Process the plugin data if it exists
|
|
964
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
965
|
-
for (const plugin of this.plugins) {
|
|
966
|
-
if (plugin.processOutputClient) {
|
|
967
|
-
await plugin.processOutputClient(data);
|
|
968
|
-
}
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
// The actual datasource object is the original response (without the plugins property)
|
|
972
|
-
// Clone the data and delete the plugins property to get the original object
|
|
973
|
-
const datasourceData = { ...data };
|
|
974
|
-
delete datasourceData.plugins;
|
|
975
|
-
// Try to parse what's left as a datasource object
|
|
976
|
-
return types_1.ServiceDatasourceWithDataSchema.parse(datasourceData);
|
|
977
|
-
}
|
|
978
|
-
// Otherwise, try to parse the whole response as a datasource with data
|
|
979
|
-
return types_1.ServiceDatasourceWithDataSchema.parse(data);
|
|
512
|
+
return this.extractSingleFromPluginResponse(data, types_1.ServiceDatasourceWithDataSchema);
|
|
980
513
|
}
|
|
981
|
-
/**
|
|
982
|
-
* Get all datasources with POST to send plugins data in request body
|
|
983
|
-
* This is the primary method to get all datasources, especially when using plugins
|
|
984
|
-
*/
|
|
985
514
|
async postAllDatasources() {
|
|
986
|
-
|
|
987
|
-
let requestBody = {};
|
|
988
|
-
if (this.plugins.length > 0) {
|
|
989
|
-
const pluginsData = {};
|
|
990
|
-
// Let each plugin process the input
|
|
991
|
-
for (const plugin of this.plugins) {
|
|
992
|
-
if (plugin.processInputClient) {
|
|
993
|
-
const pluginData = await plugin.processInputClient({});
|
|
994
|
-
if (pluginData) {
|
|
995
|
-
pluginsData[plugin.id] = pluginData;
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
// Add plugins data to request body
|
|
1000
|
-
requestBody = { plugins: pluginsData };
|
|
1001
|
-
}
|
|
515
|
+
const requestBody = await this.processPluginInput({});
|
|
1002
516
|
const data = await this.makeRequest("POST", `/datasources/all`, requestBody);
|
|
1003
|
-
|
|
1004
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && 'plugins' in data) {
|
|
1005
|
-
// Process the plugin data if it exists
|
|
1006
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
1007
|
-
for (const plugin of this.plugins) {
|
|
1008
|
-
if (plugin.processOutputClient) {
|
|
1009
|
-
await plugin.processOutputClient(data);
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
// The actual datasources array is the original response (without the plugins property)
|
|
1014
|
-
// Clone the data and delete the plugins property to get the original array
|
|
1015
|
-
const datasourcesData = { ...data };
|
|
1016
|
-
delete datasourcesData.plugins;
|
|
1017
|
-
// If there are no properties left other than plugins, then the response was empty
|
|
1018
|
-
if (Object.keys(datasourcesData).length === 0) {
|
|
1019
|
-
return [];
|
|
1020
|
-
}
|
|
1021
|
-
// Try to parse what's left as an array of datasources
|
|
1022
|
-
return zod_1.z.array(types_1.ServiceDatasourceSchema).parse(Array.isArray(datasourcesData) ? datasourcesData : Object.values(datasourcesData));
|
|
1023
|
-
}
|
|
1024
|
-
return zod_1.z.array(types_1.ServiceDatasourceSchema).parse(data);
|
|
517
|
+
return this.extractDataFromPluginResponse(data, zod_1.z.array(types_1.ServiceDatasourceSchema));
|
|
1025
518
|
}
|
|
1026
|
-
/**
|
|
1027
|
-
* Get all tools that implement a specific interface
|
|
1028
|
-
*/
|
|
1029
519
|
async getToolsByInterface(interfaceType) {
|
|
1030
520
|
const allTools = await this.getTools();
|
|
1031
|
-
return allTools.filter(
|
|
521
|
+
return allTools.filter(t => t.interface === interfaceType);
|
|
1032
522
|
}
|
|
1033
|
-
/**
|
|
1034
|
-
* Get available interfaces from tools
|
|
1035
|
-
*/
|
|
1036
523
|
async getAvailableInterfaces() {
|
|
1037
524
|
const allTools = await this.getTools();
|
|
1038
525
|
const interfaces = new Set();
|
|
1039
|
-
|
|
1040
|
-
if (
|
|
1041
|
-
interfaces.add(
|
|
526
|
+
for (const t of allTools) {
|
|
527
|
+
if (t.interface && Object.values(interfaces_1.ToolInterfaceType).includes(t.interface)) {
|
|
528
|
+
interfaces.add(t.interface);
|
|
1042
529
|
}
|
|
1043
|
-
}
|
|
530
|
+
}
|
|
1044
531
|
return Array.from(interfaces);
|
|
1045
532
|
}
|
|
1046
|
-
/**
|
|
1047
|
-
* Get all agents defined by the service
|
|
1048
|
-
*/
|
|
1049
533
|
async getAgents() {
|
|
1050
534
|
const data = await this.makeRequest("GET", "/agents");
|
|
1051
535
|
return zod_1.z.array(types_1.ServiceAgentSchema).parse(data);
|
|
1052
536
|
}
|
|
1053
|
-
/**
|
|
1054
|
-
* List agents using POST to send plugins data in request body
|
|
1055
|
-
* This is the primary method to get agents, especially when using plugins
|
|
1056
|
-
*/
|
|
1057
537
|
async listAgents() {
|
|
1058
|
-
|
|
1059
|
-
let requestBody = {};
|
|
1060
|
-
if (this.plugins.length > 0) {
|
|
1061
|
-
const pluginsData = {};
|
|
1062
|
-
// Let each plugin process the input
|
|
1063
|
-
for (const plugin of this.plugins) {
|
|
1064
|
-
if (plugin.processInputClient) {
|
|
1065
|
-
const pluginData = await plugin.processInputClient({});
|
|
1066
|
-
if (pluginData) {
|
|
1067
|
-
pluginsData[plugin.id] = pluginData;
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
}
|
|
1071
|
-
// Add plugins data to request body
|
|
1072
|
-
requestBody = { plugins: pluginsData };
|
|
1073
|
-
}
|
|
538
|
+
const requestBody = await this.processPluginInput({});
|
|
1074
539
|
const data = await this.makeRequest("POST", "/agents/list", requestBody);
|
|
1075
|
-
|
|
1076
|
-
if (data && typeof data === 'object' && !Array.isArray(data) && 'plugins' in data) {
|
|
1077
|
-
// Process the plugin data if it exists
|
|
1078
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
1079
|
-
for (const plugin of this.plugins) {
|
|
1080
|
-
if (plugin.processOutputClient) {
|
|
1081
|
-
await plugin.processOutputClient(data);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
// The actual agents array is the original response (without the plugins property)
|
|
1086
|
-
// Clone the data and delete the plugins property to get the original array
|
|
1087
|
-
const agentsData = { ...data };
|
|
1088
|
-
delete agentsData.plugins;
|
|
1089
|
-
// If there are no properties left other than plugins, then the response was empty
|
|
1090
|
-
if (Object.keys(agentsData).length === 0) {
|
|
1091
|
-
return [];
|
|
1092
|
-
}
|
|
1093
|
-
// Try to parse what's left as an array of agents
|
|
1094
|
-
return zod_1.z.array(types_1.ServiceAgentSchema).parse(Array.isArray(agentsData) ? agentsData : Object.values(agentsData));
|
|
1095
|
-
}
|
|
1096
|
-
return zod_1.z.array(types_1.ServiceAgentSchema).parse(data);
|
|
540
|
+
return this.extractDataFromPluginResponse(data, zod_1.z.array(types_1.ServiceAgentSchema));
|
|
1097
541
|
}
|
|
1098
|
-
/**
|
|
1099
|
-
* Get a specific agent by ID
|
|
1100
|
-
*/
|
|
1101
542
|
async getAgent(agentId) {
|
|
1102
543
|
const data = await this.makeRequest("GET", `/agents/${agentId}`);
|
|
1103
544
|
return types_1.ServiceAgentSchema.parse(data);
|
|
1104
545
|
}
|
|
1105
|
-
/**
|
|
1106
|
-
* Get specific agent using POST to send plugins data in request body
|
|
1107
|
-
* This is the primary method to get agent data, especially when using plugins
|
|
1108
|
-
*/
|
|
1109
546
|
async postAgent(agentId) {
|
|
1110
|
-
|
|
1111
|
-
let requestBody = {};
|
|
1112
|
-
if (this.plugins.length > 0) {
|
|
1113
|
-
const pluginsData = {};
|
|
1114
|
-
// Let each plugin process the input
|
|
1115
|
-
for (const plugin of this.plugins) {
|
|
1116
|
-
if (plugin.processInputClient) {
|
|
1117
|
-
const pluginData = await plugin.processInputClient({});
|
|
1118
|
-
if (pluginData) {
|
|
1119
|
-
pluginsData[plugin.id] = pluginData;
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
|
-
// Add plugins data to request body
|
|
1124
|
-
requestBody = { plugins: pluginsData };
|
|
1125
|
-
}
|
|
547
|
+
const requestBody = await this.processPluginInput({});
|
|
1126
548
|
const data = await this.makeRequest("POST", `/agents/${agentId}`, requestBody);
|
|
1127
|
-
|
|
1128
|
-
if (data && typeof data === 'object' && 'plugins' in data) {
|
|
1129
|
-
// Process the plugin data if it exists
|
|
1130
|
-
if (this.plugins.length > 0 && data.plugins) {
|
|
1131
|
-
for (const plugin of this.plugins) {
|
|
1132
|
-
if (plugin.processOutputClient) {
|
|
1133
|
-
await plugin.processOutputClient(data);
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
// The actual agent object is the original response (without the plugins property)
|
|
1138
|
-
// Clone the data and delete the plugins property to get the original object
|
|
1139
|
-
const agentData = { ...data };
|
|
1140
|
-
delete agentData.plugins;
|
|
1141
|
-
// Try to parse what's left as an agent object
|
|
1142
|
-
return types_1.ServiceAgentSchema.parse(agentData);
|
|
1143
|
-
}
|
|
1144
|
-
// Otherwise, try to parse the whole response as an agent
|
|
1145
|
-
return types_1.ServiceAgentSchema.parse(data);
|
|
549
|
+
return this.extractSingleFromPluginResponse(data, types_1.ServiceAgentSchema);
|
|
1146
550
|
}
|
|
1147
551
|
sanitizeToolResponse(response, callbacks, options = {}) {
|
|
1148
552
|
if (!response || typeof response !== "object") {
|
|
1149
553
|
return response;
|
|
1150
554
|
}
|
|
1151
|
-
const
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
const
|
|
1155
|
-
? response._progress
|
|
1156
|
-
: [];
|
|
1157
|
-
const processes = Array.isArray(response._processes)
|
|
1158
|
-
? response._processes
|
|
1159
|
-
: [];
|
|
555
|
+
const resp = response;
|
|
556
|
+
const updates = Array.isArray(resp._updates) ? resp._updates : [];
|
|
557
|
+
const progressUpdates = Array.isArray(resp._progress) ? resp._progress : [];
|
|
558
|
+
const processes = Array.isArray(resp._processes) ? resp._processes : [];
|
|
1160
559
|
if (callbacks?.onUIUpdate) {
|
|
1161
560
|
for (const update of updates) {
|
|
1162
561
|
callbacks.onUIUpdate(update);
|
|
@@ -1172,10 +571,10 @@ class DainServiceConnection {
|
|
|
1172
571
|
callbacks.onProcess(processId);
|
|
1173
572
|
}
|
|
1174
573
|
}
|
|
1175
|
-
const { _updates, _progress, _processes, ...remaining } =
|
|
574
|
+
const { _updates: _, _progress: __, _processes: ___, ...remaining } = resp;
|
|
1176
575
|
const cleanResponse = { ...remaining };
|
|
1177
576
|
if (options.stripToolResultSuccess && cleanResponse.toolResult && typeof cleanResponse.toolResult === "object") {
|
|
1178
|
-
const { success:
|
|
577
|
+
const { success: ____, ...rest } = cleanResponse.toolResult;
|
|
1179
578
|
cleanResponse.toolResult = rest;
|
|
1180
579
|
}
|
|
1181
580
|
return cleanResponse;
|