@dainprotocol/service-sdk 2.0.78 → 2.0.79
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 +30 -57
- 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 +17 -29
- 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 +162 -408
- 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 +11 -10
package/dist/service/server.js
CHANGED
|
@@ -22,33 +22,35 @@ const auth_2 = require("./auth");
|
|
|
22
22
|
const core_1 = require("./core");
|
|
23
23
|
const hitl_1 = require("./hitl");
|
|
24
24
|
const VERBOSE_SERVICE_LOGS = process.env.DAIN_VERBOSE_SERVICE_LOGS === "true";
|
|
25
|
-
|
|
25
|
+
function debugLog(...args) {
|
|
26
26
|
if (VERBOSE_SERVICE_LOGS) {
|
|
27
27
|
console.log(...args);
|
|
28
28
|
}
|
|
29
|
-
}
|
|
30
|
-
|
|
29
|
+
}
|
|
30
|
+
function debugWarn(...args) {
|
|
31
31
|
if (VERBOSE_SERVICE_LOGS) {
|
|
32
32
|
console.warn(...args);
|
|
33
33
|
}
|
|
34
|
-
}
|
|
35
|
-
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Safely parse JSON body from request, returning empty object on failure.
|
|
37
|
+
*/
|
|
38
|
+
async function safeParseBody(c) {
|
|
39
|
+
try {
|
|
40
|
+
return await c.req.json();
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
36
46
|
/**
|
|
37
|
-
* Middleware factory to require specific OAuth scopes
|
|
38
|
-
* Defense-in-depth: Validates scopes even though JWT middleware already checked them
|
|
39
|
-
*
|
|
40
|
-
* @param requiredScope Single scope or array of scopes (ANY match required)
|
|
41
|
-
* @returns Hono middleware
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* app.get("/widgets", requireScope("widgets.read"), async (c) => { ... })
|
|
45
|
-
* app.post("/admin", requireScope(["admin.*", "super.admin"]), async (c) => { ... })
|
|
47
|
+
* Middleware factory to require specific OAuth scopes.
|
|
48
|
+
* Defense-in-depth: Validates scopes even though JWT middleware already checked them.
|
|
46
49
|
*/
|
|
47
50
|
function requireScope(requiredScope) {
|
|
48
51
|
return async (c, next) => {
|
|
49
52
|
const scopes = c.get('scope') || [];
|
|
50
53
|
const requiredScopes = Array.isArray(requiredScope) ? requiredScope : [requiredScope];
|
|
51
|
-
// Check if user has at least one of the required scopes
|
|
52
54
|
const hasRequiredScope = requiredScopes.some(scope => (0, auth_2.hasScope)(scopes, scope));
|
|
53
55
|
if (!hasRequiredScope) {
|
|
54
56
|
throw new http_exception_1.HTTPException(403, {
|
|
@@ -304,18 +306,9 @@ function setupHttpServer(config, tools, services, toolboxes, metadata, privateKe
|
|
|
304
306
|
console.log(`[Service SDK Server] Returning ${toolInfo.length} tools`);
|
|
305
307
|
return c.json(toolInfo);
|
|
306
308
|
});
|
|
307
|
-
// POST version of the basic contexts listing
|
|
308
309
|
app.post("/contexts/list", async (c) => {
|
|
309
310
|
const agentInfo = await getAgentInfo(c);
|
|
310
|
-
|
|
311
|
-
let body = {};
|
|
312
|
-
try {
|
|
313
|
-
body = await c.req.json();
|
|
314
|
-
}
|
|
315
|
-
catch (error) {
|
|
316
|
-
body = {}; // Default to empty body if parsing fails
|
|
317
|
-
}
|
|
318
|
-
// Process plugins for the request
|
|
311
|
+
const body = await safeParseBody(c);
|
|
319
312
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
320
313
|
// Merge manual contexts with auto-generated contexts (direct provider + skills)
|
|
321
314
|
const autoContexts = app.oauth2?.getDirectProviderContexts?.() || [];
|
|
@@ -331,41 +324,27 @@ function setupHttpServer(config, tools, services, toolboxes, metadata, privateKe
|
|
|
331
324
|
const processedResponse = await processPluginsForResponse(contextInfo, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
332
325
|
return c.json(processedResponse);
|
|
333
326
|
});
|
|
334
|
-
// Primary endpoint for getting a context's data with plugin support
|
|
335
327
|
app.post("/contexts/:contextId", async (c) => {
|
|
336
|
-
// Merge manual contexts with auto-generated contexts (direct provider + skills)
|
|
337
328
|
const autoContexts = app.oauth2?.getDirectProviderContexts?.() || [];
|
|
338
329
|
const serviceSlug = (0, core_1.toSlug)(metadata.title);
|
|
339
330
|
const skillsContext = config.skills?.getSkillsContext?.(serviceSlug);
|
|
340
331
|
const allContexts = [...contexts, ...autoContexts, ...(skillsContext ? [skillsContext] : [])];
|
|
341
|
-
const context = allContexts.find((
|
|
332
|
+
const context = allContexts.find((ctx) => ctx.id === c.req.param("contextId"));
|
|
342
333
|
if (context) {
|
|
343
334
|
const agentInfo = await getAgentInfo(c);
|
|
344
|
-
|
|
345
|
-
let body = {};
|
|
346
|
-
try {
|
|
347
|
-
body = await c.req.json();
|
|
348
|
-
}
|
|
349
|
-
catch (error) {
|
|
350
|
-
body = {}; // Default to empty body if parsing fails
|
|
351
|
-
}
|
|
352
|
-
// Process plugins for the request
|
|
335
|
+
const body = await safeParseBody(c);
|
|
353
336
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
354
|
-
|
|
355
|
-
const oauth2Client = app.oauth2 ? app.oauth2.getClient() : undefined;
|
|
356
|
-
// Get context data with plugins and oauth2Client
|
|
337
|
+
const oauth2Client = app.oauth2?.getClient();
|
|
357
338
|
const contextData = await context.getContextData(agentInfo, {
|
|
358
339
|
plugins: processedPluginData.plugins,
|
|
359
|
-
oauth2Client
|
|
340
|
+
oauth2Client
|
|
360
341
|
});
|
|
361
|
-
// Create the response
|
|
362
342
|
const response = {
|
|
363
343
|
id: context.id,
|
|
364
344
|
name: context.name,
|
|
365
345
|
description: context.description,
|
|
366
346
|
data: contextData
|
|
367
347
|
};
|
|
368
|
-
// Process plugins for the response
|
|
369
348
|
const processedResponse = await processPluginsForResponse(response, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
370
349
|
return c.json(processedResponse);
|
|
371
350
|
}
|
|
@@ -373,121 +352,67 @@ function setupHttpServer(config, tools, services, toolboxes, metadata, privateKe
|
|
|
373
352
|
throw new http_exception_1.HTTPException(404, { message: "Context not found" });
|
|
374
353
|
}
|
|
375
354
|
});
|
|
376
|
-
// Primary endpoint for getting all contexts with plugin support
|
|
377
355
|
app.post("/contexts", async (c) => {
|
|
378
356
|
const agentInfo = await getAgentInfo(c);
|
|
379
|
-
|
|
380
|
-
let body = {};
|
|
381
|
-
try {
|
|
382
|
-
body = await c.req.json();
|
|
383
|
-
}
|
|
384
|
-
catch (error) {
|
|
385
|
-
body = {}; // Default to empty body if parsing fails
|
|
386
|
-
}
|
|
387
|
-
// Process plugins for the request
|
|
357
|
+
const body = await safeParseBody(c);
|
|
388
358
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
389
|
-
|
|
390
|
-
const oauth2Client = app.oauth2 ? app.oauth2.getClient() : undefined;
|
|
391
|
-
// Merge manual contexts with auto-generated contexts (direct provider + skills)
|
|
359
|
+
const oauth2Client = app.oauth2?.getClient();
|
|
392
360
|
const autoContexts = app.oauth2?.getDirectProviderContexts?.() || [];
|
|
393
361
|
const serviceSlug = (0, core_1.toSlug)(metadata.title);
|
|
394
362
|
const skillsContext = config.skills?.getSkillsContext?.(serviceSlug);
|
|
395
363
|
const allContexts = [...contexts, ...autoContexts, ...(skillsContext ? [skillsContext] : [])];
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
data: await context.getContextData(agentInfo, {
|
|
364
|
+
const contextsFull = await Promise.all(allContexts.map(async (ctx) => ({
|
|
365
|
+
id: ctx.id,
|
|
366
|
+
name: ctx.name,
|
|
367
|
+
description: ctx.description,
|
|
368
|
+
data: await ctx.getContextData(agentInfo, {
|
|
402
369
|
plugins: processedPluginData.plugins,
|
|
403
|
-
oauth2Client
|
|
370
|
+
oauth2Client
|
|
404
371
|
}),
|
|
405
372
|
})));
|
|
406
|
-
|
|
407
|
-
const response = contextsFull;
|
|
408
|
-
// Process plugins for the response
|
|
409
|
-
const processedResponse = await processPluginsForResponse(response, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
373
|
+
const processedResponse = await processPluginsForResponse(contextsFull, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
410
374
|
return c.json(processedResponse);
|
|
411
375
|
});
|
|
412
|
-
// Get widget IDs for current user
|
|
413
376
|
app.post("/widgets", async (c) => {
|
|
414
377
|
const agentInfo = await getAgentInfo(c);
|
|
415
|
-
|
|
416
|
-
let body = {};
|
|
417
|
-
try {
|
|
418
|
-
body = await c.req.json();
|
|
419
|
-
}
|
|
420
|
-
catch (error) {
|
|
421
|
-
body = {}; // Default to empty body if parsing fails
|
|
422
|
-
}
|
|
423
|
-
// Process plugins for the request
|
|
378
|
+
const body = await safeParseBody(c);
|
|
424
379
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
widgetIds = await config.getUserWidgets(agentInfo, {
|
|
429
|
-
plugins: processedPluginData.plugins
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
// Default: return all widget IDs
|
|
434
|
-
widgetIds = widgets.map(widget => widget.id);
|
|
435
|
-
}
|
|
436
|
-
// Process plugins for the response
|
|
380
|
+
const widgetIds = config.getUserWidgets
|
|
381
|
+
? await config.getUserWidgets(agentInfo, { plugins: processedPluginData.plugins })
|
|
382
|
+
: widgets.map(widget => widget.id);
|
|
437
383
|
const processedResponse = await processPluginsForResponse(widgetIds, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
438
384
|
return c.json(processedResponse);
|
|
439
385
|
});
|
|
440
|
-
// Get all widgets with their data
|
|
441
386
|
app.post("/widgets/all", async (c) => {
|
|
442
387
|
const agentInfo = await getAgentInfo(c);
|
|
443
|
-
|
|
444
|
-
let body = {};
|
|
445
|
-
try {
|
|
446
|
-
body = await c.req.json();
|
|
447
|
-
}
|
|
448
|
-
catch (error) {
|
|
449
|
-
body = {}; // Default to empty body if parsing fails
|
|
450
|
-
}
|
|
451
|
-
// Process plugins for the request
|
|
388
|
+
const body = await safeParseBody(c);
|
|
452
389
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
plugins: processedPluginData.plugins
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
else {
|
|
461
|
-
// Default: return all widget IDs
|
|
462
|
-
widgetIds = widgets.map(widget => widget.id);
|
|
463
|
-
}
|
|
464
|
-
// Get widgets with their data
|
|
465
|
-
const oauth2Client = app.oauth2 ? app.oauth2.getClient() : undefined;
|
|
390
|
+
const widgetIds = config.getUserWidgets
|
|
391
|
+
? await config.getUserWidgets(agentInfo, { plugins: processedPluginData.plugins })
|
|
392
|
+
: widgets.map(widget => widget.id);
|
|
393
|
+
const oauth2Client = app.oauth2?.getClient();
|
|
466
394
|
const widgetsFull = await Promise.all(widgetIds.map(async (widgetId) => {
|
|
467
395
|
const widget = widgets.find(w => w.id === widgetId);
|
|
468
396
|
if (!widget)
|
|
469
397
|
return null;
|
|
470
398
|
const widgetData = await widget.getWidget(agentInfo, {
|
|
471
399
|
plugins: processedPluginData.plugins,
|
|
472
|
-
oauth2Client
|
|
473
|
-
app
|
|
400
|
+
oauth2Client,
|
|
401
|
+
app
|
|
474
402
|
});
|
|
475
403
|
return {
|
|
476
404
|
id: widget.id,
|
|
477
405
|
name: widget.name,
|
|
478
406
|
description: widget.description,
|
|
479
407
|
icon: widget.icon,
|
|
480
|
-
size: widget.size || "sm",
|
|
408
|
+
size: widget.size || "sm",
|
|
481
409
|
...widgetData
|
|
482
410
|
};
|
|
483
411
|
}));
|
|
484
|
-
// Filter out null widgets (not found)
|
|
485
412
|
const validWidgets = widgetsFull.filter(w => w !== null);
|
|
486
|
-
// Process plugins for the response
|
|
487
413
|
const processedResponse = await processPluginsForResponse(validWidgets, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
488
414
|
return c.json(processedResponse);
|
|
489
415
|
});
|
|
490
|
-
// Get specific widget with data
|
|
491
416
|
app.post("/widgets/:widgetId", async (c) => {
|
|
492
417
|
const widgetId = c.req.param("widgetId");
|
|
493
418
|
const widget = widgets.find(w => w.id === widgetId);
|
|
@@ -495,86 +420,49 @@ function setupHttpServer(config, tools, services, toolboxes, metadata, privateKe
|
|
|
495
420
|
throw new http_exception_1.HTTPException(404, { message: "Widget not found" });
|
|
496
421
|
}
|
|
497
422
|
const agentInfo = await getAgentInfo(c);
|
|
498
|
-
|
|
499
|
-
let body = {};
|
|
500
|
-
try {
|
|
501
|
-
body = await c.req.json();
|
|
502
|
-
}
|
|
503
|
-
catch (error) {
|
|
504
|
-
body = {}; // Default to empty body if parsing fails
|
|
505
|
-
}
|
|
506
|
-
// Process plugins for the request
|
|
423
|
+
const body = await safeParseBody(c);
|
|
507
424
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
508
|
-
// Check if user has access to this widget
|
|
509
425
|
if (config.getUserWidgets) {
|
|
510
426
|
const userWidgetIds = await config.getUserWidgets(agentInfo, {
|
|
511
427
|
plugins: processedPluginData.plugins
|
|
512
428
|
});
|
|
513
|
-
// Get the home UI widget ID for this user (if configured)
|
|
514
429
|
let homeUIWidgetId = null;
|
|
515
430
|
if (config.homeUI) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
else {
|
|
520
|
-
homeUIWidgetId = await config.homeUI(agentInfo, {
|
|
521
|
-
plugins: processedPluginData.plugins
|
|
522
|
-
});
|
|
523
|
-
}
|
|
431
|
+
homeUIWidgetId = typeof config.homeUI === 'string'
|
|
432
|
+
? config.homeUI
|
|
433
|
+
: await config.homeUI(agentInfo, { plugins: processedPluginData.plugins });
|
|
524
434
|
}
|
|
525
|
-
// Allow access if widget is in getUserWidgets OR if it's the homeUI widget
|
|
526
435
|
if (!userWidgetIds.includes(widgetId) && widgetId !== homeUIWidgetId) {
|
|
527
436
|
throw new http_exception_1.HTTPException(403, { message: "Access denied to this widget" });
|
|
528
437
|
}
|
|
529
438
|
}
|
|
530
|
-
|
|
531
|
-
const oauth2Client = app.oauth2 ? app.oauth2.getClient() : undefined;
|
|
439
|
+
const oauth2Client = app.oauth2?.getClient();
|
|
532
440
|
const widgetData = await widget.getWidget(agentInfo, {
|
|
533
441
|
plugins: processedPluginData.plugins,
|
|
534
|
-
oauth2Client
|
|
535
|
-
app
|
|
442
|
+
oauth2Client,
|
|
443
|
+
app
|
|
536
444
|
});
|
|
537
|
-
// Create the response
|
|
538
445
|
const response = {
|
|
539
446
|
id: widget.id,
|
|
540
447
|
name: widget.name,
|
|
541
448
|
description: widget.description,
|
|
542
449
|
icon: widget.icon,
|
|
543
|
-
size: widget.size || "sm",
|
|
450
|
+
size: widget.size || "sm",
|
|
544
451
|
...widgetData
|
|
545
452
|
};
|
|
546
|
-
// Process plugins for the response
|
|
547
453
|
const processedResponse = await processPluginsForResponse(response, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
548
454
|
return c.json(processedResponse);
|
|
549
455
|
});
|
|
550
|
-
// Get home UI widget ID for current user
|
|
551
456
|
app.post("/homeUI", async (c) => {
|
|
552
|
-
// Return null widgetId if homeUI is not configured (instead of 404)
|
|
553
457
|
if (!config.homeUI) {
|
|
554
458
|
return c.json({ widgetId: null });
|
|
555
459
|
}
|
|
556
460
|
const agentInfo = await getAgentInfo(c);
|
|
557
|
-
|
|
558
|
-
let body = {};
|
|
559
|
-
try {
|
|
560
|
-
body = await c.req.json();
|
|
561
|
-
}
|
|
562
|
-
catch (error) {
|
|
563
|
-
body = {}; // Default to empty body if parsing fails
|
|
564
|
-
}
|
|
565
|
-
// Process plugins for the request
|
|
461
|
+
const body = await safeParseBody(c);
|
|
566
462
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
homeUIWidgetId = config.homeUI;
|
|
571
|
-
}
|
|
572
|
-
else {
|
|
573
|
-
homeUIWidgetId = await config.homeUI(agentInfo, {
|
|
574
|
-
plugins: processedPluginData.plugins
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
// Return null if widget ID is empty or widget doesn't exist
|
|
463
|
+
const homeUIWidgetId = typeof config.homeUI === 'string'
|
|
464
|
+
? config.homeUI
|
|
465
|
+
: await config.homeUI(agentInfo, { plugins: processedPluginData.plugins });
|
|
578
466
|
if (!homeUIWidgetId) {
|
|
579
467
|
return c.json({ widgetId: null });
|
|
580
468
|
}
|
|
@@ -582,145 +470,77 @@ function setupHttpServer(config, tools, services, toolboxes, metadata, privateKe
|
|
|
582
470
|
if (!widget) {
|
|
583
471
|
return c.json({ widgetId: null });
|
|
584
472
|
}
|
|
585
|
-
// Process plugins for the response
|
|
586
473
|
const processedResponse = await processPluginsForResponse({ widgetId: homeUIWidgetId }, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
587
474
|
return c.json(processedResponse);
|
|
588
475
|
});
|
|
589
|
-
|
|
590
|
-
|
|
476
|
+
function mapDatasourceInfo(datasource) {
|
|
477
|
+
return {
|
|
591
478
|
id: datasource.id,
|
|
592
479
|
name: datasource.name,
|
|
593
480
|
description: datasource.description,
|
|
594
481
|
type: datasource.type,
|
|
595
482
|
inputSchema: (0, schemaStructure_1.getDetailedSchemaStructure)(datasource.input),
|
|
596
|
-
}
|
|
597
|
-
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
app.get("/datasources", (c) => {
|
|
486
|
+
return c.json(datasources.map(mapDatasourceInfo));
|
|
598
487
|
});
|
|
599
|
-
// POST version of the basic datasources listing
|
|
600
488
|
app.post("/datasources/list", async (c) => {
|
|
601
489
|
const agentInfo = await getAgentInfo(c);
|
|
602
|
-
|
|
603
|
-
let body = {};
|
|
604
|
-
try {
|
|
605
|
-
body = await c.req.json();
|
|
606
|
-
}
|
|
607
|
-
catch (error) {
|
|
608
|
-
body = {}; // Default to empty body if parsing fails
|
|
609
|
-
}
|
|
610
|
-
// Process plugins for the request
|
|
490
|
+
const body = await safeParseBody(c);
|
|
611
491
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
612
|
-
const
|
|
613
|
-
id: datasource.id,
|
|
614
|
-
name: datasource.name,
|
|
615
|
-
description: datasource.description,
|
|
616
|
-
type: datasource.type,
|
|
617
|
-
inputSchema: (0, schemaStructure_1.getDetailedSchemaStructure)(datasource.input),
|
|
618
|
-
}));
|
|
619
|
-
// Process plugins for the response
|
|
620
|
-
const processedResponse = await processPluginsForResponse(datasourceInfo, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
492
|
+
const processedResponse = await processPluginsForResponse(datasources.map(mapDatasourceInfo), body, { extraData: { plugins: processedPluginData.plugins } });
|
|
621
493
|
return c.json(processedResponse);
|
|
622
494
|
});
|
|
623
|
-
// Primary endpoint for getting all datasources with plugin support
|
|
624
495
|
app.post("/datasources/all", async (c) => {
|
|
625
496
|
const agentInfo = await getAgentInfo(c);
|
|
626
|
-
|
|
627
|
-
let body = {};
|
|
628
|
-
try {
|
|
629
|
-
body = await c.req.json();
|
|
630
|
-
}
|
|
631
|
-
catch (error) {
|
|
632
|
-
body = {}; // Default to empty body if parsing fails
|
|
633
|
-
}
|
|
634
|
-
// Process plugins for the request
|
|
497
|
+
const body = await safeParseBody(c);
|
|
635
498
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
636
|
-
|
|
637
|
-
const datasourcesFull = datasources.map((datasource) => ({
|
|
638
|
-
id: datasource.id,
|
|
639
|
-
name: datasource.name,
|
|
640
|
-
description: datasource.description,
|
|
641
|
-
type: datasource.type,
|
|
642
|
-
inputSchema: (0, schemaStructure_1.getDetailedSchemaStructure)(datasource.input),
|
|
643
|
-
}));
|
|
644
|
-
// Process plugins for the response
|
|
645
|
-
const processedResponse = await processPluginsForResponse(datasourcesFull, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
499
|
+
const processedResponse = await processPluginsForResponse(datasources.map(mapDatasourceInfo), body, { extraData: { plugins: processedPluginData.plugins } });
|
|
646
500
|
return c.json(processedResponse);
|
|
647
501
|
});
|
|
648
502
|
app.post("/datasources/:datasourceId", async (c) => {
|
|
649
|
-
const datasource = datasources.find((
|
|
650
|
-
if (datasource) {
|
|
651
|
-
const agentInfo = await getAgentInfo(c);
|
|
652
|
-
let params = await c.req.json();
|
|
653
|
-
// Process plugins for the request
|
|
654
|
-
params = await processPluginsForRequest(params, agentInfo);
|
|
655
|
-
// Extract plugins data for the datasource
|
|
656
|
-
const pluginsData = params.plugins || {};
|
|
657
|
-
delete params.plugins;
|
|
658
|
-
try {
|
|
659
|
-
const parsedParams = datasource.input.parse(params);
|
|
660
|
-
// Get oauth2 client if available
|
|
661
|
-
const oauth2Client = app.oauth2 ? app.oauth2.getClient() : undefined;
|
|
662
|
-
// Get datasource with plugins and oauth2Client
|
|
663
|
-
const data = await datasource.getDatasource(agentInfo, parsedParams, {
|
|
664
|
-
plugins: pluginsData,
|
|
665
|
-
oauth2Client: oauth2Client
|
|
666
|
-
});
|
|
667
|
-
// Create the response
|
|
668
|
-
const response = {
|
|
669
|
-
id: datasource.id,
|
|
670
|
-
name: datasource.name,
|
|
671
|
-
description: datasource.description,
|
|
672
|
-
type: datasource.type,
|
|
673
|
-
data: data,
|
|
674
|
-
};
|
|
675
|
-
// Process plugins for the response
|
|
676
|
-
const processedResponse = await processPluginsForResponse(response, { plugins: pluginsData }, { extraData: { plugins: pluginsData } });
|
|
677
|
-
return c.json(processedResponse);
|
|
678
|
-
}
|
|
679
|
-
catch (error) {
|
|
680
|
-
if (error instanceof zod_1.z.ZodError) {
|
|
681
|
-
const missingParams = error.issues
|
|
682
|
-
.map((issue) => issue.path.join("."))
|
|
683
|
-
.join(", ");
|
|
684
|
-
return c.json({
|
|
685
|
-
error: `Missing or invalid parameters: ${missingParams}`,
|
|
686
|
-
code: "INVALID_PARAMS"
|
|
687
|
-
}, 400);
|
|
688
|
-
}
|
|
689
|
-
throw error;
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
else {
|
|
503
|
+
const datasource = datasources.find((ds) => ds.id === c.req.param("datasourceId"));
|
|
504
|
+
if (!datasource) {
|
|
693
505
|
throw new http_exception_1.HTTPException(404, { message: "Datasource not found" });
|
|
694
506
|
}
|
|
695
|
-
});
|
|
696
|
-
// Agents list endpoint
|
|
697
|
-
app.get("/agents", (c) => {
|
|
698
|
-
const agentInfo = agents.map((agent) => ({
|
|
699
|
-
id: agent.id,
|
|
700
|
-
name: agent.name,
|
|
701
|
-
context: agent.context,
|
|
702
|
-
prompt: agent.prompt,
|
|
703
|
-
resolveCondition: agent.resolveCondition,
|
|
704
|
-
serviceConnections: agent.serviceConnections || [process.env.BASE_URL || 'http://localhost:3000'],
|
|
705
|
-
inputSchema: (0, schemaStructure_1.zodToJsonSchema)(agent.input),
|
|
706
|
-
outputSchema: (0, schemaStructure_1.zodToJsonSchema)(agent.output),
|
|
707
|
-
}));
|
|
708
|
-
return c.json(agentInfo);
|
|
709
|
-
});
|
|
710
|
-
// POST version of the basic agents listing
|
|
711
|
-
app.post("/agents/list", async (c) => {
|
|
712
507
|
const agentInfo = await getAgentInfo(c);
|
|
713
|
-
|
|
714
|
-
|
|
508
|
+
let params = await c.req.json();
|
|
509
|
+
params = await processPluginsForRequest(params, agentInfo);
|
|
510
|
+
const pluginsData = params.plugins || {};
|
|
511
|
+
delete params.plugins;
|
|
715
512
|
try {
|
|
716
|
-
|
|
513
|
+
const parsedParams = datasource.input.parse(params);
|
|
514
|
+
const oauth2Client = app.oauth2?.getClient();
|
|
515
|
+
const data = await datasource.getDatasource(agentInfo, parsedParams, {
|
|
516
|
+
plugins: pluginsData,
|
|
517
|
+
oauth2Client
|
|
518
|
+
});
|
|
519
|
+
const response = {
|
|
520
|
+
id: datasource.id,
|
|
521
|
+
name: datasource.name,
|
|
522
|
+
description: datasource.description,
|
|
523
|
+
type: datasource.type,
|
|
524
|
+
data,
|
|
525
|
+
};
|
|
526
|
+
const processedResponse = await processPluginsForResponse(response, { plugins: pluginsData }, { extraData: { plugins: pluginsData } });
|
|
527
|
+
return c.json(processedResponse);
|
|
717
528
|
}
|
|
718
529
|
catch (error) {
|
|
719
|
-
|
|
530
|
+
if (error instanceof zod_1.z.ZodError) {
|
|
531
|
+
const missingParams = error.issues
|
|
532
|
+
.map((issue) => issue.path.join("."))
|
|
533
|
+
.join(", ");
|
|
534
|
+
return c.json({
|
|
535
|
+
error: `Missing or invalid parameters: ${missingParams}`,
|
|
536
|
+
code: "INVALID_PARAMS"
|
|
537
|
+
}, 400);
|
|
538
|
+
}
|
|
539
|
+
throw error;
|
|
720
540
|
}
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
541
|
+
});
|
|
542
|
+
function mapAgentInfo(agent) {
|
|
543
|
+
return {
|
|
724
544
|
id: agent.id,
|
|
725
545
|
name: agent.name,
|
|
726
546
|
context: agent.context,
|
|
@@ -729,145 +549,91 @@ function setupHttpServer(config, tools, services, toolboxes, metadata, privateKe
|
|
|
729
549
|
serviceConnections: agent.serviceConnections || [process.env.BASE_URL || 'http://localhost:3000'],
|
|
730
550
|
inputSchema: (0, schemaStructure_1.zodToJsonSchema)(agent.input),
|
|
731
551
|
outputSchema: (0, schemaStructure_1.zodToJsonSchema)(agent.output),
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
app.get("/agents", (c) => {
|
|
555
|
+
return c.json(agents.map(mapAgentInfo));
|
|
556
|
+
});
|
|
557
|
+
app.post("/agents/list", async (c) => {
|
|
558
|
+
const agentInfo = await getAgentInfo(c);
|
|
559
|
+
const body = await safeParseBody(c);
|
|
560
|
+
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
561
|
+
const processedResponse = await processPluginsForResponse(agents.map(mapAgentInfo), body, { extraData: { plugins: processedPluginData.plugins } });
|
|
735
562
|
return c.json(processedResponse);
|
|
736
563
|
});
|
|
737
|
-
// Get specific agent
|
|
738
564
|
app.get("/agents/:agentId", (c) => {
|
|
739
565
|
const agent = agents.find((a) => a.id === c.req.param("agentId"));
|
|
740
|
-
if (agent) {
|
|
741
|
-
const agentDetails = {
|
|
742
|
-
id: agent.id,
|
|
743
|
-
name: agent.name,
|
|
744
|
-
context: agent.context,
|
|
745
|
-
prompt: agent.prompt,
|
|
746
|
-
resolveCondition: agent.resolveCondition,
|
|
747
|
-
serviceConnections: agent.serviceConnections || [process.env.BASE_URL || 'http://localhost:3000'],
|
|
748
|
-
inputSchema: (0, schemaStructure_1.zodToJsonSchema)(agent.input),
|
|
749
|
-
outputSchema: (0, schemaStructure_1.zodToJsonSchema)(agent.output),
|
|
750
|
-
};
|
|
751
|
-
return c.json(agentDetails);
|
|
752
|
-
}
|
|
753
|
-
else {
|
|
566
|
+
if (!agent) {
|
|
754
567
|
throw new http_exception_1.HTTPException(404, { message: "Agent not found" });
|
|
755
568
|
}
|
|
569
|
+
return c.json(mapAgentInfo(agent));
|
|
756
570
|
});
|
|
757
|
-
// POST version for getting specific agent with plugin support
|
|
758
571
|
app.post("/agents/:agentId", async (c) => {
|
|
759
572
|
const agent = agents.find((a) => a.id === c.req.param("agentId"));
|
|
760
|
-
if (agent) {
|
|
761
|
-
const agentInfo = await getAgentInfo(c);
|
|
762
|
-
// Get plugin data from request body
|
|
763
|
-
let body = {};
|
|
764
|
-
try {
|
|
765
|
-
body = await c.req.json();
|
|
766
|
-
}
|
|
767
|
-
catch (error) {
|
|
768
|
-
body = {}; // Default to empty body if parsing fails
|
|
769
|
-
}
|
|
770
|
-
// Process plugins for the request
|
|
771
|
-
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
772
|
-
const agentDetails = {
|
|
773
|
-
id: agent.id,
|
|
774
|
-
name: agent.name,
|
|
775
|
-
context: agent.context,
|
|
776
|
-
prompt: agent.prompt,
|
|
777
|
-
resolveCondition: agent.resolveCondition,
|
|
778
|
-
serviceConnections: agent.serviceConnections || [process.env.BASE_URL || 'http://localhost:3000'],
|
|
779
|
-
inputSchema: (0, schemaStructure_1.zodToJsonSchema)(agent.input),
|
|
780
|
-
outputSchema: (0, schemaStructure_1.zodToJsonSchema)(agent.output),
|
|
781
|
-
};
|
|
782
|
-
// Process plugins for the response
|
|
783
|
-
const processedResponse = await processPluginsForResponse(agentDetails, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
784
|
-
return c.json(processedResponse);
|
|
785
|
-
}
|
|
786
|
-
else {
|
|
573
|
+
if (!agent) {
|
|
787
574
|
throw new http_exception_1.HTTPException(404, { message: "Agent not found" });
|
|
788
575
|
}
|
|
576
|
+
const agentInfo = await getAgentInfo(c);
|
|
577
|
+
const body = await safeParseBody(c);
|
|
578
|
+
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
579
|
+
const processedResponse = await processPluginsForResponse(mapAgentInfo(agent), body, { extraData: { plugins: processedPluginData.plugins } });
|
|
580
|
+
return c.json(processedResponse);
|
|
789
581
|
});
|
|
582
|
+
function fixEmptySchemas(schema) {
|
|
583
|
+
if (!schema || typeof schema !== 'object')
|
|
584
|
+
return;
|
|
585
|
+
if (schema.properties && typeof schema.properties === 'object') {
|
|
586
|
+
const props = schema.properties;
|
|
587
|
+
for (const key of Object.keys(props)) {
|
|
588
|
+
const prop = props[key];
|
|
589
|
+
if (prop && typeof prop === 'object' && Object.keys(prop).length === 0) {
|
|
590
|
+
props[key] = { type: 'object' };
|
|
591
|
+
}
|
|
592
|
+
fixEmptySchemas(prop);
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
if (schema.items) {
|
|
596
|
+
fixEmptySchemas(schema.items);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function mapToolToJsonSchema(tool) {
|
|
600
|
+
let inputSchema = (0, schemaStructure_1.zodToJsonSchema)(tool.input);
|
|
601
|
+
let outputSchema = (0, schemaStructure_1.zodToJsonSchema)(tool.output);
|
|
602
|
+
if (!inputSchema.type) {
|
|
603
|
+
inputSchema = { ...inputSchema, type: 'object' };
|
|
604
|
+
}
|
|
605
|
+
if (!outputSchema.type) {
|
|
606
|
+
outputSchema = { ...outputSchema, type: 'object' };
|
|
607
|
+
}
|
|
608
|
+
fixEmptySchemas(inputSchema);
|
|
609
|
+
fixEmptySchemas(outputSchema);
|
|
610
|
+
return {
|
|
611
|
+
id: tool.id,
|
|
612
|
+
name: tool.name,
|
|
613
|
+
description: tool.description,
|
|
614
|
+
inputSchema,
|
|
615
|
+
outputSchema,
|
|
616
|
+
interface: tool.interface,
|
|
617
|
+
suggestConfirmation: tool.suggestConfirmation,
|
|
618
|
+
supportsUserActions: tool.supportsUserActions,
|
|
619
|
+
};
|
|
620
|
+
}
|
|
790
621
|
app.get("/getAllToolsAsJsonSchema", (c) => {
|
|
791
|
-
const toolInfo = tools.map((tool) => {
|
|
792
|
-
const inputSchema = (0, schemaStructure_1.zodToJsonSchema)(tool.input);
|
|
793
|
-
const outputSchema = (0, schemaStructure_1.zodToJsonSchema)(tool.output);
|
|
794
|
-
return {
|
|
795
|
-
id: tool.id,
|
|
796
|
-
name: tool.name,
|
|
797
|
-
description: tool.description,
|
|
798
|
-
inputSchema,
|
|
799
|
-
outputSchema,
|
|
800
|
-
interface: tool.interface,
|
|
801
|
-
suggestConfirmation: tool.suggestConfirmation,
|
|
802
|
-
supportsUserActions: tool.supportsUserActions,
|
|
803
|
-
};
|
|
804
|
-
});
|
|
805
622
|
return c.json({
|
|
806
|
-
tools:
|
|
623
|
+
tools: tools.map(mapToolToJsonSchema),
|
|
807
624
|
reccomendedPrompts: toolboxes.map((toolbox) => toolbox.recommendedPrompt),
|
|
808
625
|
});
|
|
809
626
|
});
|
|
810
|
-
// POST version of getAllToolsAsJsonSchema
|
|
811
627
|
app.post("/getAllToolsAsJsonSchema", async (c) => {
|
|
812
628
|
const agentInfo = await getAgentInfo(c);
|
|
813
|
-
|
|
814
|
-
let body = {};
|
|
815
|
-
try {
|
|
816
|
-
body = await c.req.json();
|
|
817
|
-
}
|
|
818
|
-
catch (error) {
|
|
819
|
-
body = {}; // Default to empty body if parsing fails
|
|
820
|
-
}
|
|
821
|
-
// Process plugins for the request
|
|
629
|
+
const body = await safeParseBody(c);
|
|
822
630
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
823
|
-
const toolInfo = tools.map(
|
|
824
|
-
|
|
825
|
-
let outputSchema = (0, schemaStructure_1.zodToJsonSchema)(tool.output);
|
|
826
|
-
// Ensure inputSchema has type: 'object' at root level (butterfly-web compatibility)
|
|
827
|
-
if (!inputSchema.type) {
|
|
828
|
-
inputSchema = { ...inputSchema, type: 'object' };
|
|
829
|
-
}
|
|
830
|
-
if (!outputSchema.type) {
|
|
831
|
-
outputSchema = { ...outputSchema, type: 'object' };
|
|
832
|
-
}
|
|
833
|
-
// Fix empty object schemas (from z.any()) to have type
|
|
834
|
-
const fixEmptySchemas = (schema) => {
|
|
835
|
-
if (schema && typeof schema === 'object') {
|
|
836
|
-
if (schema.properties) {
|
|
837
|
-
Object.keys(schema.properties).forEach(key => {
|
|
838
|
-
const prop = schema.properties[key];
|
|
839
|
-
if (prop && typeof prop === 'object' && Object.keys(prop).length === 0) {
|
|
840
|
-
schema.properties[key] = { type: 'object' };
|
|
841
|
-
}
|
|
842
|
-
fixEmptySchemas(prop);
|
|
843
|
-
});
|
|
844
|
-
}
|
|
845
|
-
if (schema.items) {
|
|
846
|
-
fixEmptySchemas(schema.items);
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
};
|
|
850
|
-
fixEmptySchemas(inputSchema);
|
|
851
|
-
fixEmptySchemas(outputSchema);
|
|
852
|
-
console.log(`[getAllToolsAsJsonSchema POST] Tool: ${tool.id}`);
|
|
853
|
-
console.log(`[getAllToolsAsJsonSchema POST] Input Schema:`, JSON.stringify(inputSchema, null, 2));
|
|
854
|
-
return {
|
|
855
|
-
id: tool.id,
|
|
856
|
-
name: tool.name,
|
|
857
|
-
description: tool.description,
|
|
858
|
-
inputSchema,
|
|
859
|
-
outputSchema,
|
|
860
|
-
interface: tool.interface,
|
|
861
|
-
suggestConfirmation: tool.suggestConfirmation,
|
|
862
|
-
supportsUserActions: tool.supportsUserActions,
|
|
863
|
-
};
|
|
864
|
-
});
|
|
631
|
+
const toolInfo = tools.map(mapToolToJsonSchema);
|
|
632
|
+
debugLog(`[getAllToolsAsJsonSchema POST] Returning ${toolInfo.length} tools`);
|
|
865
633
|
const response = {
|
|
866
634
|
tools: toolInfo,
|
|
867
635
|
reccomendedPrompts: toolboxes.map((toolbox) => toolbox.recommendedPrompt),
|
|
868
636
|
};
|
|
869
|
-
console.log(`[getAllToolsAsJsonSchema POST] Returning ${toolInfo.length} tools`);
|
|
870
|
-
// Process plugins for the response
|
|
871
637
|
const processedResponse = await processPluginsForResponse(response, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
872
638
|
return c.json(processedResponse);
|
|
873
639
|
});
|
|
@@ -1385,23 +1151,11 @@ function setupHttpServer(config, tools, services, toolboxes, metadata, privateKe
|
|
|
1385
1151
|
app.get("/exampleQueries", (c) => {
|
|
1386
1152
|
return c.json(config.exampleQueries || []);
|
|
1387
1153
|
});
|
|
1388
|
-
// POST version of exampleQueries with plugin support
|
|
1389
1154
|
app.post("/exampleQueries", async (c) => {
|
|
1390
1155
|
const agentInfo = await getAgentInfo(c);
|
|
1391
|
-
|
|
1392
|
-
let body = {};
|
|
1393
|
-
try {
|
|
1394
|
-
body = await c.req.json();
|
|
1395
|
-
}
|
|
1396
|
-
catch (error) {
|
|
1397
|
-
body = {}; // Default to empty body if parsing fails
|
|
1398
|
-
}
|
|
1399
|
-
// Process plugins for the request
|
|
1156
|
+
const body = await safeParseBody(c);
|
|
1400
1157
|
const processedPluginData = await processPluginsForRequest(body, agentInfo);
|
|
1401
|
-
|
|
1402
|
-
const queries = config.exampleQueries || [];
|
|
1403
|
-
// Process plugins for the response
|
|
1404
|
-
const processedResponse = await processPluginsForResponse(queries, body, { extraData: { plugins: processedPluginData.plugins } });
|
|
1158
|
+
const processedResponse = await processPluginsForResponse(config.exampleQueries || [], body, { extraData: { plugins: processedPluginData.plugins } });
|
|
1405
1159
|
return c.json(processedResponse);
|
|
1406
1160
|
});
|
|
1407
1161
|
// Services list endpoint
|