@dexto/server 1.2.5

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.
Files changed (174) hide show
  1. package/LICENSE +44 -0
  2. package/dist/a2a/adapters/index.cjs +42 -0
  3. package/dist/a2a/adapters/index.d.ts +10 -0
  4. package/dist/a2a/adapters/index.d.ts.map +1 -0
  5. package/dist/a2a/adapters/index.js +12 -0
  6. package/dist/a2a/adapters/message.cjs +193 -0
  7. package/dist/a2a/adapters/message.d.ts +50 -0
  8. package/dist/a2a/adapters/message.d.ts.map +1 -0
  9. package/dist/a2a/adapters/message.js +167 -0
  10. package/dist/a2a/adapters/state.cjs +57 -0
  11. package/dist/a2a/adapters/state.d.ts +36 -0
  12. package/dist/a2a/adapters/state.d.ts.map +1 -0
  13. package/dist/a2a/adapters/state.js +32 -0
  14. package/dist/a2a/adapters/task-view.cjs +85 -0
  15. package/dist/a2a/adapters/task-view.d.ts +58 -0
  16. package/dist/a2a/adapters/task-view.d.ts.map +1 -0
  17. package/dist/a2a/adapters/task-view.js +60 -0
  18. package/dist/a2a/index.cjs +51 -0
  19. package/dist/a2a/index.d.ts +15 -0
  20. package/dist/a2a/index.d.ts.map +1 -0
  21. package/dist/a2a/index.js +30 -0
  22. package/dist/a2a/jsonrpc/index.cjs +38 -0
  23. package/dist/a2a/jsonrpc/index.d.ts +11 -0
  24. package/dist/a2a/jsonrpc/index.d.ts.map +1 -0
  25. package/dist/a2a/jsonrpc/index.js +10 -0
  26. package/dist/a2a/jsonrpc/methods.cjs +183 -0
  27. package/dist/a2a/jsonrpc/methods.d.ts +110 -0
  28. package/dist/a2a/jsonrpc/methods.d.ts.map +1 -0
  29. package/dist/a2a/jsonrpc/methods.js +159 -0
  30. package/dist/a2a/jsonrpc/server.cjs +199 -0
  31. package/dist/a2a/jsonrpc/server.d.ts +100 -0
  32. package/dist/a2a/jsonrpc/server.d.ts.map +1 -0
  33. package/dist/a2a/jsonrpc/server.js +175 -0
  34. package/dist/a2a/jsonrpc/types.cjs +47 -0
  35. package/dist/a2a/jsonrpc/types.d.ts +91 -0
  36. package/dist/a2a/jsonrpc/types.d.ts.map +1 -0
  37. package/dist/a2a/jsonrpc/types.js +21 -0
  38. package/dist/a2a/types.cjs +16 -0
  39. package/dist/a2a/types.d.ts +250 -0
  40. package/dist/a2a/types.d.ts.map +1 -0
  41. package/dist/a2a/types.js +0 -0
  42. package/dist/approval/approval-coordinator.cjs +87 -0
  43. package/dist/approval/approval-coordinator.d.ts +52 -0
  44. package/dist/approval/approval-coordinator.d.ts.map +1 -0
  45. package/dist/approval/approval-coordinator.js +63 -0
  46. package/dist/approval/manual-approval-handler.cjs +100 -0
  47. package/dist/approval/manual-approval-handler.d.ts +32 -0
  48. package/dist/approval/manual-approval-handler.d.ts.map +1 -0
  49. package/dist/approval/manual-approval-handler.js +76 -0
  50. package/dist/events/a2a-sse-subscriber.cjs +271 -0
  51. package/dist/events/a2a-sse-subscriber.d.ts +94 -0
  52. package/dist/events/a2a-sse-subscriber.d.ts.map +1 -0
  53. package/dist/events/a2a-sse-subscriber.js +247 -0
  54. package/dist/events/types.cjs +16 -0
  55. package/dist/events/types.d.ts +15 -0
  56. package/dist/events/types.d.ts.map +1 -0
  57. package/dist/events/types.js +0 -0
  58. package/dist/events/webhook-subscriber.cjs +301 -0
  59. package/dist/events/webhook-subscriber.d.ts +64 -0
  60. package/dist/events/webhook-subscriber.d.ts.map +1 -0
  61. package/dist/events/webhook-subscriber.js +269 -0
  62. package/dist/events/webhook-types.cjs +16 -0
  63. package/dist/events/webhook-types.d.ts +91 -0
  64. package/dist/events/webhook-types.d.ts.map +1 -0
  65. package/dist/events/webhook-types.js +0 -0
  66. package/dist/hono/__tests__/test-fixtures.cjs +236 -0
  67. package/dist/hono/__tests__/test-fixtures.d.ts +65 -0
  68. package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -0
  69. package/dist/hono/__tests__/test-fixtures.js +197 -0
  70. package/dist/hono/index.cjs +166 -0
  71. package/dist/hono/index.d.ts +2783 -0
  72. package/dist/hono/index.d.ts.map +1 -0
  73. package/dist/hono/index.js +141 -0
  74. package/dist/hono/middleware/auth.cjs +75 -0
  75. package/dist/hono/middleware/auth.d.ts +3 -0
  76. package/dist/hono/middleware/auth.d.ts.map +1 -0
  77. package/dist/hono/middleware/auth.js +51 -0
  78. package/dist/hono/middleware/cors.cjs +57 -0
  79. package/dist/hono/middleware/cors.d.ts +9 -0
  80. package/dist/hono/middleware/cors.d.ts.map +1 -0
  81. package/dist/hono/middleware/cors.js +33 -0
  82. package/dist/hono/middleware/error.cjs +131 -0
  83. package/dist/hono/middleware/error.d.ts +5 -0
  84. package/dist/hono/middleware/error.d.ts.map +1 -0
  85. package/dist/hono/middleware/error.js +105 -0
  86. package/dist/hono/middleware/redaction.cjs +45 -0
  87. package/dist/hono/middleware/redaction.d.ts +4 -0
  88. package/dist/hono/middleware/redaction.d.ts.map +1 -0
  89. package/dist/hono/middleware/redaction.js +20 -0
  90. package/dist/hono/node/index.cjs +139 -0
  91. package/dist/hono/node/index.d.ts +19 -0
  92. package/dist/hono/node/index.d.ts.map +1 -0
  93. package/dist/hono/node/index.js +115 -0
  94. package/dist/hono/routes/a2a-jsonrpc.cjs +119 -0
  95. package/dist/hono/routes/a2a-jsonrpc.d.ts +46 -0
  96. package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -0
  97. package/dist/hono/routes/a2a-jsonrpc.js +95 -0
  98. package/dist/hono/routes/a2a-tasks.cjs +315 -0
  99. package/dist/hono/routes/a2a-tasks.d.ts +530 -0
  100. package/dist/hono/routes/a2a-tasks.d.ts.map +1 -0
  101. package/dist/hono/routes/a2a-tasks.js +291 -0
  102. package/dist/hono/routes/a2a.cjs +36 -0
  103. package/dist/hono/routes/a2a.d.ts +4 -0
  104. package/dist/hono/routes/a2a.d.ts.map +1 -0
  105. package/dist/hono/routes/a2a.js +12 -0
  106. package/dist/hono/routes/agents.cjs +735 -0
  107. package/dist/hono/routes/agents.d.ts +650 -0
  108. package/dist/hono/routes/agents.d.ts.map +1 -0
  109. package/dist/hono/routes/agents.js +711 -0
  110. package/dist/hono/routes/approvals.cjs +125 -0
  111. package/dist/hono/routes/approvals.d.ts +89 -0
  112. package/dist/hono/routes/approvals.d.ts.map +1 -0
  113. package/dist/hono/routes/approvals.js +101 -0
  114. package/dist/hono/routes/greeting.cjs +60 -0
  115. package/dist/hono/routes/greeting.d.ts +19 -0
  116. package/dist/hono/routes/greeting.d.ts.map +1 -0
  117. package/dist/hono/routes/greeting.js +36 -0
  118. package/dist/hono/routes/health.cjs +45 -0
  119. package/dist/hono/routes/health.d.ts +17 -0
  120. package/dist/hono/routes/health.d.ts.map +1 -0
  121. package/dist/hono/routes/health.js +21 -0
  122. package/dist/hono/routes/llm.cjs +298 -0
  123. package/dist/hono/routes/llm.d.ts +294 -0
  124. package/dist/hono/routes/llm.d.ts.map +1 -0
  125. package/dist/hono/routes/llm.js +287 -0
  126. package/dist/hono/routes/mcp.cjs +356 -0
  127. package/dist/hono/routes/mcp.d.ts +246 -0
  128. package/dist/hono/routes/mcp.d.ts.map +1 -0
  129. package/dist/hono/routes/mcp.js +332 -0
  130. package/dist/hono/routes/memory.cjs +192 -0
  131. package/dist/hono/routes/memory.d.ts +146 -0
  132. package/dist/hono/routes/memory.d.ts.map +1 -0
  133. package/dist/hono/routes/memory.js +168 -0
  134. package/dist/hono/routes/messages.cjs +320 -0
  135. package/dist/hono/routes/messages.d.ts +163 -0
  136. package/dist/hono/routes/messages.d.ts.map +1 -0
  137. package/dist/hono/routes/messages.js +296 -0
  138. package/dist/hono/routes/prompts.cjs +228 -0
  139. package/dist/hono/routes/prompts.d.ts +150 -0
  140. package/dist/hono/routes/prompts.d.ts.map +1 -0
  141. package/dist/hono/routes/prompts.js +204 -0
  142. package/dist/hono/routes/resources.cjs +110 -0
  143. package/dist/hono/routes/resources.d.ts +76 -0
  144. package/dist/hono/routes/resources.d.ts.map +1 -0
  145. package/dist/hono/routes/resources.js +86 -0
  146. package/dist/hono/routes/search.cjs +109 -0
  147. package/dist/hono/routes/search.d.ts +137 -0
  148. package/dist/hono/routes/search.d.ts.map +1 -0
  149. package/dist/hono/routes/search.js +85 -0
  150. package/dist/hono/routes/sessions.cjs +366 -0
  151. package/dist/hono/routes/sessions.d.ts +229 -0
  152. package/dist/hono/routes/sessions.d.ts.map +1 -0
  153. package/dist/hono/routes/sessions.js +342 -0
  154. package/dist/hono/routes/webhooks.cjs +228 -0
  155. package/dist/hono/routes/webhooks.d.ts +127 -0
  156. package/dist/hono/routes/webhooks.d.ts.map +1 -0
  157. package/dist/hono/routes/webhooks.js +204 -0
  158. package/dist/hono/schemas/responses.cjs +276 -0
  159. package/dist/hono/schemas/responses.d.ts +1418 -0
  160. package/dist/hono/schemas/responses.d.ts.map +1 -0
  161. package/dist/hono/schemas/responses.js +227 -0
  162. package/dist/hono/types.cjs +16 -0
  163. package/dist/hono/types.d.ts +6 -0
  164. package/dist/hono/types.d.ts.map +1 -0
  165. package/dist/hono/types.js +0 -0
  166. package/dist/index.cjs +38 -0
  167. package/dist/index.d.ts +11 -0
  168. package/dist/index.d.ts.map +1 -0
  169. package/dist/index.js +9 -0
  170. package/dist/mcp/mcp-handler.cjs +145 -0
  171. package/dist/mcp/mcp-handler.d.ts +14 -0
  172. package/dist/mcp/mcp-handler.d.ts.map +1 -0
  173. package/dist/mcp/mcp-handler.js +118 -0
  174. package/package.json +59 -0
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var redaction_exports = {};
20
+ __export(redaction_exports, {
21
+ prettyJsonMiddleware: () => prettyJsonMiddleware,
22
+ redactionMiddleware: () => redactionMiddleware
23
+ });
24
+ module.exports = __toCommonJS(redaction_exports);
25
+ var import_pretty_json = require("hono/pretty-json");
26
+ var import_core = require("@dexto/core");
27
+ const prettyJsonMiddleware = (0, import_pretty_json.prettyJSON)();
28
+ const redactionMiddleware = async (ctx, next) => {
29
+ const originalJson = ctx.json.bind(ctx);
30
+ ctx.json = ((data, status, headers) => {
31
+ const redacted = (0, import_core.redactSensitiveData)(data);
32
+ return originalJson(redacted, status, headers);
33
+ });
34
+ const originalBody = ctx.body.bind(ctx);
35
+ ctx.body = ((data, status, headers) => {
36
+ const payload = typeof data === "string" ? (0, import_core.redactSensitiveData)(data) : data;
37
+ return originalBody(payload, status, headers);
38
+ });
39
+ await next();
40
+ };
41
+ // Annotate the CommonJS export names for ESM import in node:
42
+ 0 && (module.exports = {
43
+ prettyJsonMiddleware,
44
+ redactionMiddleware
45
+ });
@@ -0,0 +1,4 @@
1
+ import type { MiddlewareHandler } from 'hono';
2
+ export declare const prettyJsonMiddleware: MiddlewareHandler;
3
+ export declare const redactionMiddleware: MiddlewareHandler;
4
+ //# sourceMappingURL=redaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../../src/hono/middleware/redaction.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAG9C,eAAO,MAAM,oBAAoB,mBAAe,CAAC;AAEjD,eAAO,MAAM,mBAAmB,EAAE,iBAejC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { prettyJSON } from "hono/pretty-json";
2
+ import { redactSensitiveData } from "@dexto/core";
3
+ const prettyJsonMiddleware = prettyJSON();
4
+ const redactionMiddleware = async (ctx, next) => {
5
+ const originalJson = ctx.json.bind(ctx);
6
+ ctx.json = ((data, status, headers) => {
7
+ const redacted = redactSensitiveData(data);
8
+ return originalJson(redacted, status, headers);
9
+ });
10
+ const originalBody = ctx.body.bind(ctx);
11
+ ctx.body = ((data, status, headers) => {
12
+ const payload = typeof data === "string" ? redactSensitiveData(data) : data;
13
+ return originalBody(payload, status, headers);
14
+ });
15
+ await next();
16
+ };
17
+ export {
18
+ prettyJsonMiddleware,
19
+ redactionMiddleware
20
+ };
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var node_exports = {};
20
+ __export(node_exports, {
21
+ createNodeServer: () => createNodeServer
22
+ });
23
+ module.exports = __toCommonJS(node_exports);
24
+ var import_node_http = require("node:http");
25
+ var import_node_stream = require("node:stream");
26
+ var import_core = require("@dexto/core");
27
+ function createNodeServer(app, options) {
28
+ const { getAgent: _getAgent } = options;
29
+ const webhookSubscriber = app.webhookSubscriber;
30
+ const server = (0, import_node_http.createServer)(async (req, res) => {
31
+ try {
32
+ if (options.mcpHandlers && req.url?.startsWith("/mcp")) {
33
+ if (req.method === "GET") {
34
+ await options.mcpHandlers.handleGet(req, res);
35
+ return;
36
+ }
37
+ if (req.method === "POST") {
38
+ req.setEncoding("utf8");
39
+ let body = "";
40
+ const MAX_BODY_SIZE = 10 * 1024 * 1024;
41
+ req.on("data", (chunk) => {
42
+ body += chunk;
43
+ if (body.length > MAX_BODY_SIZE) {
44
+ req.destroy();
45
+ res.statusCode = 413;
46
+ res.end("Payload too large");
47
+ }
48
+ });
49
+ req.on("end", async () => {
50
+ try {
51
+ const parsed = body.length > 0 ? JSON.parse(body) : void 0;
52
+ await options.mcpHandlers.handlePost(req, res, parsed);
53
+ } catch (err) {
54
+ import_core.logger.error(`Failed to process MCP POST body: ${String(err)}`);
55
+ res.statusCode = 400;
56
+ res.end("Invalid JSON body");
57
+ }
58
+ });
59
+ req.on("error", (err) => {
60
+ import_core.logger.error(`Error reading MCP POST body: ${String(err)}`);
61
+ res.statusCode = 500;
62
+ res.end("Failed to read request body");
63
+ });
64
+ return;
65
+ }
66
+ }
67
+ const request = await toRequest(req);
68
+ const response = await app.fetch(request);
69
+ await sendNodeResponse(res, response);
70
+ } catch (error) {
71
+ const message = error instanceof Error ? error.message : String(error);
72
+ import_core.logger.error(`Unhandled error in Node bridge: ${message}`, { error });
73
+ res.statusCode = 500;
74
+ res.end("Internal Server Error");
75
+ }
76
+ });
77
+ server.on("close", () => {
78
+ webhookSubscriber?.cleanup?.();
79
+ });
80
+ if (typeof options.port === "number") {
81
+ const hostname = options.hostname ?? "0.0.0.0";
82
+ server.listen(options.port, hostname, () => {
83
+ import_core.logger.info(`Hono Node bridge listening on http://${hostname}:${options.port}`);
84
+ });
85
+ }
86
+ const result = {
87
+ server
88
+ };
89
+ if (webhookSubscriber) {
90
+ result.webhookSubscriber = webhookSubscriber;
91
+ }
92
+ return result;
93
+ }
94
+ async function toRequest(req) {
95
+ const protocol = req.socket?.encrypted ? "https" : "http";
96
+ const host = req.headers.host ?? "localhost";
97
+ const url = new URL(req.url ?? "/", `${protocol}://${host}`);
98
+ const headers = new globalThis.Headers();
99
+ for (const [key, value] of Object.entries(req.headers)) {
100
+ if (value === void 0) continue;
101
+ if (Array.isArray(value)) {
102
+ value.forEach((entry) => headers.append(key, entry));
103
+ } else {
104
+ headers.set(key, value);
105
+ }
106
+ }
107
+ const method = req.method ?? "GET";
108
+ const body = method === "GET" || method === "HEAD" ? null : req;
109
+ return new globalThis.Request(url, {
110
+ method,
111
+ headers,
112
+ body: body ?? void 0,
113
+ duplex: body ? "half" : void 0
114
+ });
115
+ }
116
+ async function sendNodeResponse(res, response) {
117
+ res.statusCode = response.status;
118
+ response.headers.forEach((value, key) => {
119
+ if (key.toLowerCase() === "content-length") {
120
+ return;
121
+ }
122
+ res.setHeader(key, value);
123
+ });
124
+ if (!response.body) {
125
+ res.end();
126
+ return;
127
+ }
128
+ const webStream = response.body;
129
+ const readable = import_node_stream.Readable.fromWeb(webStream);
130
+ await new Promise((resolve, reject) => {
131
+ readable.on("error", reject);
132
+ res.on("finish", resolve);
133
+ readable.pipe(res);
134
+ });
135
+ }
136
+ // Annotate the CommonJS export names for ESM import in node:
137
+ 0 && (module.exports = {
138
+ createNodeServer
139
+ });
@@ -0,0 +1,19 @@
1
+ import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';
2
+ import type { DextoApp } from '../types.js';
3
+ import type { DextoAgent } from '@dexto/core';
4
+ import type { WebhookEventSubscriber } from '../../events/webhook-subscriber.js';
5
+ export type NodeBridgeOptions = {
6
+ getAgent: () => DextoAgent;
7
+ port?: number;
8
+ hostname?: string;
9
+ mcpHandlers?: {
10
+ handlePost: (req: IncomingMessage, res: ServerResponse, body: unknown) => Promise<void> | void;
11
+ handleGet: (req: IncomingMessage, res: ServerResponse) => Promise<void> | void;
12
+ } | null;
13
+ };
14
+ export type NodeBridgeResult = {
15
+ server: ReturnType<typeof createServer>;
16
+ webhookSubscriber?: WebhookEventSubscriber;
17
+ };
18
+ export declare function createNodeServer(app: DextoApp, options: NodeBridgeOptions): NodeBridgeResult;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hono/node/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAGpF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAKjF,MAAM,MAAM,iBAAiB,GAAG;IAC5B,QAAQ,EAAE,MAAM,UAAU,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE;QACV,UAAU,EAAE,CACR,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,OAAO,KACZ,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;QAC1B,SAAS,EAAE,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;KAClF,GAAG,IAAI,CAAC;CACZ,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;IACxC,iBAAiB,CAAC,EAAE,sBAAsB,CAAC;CAC9C,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CAyE5F"}
@@ -0,0 +1,115 @@
1
+ import { createServer } from "node:http";
2
+ import { Readable } from "node:stream";
3
+ import { logger } from "@dexto/core";
4
+ function createNodeServer(app, options) {
5
+ const { getAgent: _getAgent } = options;
6
+ const webhookSubscriber = app.webhookSubscriber;
7
+ const server = createServer(async (req, res) => {
8
+ try {
9
+ if (options.mcpHandlers && req.url?.startsWith("/mcp")) {
10
+ if (req.method === "GET") {
11
+ await options.mcpHandlers.handleGet(req, res);
12
+ return;
13
+ }
14
+ if (req.method === "POST") {
15
+ req.setEncoding("utf8");
16
+ let body = "";
17
+ const MAX_BODY_SIZE = 10 * 1024 * 1024;
18
+ req.on("data", (chunk) => {
19
+ body += chunk;
20
+ if (body.length > MAX_BODY_SIZE) {
21
+ req.destroy();
22
+ res.statusCode = 413;
23
+ res.end("Payload too large");
24
+ }
25
+ });
26
+ req.on("end", async () => {
27
+ try {
28
+ const parsed = body.length > 0 ? JSON.parse(body) : void 0;
29
+ await options.mcpHandlers.handlePost(req, res, parsed);
30
+ } catch (err) {
31
+ logger.error(`Failed to process MCP POST body: ${String(err)}`);
32
+ res.statusCode = 400;
33
+ res.end("Invalid JSON body");
34
+ }
35
+ });
36
+ req.on("error", (err) => {
37
+ logger.error(`Error reading MCP POST body: ${String(err)}`);
38
+ res.statusCode = 500;
39
+ res.end("Failed to read request body");
40
+ });
41
+ return;
42
+ }
43
+ }
44
+ const request = await toRequest(req);
45
+ const response = await app.fetch(request);
46
+ await sendNodeResponse(res, response);
47
+ } catch (error) {
48
+ const message = error instanceof Error ? error.message : String(error);
49
+ logger.error(`Unhandled error in Node bridge: ${message}`, { error });
50
+ res.statusCode = 500;
51
+ res.end("Internal Server Error");
52
+ }
53
+ });
54
+ server.on("close", () => {
55
+ webhookSubscriber?.cleanup?.();
56
+ });
57
+ if (typeof options.port === "number") {
58
+ const hostname = options.hostname ?? "0.0.0.0";
59
+ server.listen(options.port, hostname, () => {
60
+ logger.info(`Hono Node bridge listening on http://${hostname}:${options.port}`);
61
+ });
62
+ }
63
+ const result = {
64
+ server
65
+ };
66
+ if (webhookSubscriber) {
67
+ result.webhookSubscriber = webhookSubscriber;
68
+ }
69
+ return result;
70
+ }
71
+ async function toRequest(req) {
72
+ const protocol = req.socket?.encrypted ? "https" : "http";
73
+ const host = req.headers.host ?? "localhost";
74
+ const url = new URL(req.url ?? "/", `${protocol}://${host}`);
75
+ const headers = new globalThis.Headers();
76
+ for (const [key, value] of Object.entries(req.headers)) {
77
+ if (value === void 0) continue;
78
+ if (Array.isArray(value)) {
79
+ value.forEach((entry) => headers.append(key, entry));
80
+ } else {
81
+ headers.set(key, value);
82
+ }
83
+ }
84
+ const method = req.method ?? "GET";
85
+ const body = method === "GET" || method === "HEAD" ? null : req;
86
+ return new globalThis.Request(url, {
87
+ method,
88
+ headers,
89
+ body: body ?? void 0,
90
+ duplex: body ? "half" : void 0
91
+ });
92
+ }
93
+ async function sendNodeResponse(res, response) {
94
+ res.statusCode = response.status;
95
+ response.headers.forEach((value, key) => {
96
+ if (key.toLowerCase() === "content-length") {
97
+ return;
98
+ }
99
+ res.setHeader(key, value);
100
+ });
101
+ if (!response.body) {
102
+ res.end();
103
+ return;
104
+ }
105
+ const webStream = response.body;
106
+ const readable = Readable.fromWeb(webStream);
107
+ await new Promise((resolve, reject) => {
108
+ readable.on("error", reject);
109
+ res.on("finish", resolve);
110
+ readable.pipe(res);
111
+ });
112
+ }
113
+ export {
114
+ createNodeServer
115
+ };
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var a2a_jsonrpc_exports = {};
20
+ __export(a2a_jsonrpc_exports, {
21
+ createA2AJsonRpcRouter: () => createA2AJsonRpcRouter
22
+ });
23
+ module.exports = __toCommonJS(a2a_jsonrpc_exports);
24
+ var import_hono = require("hono");
25
+ var import_server = require("../../a2a/jsonrpc/server.js");
26
+ var import_methods = require("../../a2a/jsonrpc/methods.js");
27
+ var import_core = require("@dexto/core");
28
+ var import_message = require("../../a2a/adapters/message.js");
29
+ function createA2AJsonRpcRouter(getAgent, sseSubscriber) {
30
+ const app = new import_hono.Hono();
31
+ app.post("/jsonrpc", async (ctx) => {
32
+ try {
33
+ const agent = getAgent();
34
+ const requestBody = await ctx.req.json();
35
+ const isStreamingRequest = !Array.isArray(requestBody) && requestBody.method === "message/stream";
36
+ if (isStreamingRequest) {
37
+ import_core.logger.info("JSON-RPC streaming request: message/stream");
38
+ const params = requestBody.params;
39
+ if (!params?.message) {
40
+ return ctx.json({
41
+ jsonrpc: "2.0",
42
+ error: {
43
+ code: -32602,
44
+ message: "Invalid params: message is required"
45
+ },
46
+ id: requestBody.id
47
+ });
48
+ }
49
+ const taskId = params.message.taskId;
50
+ const session = await agent.createSession(taskId);
51
+ const stream = sseSubscriber.createStream(session.id);
52
+ const { text, image, file } = (0, import_message.a2aToInternalMessage)(params.message);
53
+ agent.run(text, image, file, session.id).catch((error) => {
54
+ import_core.logger.error(`Error in streaming task ${session.id}: ${error}`);
55
+ });
56
+ import_core.logger.info(`JSON-RPC SSE stream opened for task ${session.id}`);
57
+ return new Response(stream, {
58
+ headers: {
59
+ "Content-Type": "text/event-stream",
60
+ "Cache-Control": "no-cache",
61
+ Connection: "keep-alive",
62
+ "X-Accel-Buffering": "no"
63
+ }
64
+ });
65
+ }
66
+ const handlers = new import_methods.A2AMethodHandlers(agent);
67
+ const rpcServer = new import_server.JsonRpcServer({
68
+ methods: handlers.getMethods(),
69
+ onError: (error, request) => {
70
+ import_core.logger.error(`JSON-RPC error for method ${request?.method}: ${error.message}`, {
71
+ error,
72
+ request
73
+ });
74
+ }
75
+ });
76
+ import_core.logger.debug(`A2A JSON-RPC request received`, {
77
+ method: Array.isArray(requestBody) ? `batch(${requestBody.length})` : requestBody.method
78
+ });
79
+ const response = await rpcServer.handle(requestBody);
80
+ return ctx.json(response);
81
+ } catch (error) {
82
+ import_core.logger.error(`Failed to process JSON-RPC request: ${error}`, { error });
83
+ return ctx.json({
84
+ jsonrpc: "2.0",
85
+ error: {
86
+ code: -32700,
87
+ message: "Parse error",
88
+ data: error instanceof Error ? error.message : String(error)
89
+ },
90
+ id: null
91
+ });
92
+ }
93
+ });
94
+ app.get("/jsonrpc", (ctx) => {
95
+ const agent = getAgent();
96
+ const handlers = new import_methods.A2AMethodHandlers(agent);
97
+ return ctx.json({
98
+ service: "A2A JSON-RPC 2.0",
99
+ version: "0.3.0",
100
+ endpoint: "/jsonrpc",
101
+ methods: Object.keys(handlers.getMethods()),
102
+ usage: {
103
+ method: "POST",
104
+ contentType: "application/json",
105
+ example: {
106
+ jsonrpc: "2.0",
107
+ method: "agent.getInfo",
108
+ params: {},
109
+ id: 1
110
+ }
111
+ }
112
+ });
113
+ });
114
+ return app;
115
+ }
116
+ // Annotate the CommonJS export names for ESM import in node:
117
+ 0 && (module.exports = {
118
+ createA2AJsonRpcRouter
119
+ });
@@ -0,0 +1,46 @@
1
+ /**
2
+ * A2A JSON-RPC HTTP Endpoint
3
+ *
4
+ * Exposes A2A Protocol JSON-RPC methods via HTTP POST endpoint.
5
+ * Implements JSON-RPC 2.0 over HTTP transport.
6
+ */
7
+ import { Hono } from 'hono';
8
+ import type { DextoAgent } from '@dexto/core';
9
+ import type { A2ASseEventSubscriber } from '../../events/a2a-sse-subscriber.js';
10
+ /**
11
+ * Create A2A JSON-RPC router
12
+ *
13
+ * Exposes POST /jsonrpc endpoint for A2A Protocol communication.
14
+ *
15
+ * Usage:
16
+ * ```typescript
17
+ * const a2aRouter = createA2AJsonRpcRouter(getAgent, sseSubscriber);
18
+ * app.route('/', a2aRouter);
19
+ * ```
20
+ *
21
+ * Example request:
22
+ * ```json
23
+ * POST /jsonrpc
24
+ * Content-Type: application/json
25
+ *
26
+ * {
27
+ * "jsonrpc": "2.0",
28
+ * "method": "message/send",
29
+ * "params": {
30
+ * "message": {
31
+ * "role": "user",
32
+ * "parts": [{ "kind": "text", "text": "Hello!" }],
33
+ * "messageId": "msg-123",
34
+ * "kind": "message"
35
+ * }
36
+ * },
37
+ * "id": 1
38
+ * }
39
+ * ```
40
+ *
41
+ * @param getAgent Function to get current DextoAgent instance
42
+ * @param sseSubscriber SSE event subscriber for streaming methods
43
+ * @returns Hono router with /jsonrpc endpoint
44
+ */
45
+ export declare function createA2AJsonRpcRouter(getAgent: () => DextoAgent, sseSubscriber: A2ASseEventSubscriber): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
46
+ //# sourceMappingURL=a2a-jsonrpc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2a-jsonrpc.d.ts","sourceRoot":"","sources":["../../../src/hono/routes/a2a-jsonrpc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAGhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,sBAAsB,CAClC,QAAQ,EAAE,MAAM,UAAU,EAC1B,aAAa,EAAE,qBAAqB,8EA4HvC"}
@@ -0,0 +1,95 @@
1
+ import { Hono } from "hono";
2
+ import { JsonRpcServer } from "../../a2a/jsonrpc/server.js";
3
+ import { A2AMethodHandlers } from "../../a2a/jsonrpc/methods.js";
4
+ import { logger } from "@dexto/core";
5
+ import { a2aToInternalMessage } from "../../a2a/adapters/message.js";
6
+ function createA2AJsonRpcRouter(getAgent, sseSubscriber) {
7
+ const app = new Hono();
8
+ app.post("/jsonrpc", async (ctx) => {
9
+ try {
10
+ const agent = getAgent();
11
+ const requestBody = await ctx.req.json();
12
+ const isStreamingRequest = !Array.isArray(requestBody) && requestBody.method === "message/stream";
13
+ if (isStreamingRequest) {
14
+ logger.info("JSON-RPC streaming request: message/stream");
15
+ const params = requestBody.params;
16
+ if (!params?.message) {
17
+ return ctx.json({
18
+ jsonrpc: "2.0",
19
+ error: {
20
+ code: -32602,
21
+ message: "Invalid params: message is required"
22
+ },
23
+ id: requestBody.id
24
+ });
25
+ }
26
+ const taskId = params.message.taskId;
27
+ const session = await agent.createSession(taskId);
28
+ const stream = sseSubscriber.createStream(session.id);
29
+ const { text, image, file } = a2aToInternalMessage(params.message);
30
+ agent.run(text, image, file, session.id).catch((error) => {
31
+ logger.error(`Error in streaming task ${session.id}: ${error}`);
32
+ });
33
+ logger.info(`JSON-RPC SSE stream opened for task ${session.id}`);
34
+ return new Response(stream, {
35
+ headers: {
36
+ "Content-Type": "text/event-stream",
37
+ "Cache-Control": "no-cache",
38
+ Connection: "keep-alive",
39
+ "X-Accel-Buffering": "no"
40
+ }
41
+ });
42
+ }
43
+ const handlers = new A2AMethodHandlers(agent);
44
+ const rpcServer = new JsonRpcServer({
45
+ methods: handlers.getMethods(),
46
+ onError: (error, request) => {
47
+ logger.error(`JSON-RPC error for method ${request?.method}: ${error.message}`, {
48
+ error,
49
+ request
50
+ });
51
+ }
52
+ });
53
+ logger.debug(`A2A JSON-RPC request received`, {
54
+ method: Array.isArray(requestBody) ? `batch(${requestBody.length})` : requestBody.method
55
+ });
56
+ const response = await rpcServer.handle(requestBody);
57
+ return ctx.json(response);
58
+ } catch (error) {
59
+ logger.error(`Failed to process JSON-RPC request: ${error}`, { error });
60
+ return ctx.json({
61
+ jsonrpc: "2.0",
62
+ error: {
63
+ code: -32700,
64
+ message: "Parse error",
65
+ data: error instanceof Error ? error.message : String(error)
66
+ },
67
+ id: null
68
+ });
69
+ }
70
+ });
71
+ app.get("/jsonrpc", (ctx) => {
72
+ const agent = getAgent();
73
+ const handlers = new A2AMethodHandlers(agent);
74
+ return ctx.json({
75
+ service: "A2A JSON-RPC 2.0",
76
+ version: "0.3.0",
77
+ endpoint: "/jsonrpc",
78
+ methods: Object.keys(handlers.getMethods()),
79
+ usage: {
80
+ method: "POST",
81
+ contentType: "application/json",
82
+ example: {
83
+ jsonrpc: "2.0",
84
+ method: "agent.getInfo",
85
+ params: {},
86
+ id: 1
87
+ }
88
+ }
89
+ });
90
+ });
91
+ return app;
92
+ }
93
+ export {
94
+ createA2AJsonRpcRouter
95
+ };