@radaros/transport 0.3.14 → 0.3.16
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/README.md +3 -2
- package/dist/index.d.ts +96 -2
- package/dist/index.js +338 -11
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -29,8 +29,9 @@ app.listen(3000);
|
|
|
29
29
|
|
|
30
30
|
## Features
|
|
31
31
|
|
|
32
|
-
- **
|
|
33
|
-
- **
|
|
32
|
+
- **Auto-Discovery** — Reads from the global `Registry` at request time; agents created after server start are immediately available
|
|
33
|
+
- **Express Router** — REST API with streaming support and list endpoints (`GET /agents`, `/teams`, `/workflows`, `/tools`)
|
|
34
|
+
- **Socket.IO Gateway** — Real-time WebSocket communication with dynamic agent/team lookup and tool discovery
|
|
34
35
|
- **A2A Server** — Agent-to-Agent protocol support
|
|
35
36
|
- **CORS & Rate Limiting** — Built-in security middleware
|
|
36
37
|
- **Swagger** — Auto-generated API documentation
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Agent, A2AAgentCard, Registry, Servable, Team, Workflow, EventBus, VoiceAgent } from '@radaros/core';
|
|
1
|
+
import { Agent, A2AAgentCard, MCPToolProviderConfig, ToolDef, MCPToolProvider, Registry, Servable, Team, Workflow, Toolkit, EventBus, VoiceAgent } from '@radaros/core';
|
|
2
2
|
|
|
3
3
|
interface A2AServerOptions {
|
|
4
4
|
agents: Record<string, Agent>;
|
|
@@ -34,6 +34,85 @@ declare function generateMultiAgentCard(agents: Record<string, Agent>, serverUrl
|
|
|
34
34
|
url?: string;
|
|
35
35
|
}, version?: string): A2AAgentCard;
|
|
36
36
|
|
|
37
|
+
interface MCPServerEntry {
|
|
38
|
+
id: string;
|
|
39
|
+
config: MCPToolProviderConfig;
|
|
40
|
+
provider: MCPToolProvider;
|
|
41
|
+
status: "disconnected" | "connecting" | "connected" | "error";
|
|
42
|
+
error?: string;
|
|
43
|
+
toolCount: number;
|
|
44
|
+
connectedAt?: Date;
|
|
45
|
+
}
|
|
46
|
+
interface MCPServerSummary {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
transport: string;
|
|
50
|
+
url?: string;
|
|
51
|
+
command?: string;
|
|
52
|
+
status: string;
|
|
53
|
+
toolCount: number;
|
|
54
|
+
error?: string;
|
|
55
|
+
connectedAt?: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Manages multiple MCP server connections at runtime.
|
|
59
|
+
* Servers can be added/removed/connected/disconnected dynamically,
|
|
60
|
+
* and their tools can be collected for injection into agents.
|
|
61
|
+
*/
|
|
62
|
+
declare class MCPManager {
|
|
63
|
+
private servers;
|
|
64
|
+
/** Add a server config. Auto-generates an id from the name if not provided. */
|
|
65
|
+
add(config: MCPToolProviderConfig, id?: string): MCPServerSummary;
|
|
66
|
+
/** Connect a server by id. Discovers tools on success. */
|
|
67
|
+
connect(id: string): Promise<MCPServerSummary>;
|
|
68
|
+
/** Disconnect a server by id. */
|
|
69
|
+
disconnect(id: string): Promise<MCPServerSummary>;
|
|
70
|
+
/** Remove a server entirely. Disconnects first if connected. */
|
|
71
|
+
remove(id: string): Promise<void>;
|
|
72
|
+
/** Get all tools from all connected servers, merged into one array. */
|
|
73
|
+
getAllTools(): Promise<ToolDef[]>;
|
|
74
|
+
/** Get tools from a specific server. */
|
|
75
|
+
getTools(id: string): Promise<ToolDef[]>;
|
|
76
|
+
/** List all registered servers. */
|
|
77
|
+
list(): MCPServerSummary[];
|
|
78
|
+
/** Get a single server summary. */
|
|
79
|
+
get(id: string): MCPServerSummary;
|
|
80
|
+
has(id: string): boolean;
|
|
81
|
+
/** Disconnect all servers. */
|
|
82
|
+
closeAll(): Promise<void>;
|
|
83
|
+
private getEntry;
|
|
84
|
+
private summarize;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface AdminRouterOptions {
|
|
88
|
+
/** Shared MCPManager instance. If omitted, a new one is created. */
|
|
89
|
+
mcpManager?: MCPManager;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Creates an Express sub-router with admin endpoints for managing
|
|
93
|
+
* MCP servers and the toolkit catalog at runtime.
|
|
94
|
+
*
|
|
95
|
+
* Mount under a prefix: `app.use("/admin", createAdminRouter())`
|
|
96
|
+
*
|
|
97
|
+
* Routes:
|
|
98
|
+
* GET /mcp — list MCP servers
|
|
99
|
+
* POST /mcp — add + connect an MCP server
|
|
100
|
+
* GET /mcp/:id — single server details
|
|
101
|
+
* POST /mcp/:id/connect — connect a server
|
|
102
|
+
* POST /mcp/:id/disconnect — disconnect
|
|
103
|
+
* DELETE /mcp/:id — remove a server
|
|
104
|
+
* GET /mcp/:id/tools — tools from a specific server
|
|
105
|
+
* GET /mcp/tools — all tools across connected servers
|
|
106
|
+
*
|
|
107
|
+
* GET /toolkits — list toolkit catalog
|
|
108
|
+
* GET /toolkits/:id — single toolkit meta
|
|
109
|
+
* POST /toolkits/:id — instantiate a toolkit with config
|
|
110
|
+
*/
|
|
111
|
+
declare function createAdminRouter(opts?: AdminRouterOptions): {
|
|
112
|
+
router: any;
|
|
113
|
+
mcpManager: MCPManager;
|
|
114
|
+
};
|
|
115
|
+
|
|
37
116
|
interface FileUploadOptions {
|
|
38
117
|
maxFileSize?: number;
|
|
39
118
|
maxFiles?: number;
|
|
@@ -104,6 +183,17 @@ interface RouterOptions {
|
|
|
104
183
|
windowMs?: number;
|
|
105
184
|
max?: number;
|
|
106
185
|
} | boolean;
|
|
186
|
+
/** Named tool library exposed via GET /tools. Tools from toolkits are auto-collected. */
|
|
187
|
+
toolLibrary?: Record<string, ToolDef>;
|
|
188
|
+
/** Toolkit instances whose tools are exposed via GET /tools. Merged with toolLibrary. */
|
|
189
|
+
toolkits?: Toolkit[];
|
|
190
|
+
/**
|
|
191
|
+
* Enable admin routes under `/admin` for managing MCP servers and the toolkit catalog.
|
|
192
|
+
* Pass `true` to use defaults, or provide an MCPManager instance to share state.
|
|
193
|
+
*/
|
|
194
|
+
admin?: boolean | {
|
|
195
|
+
mcpManager?: MCPManager;
|
|
196
|
+
};
|
|
107
197
|
}
|
|
108
198
|
|
|
109
199
|
declare function createAgentRouter(opts: RouterOptions): any;
|
|
@@ -218,6 +308,10 @@ interface GatewayOptions {
|
|
|
218
308
|
authMiddleware?: (socket: any, next: (err?: Error) => void) => void;
|
|
219
309
|
/** Max requests per minute per socket. Default: 60 */
|
|
220
310
|
maxRequestsPerMinute?: number;
|
|
311
|
+
/** Named tool library exposed via tools.list event. */
|
|
312
|
+
toolLibrary?: Record<string, ToolDef>;
|
|
313
|
+
/** Toolkit instances whose tools are exposed via tools.list. Merged with toolLibrary. */
|
|
314
|
+
toolkits?: Toolkit[];
|
|
221
315
|
}
|
|
222
316
|
|
|
223
317
|
declare function createAgentGateway(opts: GatewayOptions): void;
|
|
@@ -230,4 +324,4 @@ interface VoiceGatewayOptions {
|
|
|
230
324
|
}
|
|
231
325
|
declare function createVoiceGateway(opts: VoiceGatewayOptions): void;
|
|
232
326
|
|
|
233
|
-
export { type A2AServerOptions, type BrowserGatewayOptions, type FileUploadOptions, type GatewayOptions, type RouterOptions, type SwaggerOptions, type VoiceGatewayOptions, buildMultiModalInput, createA2AServer, createAgentGateway, createAgentRouter, createBrowserGateway, createFileUploadMiddleware, createVoiceGateway, errorHandler, generateAgentCard, generateMultiAgentCard, generateOpenAPISpec, requestLogger };
|
|
327
|
+
export { type A2AServerOptions, type AdminRouterOptions, type BrowserGatewayOptions, type FileUploadOptions, type GatewayOptions, MCPManager, type MCPServerEntry, type MCPServerSummary, type RouterOptions, type SwaggerOptions, type VoiceGatewayOptions, buildMultiModalInput, createA2AServer, createAdminRouter, createAgentGateway, createAgentRouter, createBrowserGateway, createFileUploadMiddleware, createVoiceGateway, errorHandler, generateAgentCard, generateMultiAgentCard, generateOpenAPISpec, requestLogger };
|
package/dist/index.js
CHANGED
|
@@ -341,9 +341,263 @@ function handleTasksCancel(res, body, store) {
|
|
|
341
341
|
});
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
// src/express/
|
|
344
|
+
// src/express/admin-router.ts
|
|
345
345
|
import { createRequire as createRequire2 } from "module";
|
|
346
|
+
import { toolkitCatalog } from "@radaros/core";
|
|
347
|
+
|
|
348
|
+
// src/express/mcp-manager.ts
|
|
349
|
+
import { MCPToolProvider } from "@radaros/core";
|
|
350
|
+
var MCPManager = class {
|
|
351
|
+
servers = /* @__PURE__ */ new Map();
|
|
352
|
+
/** Add a server config. Auto-generates an id from the name if not provided. */
|
|
353
|
+
add(config, id) {
|
|
354
|
+
const serverId = id ?? config.name;
|
|
355
|
+
if (this.servers.has(serverId)) {
|
|
356
|
+
throw new Error(`MCP server "${serverId}" already exists`);
|
|
357
|
+
}
|
|
358
|
+
const provider = new MCPToolProvider(config);
|
|
359
|
+
const entry = {
|
|
360
|
+
id: serverId,
|
|
361
|
+
config,
|
|
362
|
+
provider,
|
|
363
|
+
status: "disconnected",
|
|
364
|
+
toolCount: 0
|
|
365
|
+
};
|
|
366
|
+
this.servers.set(serverId, entry);
|
|
367
|
+
return this.summarize(entry);
|
|
368
|
+
}
|
|
369
|
+
/** Connect a server by id. Discovers tools on success. */
|
|
370
|
+
async connect(id) {
|
|
371
|
+
const entry = this.getEntry(id);
|
|
372
|
+
entry.status = "connecting";
|
|
373
|
+
entry.error = void 0;
|
|
374
|
+
try {
|
|
375
|
+
await entry.provider.connect();
|
|
376
|
+
const tools = await entry.provider.getTools();
|
|
377
|
+
entry.status = "connected";
|
|
378
|
+
entry.toolCount = tools.length;
|
|
379
|
+
entry.connectedAt = /* @__PURE__ */ new Date();
|
|
380
|
+
} catch (err) {
|
|
381
|
+
entry.status = "error";
|
|
382
|
+
entry.error = err.message;
|
|
383
|
+
}
|
|
384
|
+
return this.summarize(entry);
|
|
385
|
+
}
|
|
386
|
+
/** Disconnect a server by id. */
|
|
387
|
+
async disconnect(id) {
|
|
388
|
+
const entry = this.getEntry(id);
|
|
389
|
+
try {
|
|
390
|
+
await entry.provider.close();
|
|
391
|
+
} catch {
|
|
392
|
+
}
|
|
393
|
+
entry.status = "disconnected";
|
|
394
|
+
entry.toolCount = 0;
|
|
395
|
+
entry.connectedAt = void 0;
|
|
396
|
+
return this.summarize(entry);
|
|
397
|
+
}
|
|
398
|
+
/** Remove a server entirely. Disconnects first if connected. */
|
|
399
|
+
async remove(id) {
|
|
400
|
+
const entry = this.getEntry(id);
|
|
401
|
+
if (entry.status === "connected" || entry.status === "connecting") {
|
|
402
|
+
try {
|
|
403
|
+
await entry.provider.close();
|
|
404
|
+
} catch {
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
this.servers.delete(id);
|
|
408
|
+
}
|
|
409
|
+
/** Get all tools from all connected servers, merged into one array. */
|
|
410
|
+
async getAllTools() {
|
|
411
|
+
const all = [];
|
|
412
|
+
for (const entry of this.servers.values()) {
|
|
413
|
+
if (entry.status === "connected") {
|
|
414
|
+
try {
|
|
415
|
+
const tools = await entry.provider.getTools();
|
|
416
|
+
all.push(...tools);
|
|
417
|
+
} catch {
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return all;
|
|
422
|
+
}
|
|
423
|
+
/** Get tools from a specific server. */
|
|
424
|
+
async getTools(id) {
|
|
425
|
+
const entry = this.getEntry(id);
|
|
426
|
+
if (entry.status !== "connected") {
|
|
427
|
+
throw new Error(`MCP server "${id}" is not connected`);
|
|
428
|
+
}
|
|
429
|
+
return entry.provider.getTools();
|
|
430
|
+
}
|
|
431
|
+
/** List all registered servers. */
|
|
432
|
+
list() {
|
|
433
|
+
return Array.from(this.servers.values()).map((e) => this.summarize(e));
|
|
434
|
+
}
|
|
435
|
+
/** Get a single server summary. */
|
|
436
|
+
get(id) {
|
|
437
|
+
return this.summarize(this.getEntry(id));
|
|
438
|
+
}
|
|
439
|
+
has(id) {
|
|
440
|
+
return this.servers.has(id);
|
|
441
|
+
}
|
|
442
|
+
/** Disconnect all servers. */
|
|
443
|
+
async closeAll() {
|
|
444
|
+
const promises = Array.from(this.servers.values()).map(async (entry) => {
|
|
445
|
+
if (entry.status === "connected") {
|
|
446
|
+
try {
|
|
447
|
+
await entry.provider.close();
|
|
448
|
+
} catch {
|
|
449
|
+
}
|
|
450
|
+
entry.status = "disconnected";
|
|
451
|
+
entry.toolCount = 0;
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
await Promise.all(promises);
|
|
455
|
+
}
|
|
456
|
+
getEntry(id) {
|
|
457
|
+
const entry = this.servers.get(id);
|
|
458
|
+
if (!entry) throw new Error(`MCP server "${id}" not found`);
|
|
459
|
+
return entry;
|
|
460
|
+
}
|
|
461
|
+
summarize(entry) {
|
|
462
|
+
return {
|
|
463
|
+
id: entry.id,
|
|
464
|
+
name: entry.config.name,
|
|
465
|
+
transport: entry.config.transport,
|
|
466
|
+
url: entry.config.url,
|
|
467
|
+
command: entry.config.command,
|
|
468
|
+
status: entry.status,
|
|
469
|
+
toolCount: entry.toolCount,
|
|
470
|
+
error: entry.error,
|
|
471
|
+
connectedAt: entry.connectedAt?.toISOString()
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
// src/express/admin-router.ts
|
|
346
477
|
var _require2 = createRequire2(import.meta.url);
|
|
478
|
+
function createAdminRouter(opts) {
|
|
479
|
+
let express;
|
|
480
|
+
try {
|
|
481
|
+
express = _require2("express");
|
|
482
|
+
} catch {
|
|
483
|
+
throw new Error("express is required for createAdminRouter. Install it: npm install express");
|
|
484
|
+
}
|
|
485
|
+
const router = express.Router();
|
|
486
|
+
const mcpManager = opts?.mcpManager ?? new MCPManager();
|
|
487
|
+
router.get("/mcp", (_req, res) => {
|
|
488
|
+
res.json(mcpManager.list());
|
|
489
|
+
});
|
|
490
|
+
router.get("/mcp/tools", async (_req, res) => {
|
|
491
|
+
try {
|
|
492
|
+
const tools = await mcpManager.getAllTools();
|
|
493
|
+
res.json(
|
|
494
|
+
tools.map((t) => ({
|
|
495
|
+
name: t.name,
|
|
496
|
+
description: t.description,
|
|
497
|
+
parameters: Object.keys(t.parameters?.shape ?? {})
|
|
498
|
+
}))
|
|
499
|
+
);
|
|
500
|
+
} catch (err) {
|
|
501
|
+
res.status(500).json({ error: err.message });
|
|
502
|
+
}
|
|
503
|
+
});
|
|
504
|
+
router.post("/mcp", async (req, res) => {
|
|
505
|
+
try {
|
|
506
|
+
const { name, transport, url, command, args, env, headers, id, autoConnect } = req.body;
|
|
507
|
+
if (!name || !transport) {
|
|
508
|
+
return res.status(400).json({ error: "name and transport are required" });
|
|
509
|
+
}
|
|
510
|
+
const config = { name, transport };
|
|
511
|
+
if (url) config.url = url;
|
|
512
|
+
if (command) config.command = command;
|
|
513
|
+
if (args) config.args = args;
|
|
514
|
+
if (env) config.env = env;
|
|
515
|
+
if (headers) config.headers = headers;
|
|
516
|
+
const summary = mcpManager.add(config, id);
|
|
517
|
+
if (autoConnect !== false) {
|
|
518
|
+
const connected = await mcpManager.connect(summary.id);
|
|
519
|
+
return res.status(201).json(connected);
|
|
520
|
+
}
|
|
521
|
+
res.status(201).json(summary);
|
|
522
|
+
} catch (err) {
|
|
523
|
+
res.status(400).json({ error: err.message });
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
router.get("/mcp/:id", (req, res) => {
|
|
527
|
+
try {
|
|
528
|
+
res.json(mcpManager.get(req.params.id));
|
|
529
|
+
} catch (err) {
|
|
530
|
+
res.status(404).json({ error: err.message });
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
router.post("/mcp/:id/connect", async (req, res) => {
|
|
534
|
+
try {
|
|
535
|
+
const summary = await mcpManager.connect(req.params.id);
|
|
536
|
+
res.json(summary);
|
|
537
|
+
} catch (err) {
|
|
538
|
+
res.status(400).json({ error: err.message });
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
router.post("/mcp/:id/disconnect", async (req, res) => {
|
|
542
|
+
try {
|
|
543
|
+
const summary = await mcpManager.disconnect(req.params.id);
|
|
544
|
+
res.json(summary);
|
|
545
|
+
} catch (err) {
|
|
546
|
+
res.status(400).json({ error: err.message });
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
router.delete("/mcp/:id", async (req, res) => {
|
|
550
|
+
try {
|
|
551
|
+
await mcpManager.remove(req.params.id);
|
|
552
|
+
res.json({ ok: true });
|
|
553
|
+
} catch (err) {
|
|
554
|
+
res.status(404).json({ error: err.message });
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
router.get("/mcp/:id/tools", async (req, res) => {
|
|
558
|
+
try {
|
|
559
|
+
const tools = await mcpManager.getTools(req.params.id);
|
|
560
|
+
res.json(
|
|
561
|
+
tools.map((t) => ({
|
|
562
|
+
name: t.name,
|
|
563
|
+
description: t.description,
|
|
564
|
+
parameters: Object.keys(t.parameters?.shape ?? {})
|
|
565
|
+
}))
|
|
566
|
+
);
|
|
567
|
+
} catch (err) {
|
|
568
|
+
res.status(400).json({ error: err.message });
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
router.get("/toolkits", (_req, res) => {
|
|
572
|
+
res.json(toolkitCatalog.list());
|
|
573
|
+
});
|
|
574
|
+
router.get("/toolkits/:id", (req, res) => {
|
|
575
|
+
const meta = toolkitCatalog.get(req.params.id);
|
|
576
|
+
if (!meta) return res.status(404).json({ error: `Toolkit "${req.params.id}" not found` });
|
|
577
|
+
res.json(meta);
|
|
578
|
+
});
|
|
579
|
+
router.post("/toolkits/:id", (req, res) => {
|
|
580
|
+
try {
|
|
581
|
+
const toolkit = toolkitCatalog.create(req.params.id, req.body ?? {});
|
|
582
|
+
const tools = toolkit.getTools().map((t) => ({
|
|
583
|
+
name: t.name,
|
|
584
|
+
description: t.description
|
|
585
|
+
}));
|
|
586
|
+
res.status(201).json({
|
|
587
|
+
id: req.params.id,
|
|
588
|
+
name: toolkit.name,
|
|
589
|
+
tools
|
|
590
|
+
});
|
|
591
|
+
} catch (err) {
|
|
592
|
+
res.status(400).json({ error: err.message });
|
|
593
|
+
}
|
|
594
|
+
});
|
|
595
|
+
return { router, mcpManager };
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
// src/express/file-upload.ts
|
|
599
|
+
import { createRequire as createRequire3 } from "module";
|
|
600
|
+
var _require3 = createRequire3(import.meta.url);
|
|
347
601
|
var MIME_TO_PART_TYPE = {
|
|
348
602
|
"image/png": "image",
|
|
349
603
|
"image/jpeg": "image",
|
|
@@ -365,7 +619,7 @@ function getPartType(mimeType) {
|
|
|
365
619
|
function createFileUploadMiddleware(opts = {}) {
|
|
366
620
|
let multer;
|
|
367
621
|
try {
|
|
368
|
-
multer =
|
|
622
|
+
multer = _require3("multer");
|
|
369
623
|
} catch {
|
|
370
624
|
throw new Error("multer is required for file uploads. Install it: npm install multer");
|
|
371
625
|
}
|
|
@@ -430,15 +684,15 @@ function requestLogger(options) {
|
|
|
430
684
|
}
|
|
431
685
|
|
|
432
686
|
// src/express/router-factory.ts
|
|
433
|
-
import { createRequire as
|
|
434
|
-
import { classifyServables, registry as globalRegistry } from "@radaros/core";
|
|
687
|
+
import { createRequire as createRequire5 } from "module";
|
|
688
|
+
import { classifyServables, collectToolkitTools, describeToolLibrary, registry as globalRegistry } from "@radaros/core";
|
|
435
689
|
|
|
436
690
|
// src/express/swagger.ts
|
|
437
|
-
import { createRequire as
|
|
438
|
-
var
|
|
691
|
+
import { createRequire as createRequire4 } from "module";
|
|
692
|
+
var _require4 = createRequire4(import.meta.url);
|
|
439
693
|
function zodSchemaToJsonSchema(schema) {
|
|
440
694
|
try {
|
|
441
|
-
const zodToJsonSchema =
|
|
695
|
+
const zodToJsonSchema = _require4("zod-to-json-schema").default ?? _require4("zod-to-json-schema");
|
|
442
696
|
const result = zodToJsonSchema(schema, { target: "openApi3" });
|
|
443
697
|
const { $schema, ...rest } = result;
|
|
444
698
|
return rest;
|
|
@@ -861,7 +1115,7 @@ ${agentDesc}`,
|
|
|
861
1115
|
function serveSwaggerUI(spec) {
|
|
862
1116
|
let swaggerUiExpress;
|
|
863
1117
|
try {
|
|
864
|
-
swaggerUiExpress =
|
|
1118
|
+
swaggerUiExpress = _require4("swagger-ui-express");
|
|
865
1119
|
} catch {
|
|
866
1120
|
throw new Error("swagger-ui-express is required for Swagger UI. Install it: npm install swagger-ui-express");
|
|
867
1121
|
}
|
|
@@ -875,7 +1129,7 @@ function serveSwaggerUI(spec) {
|
|
|
875
1129
|
}
|
|
876
1130
|
|
|
877
1131
|
// src/express/router-factory.ts
|
|
878
|
-
var
|
|
1132
|
+
var _require5 = createRequire5(import.meta.url);
|
|
879
1133
|
function corsMiddleware(origins) {
|
|
880
1134
|
return (req, res, next) => {
|
|
881
1135
|
const origin = req.headers.origin;
|
|
@@ -968,7 +1222,7 @@ function createAgentRouter(opts) {
|
|
|
968
1222
|
const reg = opts.registry === false ? null : opts.registry ?? globalRegistry;
|
|
969
1223
|
let express;
|
|
970
1224
|
try {
|
|
971
|
-
express =
|
|
1225
|
+
express = _require5("express");
|
|
972
1226
|
} catch {
|
|
973
1227
|
throw new Error("express is required for createAgentRouter. Install it: npm install express");
|
|
974
1228
|
}
|
|
@@ -1287,6 +1541,29 @@ function createAgentRouter(opts) {
|
|
|
1287
1541
|
res.json(reg.list());
|
|
1288
1542
|
});
|
|
1289
1543
|
}
|
|
1544
|
+
if (opts.admin) {
|
|
1545
|
+
const adminOpts = typeof opts.admin === "object" ? opts.admin : {};
|
|
1546
|
+
const { router: adminRouter } = createAdminRouter({
|
|
1547
|
+
mcpManager: adminOpts.mcpManager
|
|
1548
|
+
});
|
|
1549
|
+
router.use("/admin", adminRouter);
|
|
1550
|
+
}
|
|
1551
|
+
const fromToolkits = opts.toolkits ? collectToolkitTools(opts.toolkits) : {};
|
|
1552
|
+
const mergedTools = { ...fromToolkits, ...opts.toolLibrary ?? {} };
|
|
1553
|
+
if (Object.keys(mergedTools).length > 0) {
|
|
1554
|
+
router.get("/tools", (_req, res) => {
|
|
1555
|
+
res.json(describeToolLibrary(mergedTools));
|
|
1556
|
+
});
|
|
1557
|
+
router.get("/tools/:name", (req, res) => {
|
|
1558
|
+
const tool = mergedTools[req.params.name];
|
|
1559
|
+
if (!tool) return res.status(404).json({ error: `Tool "${req.params.name}" not found` });
|
|
1560
|
+
res.json({
|
|
1561
|
+
name: tool.name,
|
|
1562
|
+
description: tool.description,
|
|
1563
|
+
parameters: Object.keys(tool.parameters.shape ?? {})
|
|
1564
|
+
});
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1290
1567
|
return router;
|
|
1291
1568
|
}
|
|
1292
1569
|
|
|
@@ -1404,7 +1681,7 @@ function createBrowserGateway(opts) {
|
|
|
1404
1681
|
}
|
|
1405
1682
|
|
|
1406
1683
|
// src/socketio/gateway.ts
|
|
1407
|
-
import { classifyServables as classifyServables2, registry as globalRegistry2 } from "@radaros/core";
|
|
1684
|
+
import { classifyServables as classifyServables2, collectToolkitTools as collectToolkitTools2, describeToolLibrary as describeToolLibrary2, registry as globalRegistry2 } from "@radaros/core";
|
|
1408
1685
|
function createSocketRateLimiter(maxPerMinute = 60) {
|
|
1409
1686
|
return () => {
|
|
1410
1687
|
let count = 0;
|
|
@@ -1482,6 +1759,54 @@ function createAgentGateway(opts) {
|
|
|
1482
1759
|
socket.emit("agent.error", { error: error.message });
|
|
1483
1760
|
}
|
|
1484
1761
|
});
|
|
1762
|
+
socket.on("agents.list", (_data, ack) => {
|
|
1763
|
+
if (reg) {
|
|
1764
|
+
ack?.(reg.describeAgents());
|
|
1765
|
+
} else {
|
|
1766
|
+
const names = Object.keys(opts.agents ?? {});
|
|
1767
|
+
ack?.(names.map((n) => ({ name: n })));
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1770
|
+
socket.on("teams.list", (_data, ack) => {
|
|
1771
|
+
if (reg) {
|
|
1772
|
+
ack?.(reg.describeTeams());
|
|
1773
|
+
} else {
|
|
1774
|
+
const names = Object.keys(opts.teams ?? {});
|
|
1775
|
+
ack?.(names.map((n) => ({ name: n })));
|
|
1776
|
+
}
|
|
1777
|
+
});
|
|
1778
|
+
socket.on("workflows.list", (_data, ack) => {
|
|
1779
|
+
if (reg) {
|
|
1780
|
+
ack?.(reg.describeWorkflows());
|
|
1781
|
+
} else {
|
|
1782
|
+
ack?.([]);
|
|
1783
|
+
}
|
|
1784
|
+
});
|
|
1785
|
+
socket.on("registry.list", (_data, ack) => {
|
|
1786
|
+
if (reg) {
|
|
1787
|
+
ack?.(reg.list());
|
|
1788
|
+
} else {
|
|
1789
|
+
ack?.({
|
|
1790
|
+
agents: Object.keys(opts.agents ?? {}),
|
|
1791
|
+
teams: Object.keys(opts.teams ?? {}),
|
|
1792
|
+
workflows: []
|
|
1793
|
+
});
|
|
1794
|
+
}
|
|
1795
|
+
});
|
|
1796
|
+
const fromToolkits = opts.toolkits ? collectToolkitTools2(opts.toolkits) : {};
|
|
1797
|
+
const mergedTools = { ...fromToolkits, ...opts.toolLibrary ?? {} };
|
|
1798
|
+
socket.on("tools.list", (_data, ack) => {
|
|
1799
|
+
ack?.(describeToolLibrary2(mergedTools));
|
|
1800
|
+
});
|
|
1801
|
+
socket.on("tools.get", (data, ack) => {
|
|
1802
|
+
const tool = mergedTools[data?.name];
|
|
1803
|
+
if (!tool) return ack?.({ error: `Tool "${data?.name}" not found` });
|
|
1804
|
+
ack?.({
|
|
1805
|
+
name: tool.name,
|
|
1806
|
+
description: tool.description,
|
|
1807
|
+
parameters: Object.keys(tool.parameters.shape ?? {})
|
|
1808
|
+
});
|
|
1809
|
+
});
|
|
1485
1810
|
socket.on("disconnect", () => {
|
|
1486
1811
|
});
|
|
1487
1812
|
socket.on("team.run", async (data) => {
|
|
@@ -1634,8 +1959,10 @@ function createVoiceGateway(opts) {
|
|
|
1634
1959
|
});
|
|
1635
1960
|
}
|
|
1636
1961
|
export {
|
|
1962
|
+
MCPManager,
|
|
1637
1963
|
buildMultiModalInput,
|
|
1638
1964
|
createA2AServer,
|
|
1965
|
+
createAdminRouter,
|
|
1639
1966
|
createAgentGateway,
|
|
1640
1967
|
createAgentRouter,
|
|
1641
1968
|
createBrowserGateway,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@radaros/transport",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.16",
|
|
4
4
|
"description": "HTTP and WebSocket transport layer for RadarOS agents",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"typescript": "^5.6.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@radaros/core": "^0.3.
|
|
42
|
+
"@radaros/core": "^0.3.16",
|
|
43
43
|
"@types/express": "^4.0.0 || ^5.0.0",
|
|
44
44
|
"express": "^4.0.0 || ^5.0.0",
|
|
45
45
|
"multer": ">=2.0.0",
|