@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,100 @@
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 manual_approval_handler_exports = {};
20
+ __export(manual_approval_handler_exports, {
21
+ createManualApprovalHandler: () => createManualApprovalHandler
22
+ });
23
+ module.exports = __toCommonJS(manual_approval_handler_exports);
24
+ var import_core = require("@dexto/core");
25
+ function createManualApprovalHandler(coordinator) {
26
+ const pendingApprovals = /* @__PURE__ */ new Map();
27
+ const handleApproval = (request) => {
28
+ return new Promise((resolve) => {
29
+ const effectiveTimeout = request.timeout;
30
+ const timer = setTimeout(() => {
31
+ cleanup();
32
+ pendingApprovals.delete(request.approvalId);
33
+ const timeoutResponse = {
34
+ approvalId: request.approvalId,
35
+ status: import_core.ApprovalStatus.CANCELLED,
36
+ sessionId: request.sessionId,
37
+ reason: import_core.DenialReason.TIMEOUT,
38
+ message: `Approval request timed out after ${effectiveTimeout}ms`,
39
+ timeoutMs: effectiveTimeout
40
+ };
41
+ coordinator.emitResponse(timeoutResponse);
42
+ resolve(timeoutResponse);
43
+ }, effectiveTimeout);
44
+ let cleanupListener = null;
45
+ const cleanup = () => {
46
+ clearTimeout(timer);
47
+ if (cleanupListener) {
48
+ cleanupListener();
49
+ cleanupListener = null;
50
+ }
51
+ };
52
+ const listener = (res) => {
53
+ if (res.approvalId === request.approvalId) {
54
+ cleanup();
55
+ pendingApprovals.delete(request.approvalId);
56
+ resolve(res);
57
+ }
58
+ };
59
+ coordinator.on("approval:response", listener);
60
+ cleanupListener = () => coordinator.off("approval:response", listener);
61
+ pendingApprovals.set(request.approvalId, {
62
+ cleanup,
63
+ resolve,
64
+ request
65
+ });
66
+ coordinator.emitRequest(request);
67
+ });
68
+ };
69
+ const handler = Object.assign(handleApproval, {
70
+ cancel: (approvalId) => {
71
+ const pending = pendingApprovals.get(approvalId);
72
+ if (pending) {
73
+ pending.cleanup();
74
+ pendingApprovals.delete(approvalId);
75
+ const cancelResponse = {
76
+ approvalId,
77
+ status: import_core.ApprovalStatus.CANCELLED,
78
+ sessionId: pending.request.sessionId,
79
+ reason: import_core.DenialReason.SYSTEM_CANCELLED,
80
+ message: "Approval request was cancelled"
81
+ };
82
+ coordinator.emitResponse(cancelResponse);
83
+ pending.resolve(cancelResponse);
84
+ }
85
+ },
86
+ cancelAll: () => {
87
+ for (const [approvalId] of pendingApprovals) {
88
+ handler.cancel?.(approvalId);
89
+ }
90
+ },
91
+ getPending: () => {
92
+ return Array.from(pendingApprovals.keys());
93
+ }
94
+ });
95
+ return handler;
96
+ }
97
+ // Annotate the CommonJS export names for ESM import in node:
98
+ 0 && (module.exports = {
99
+ createManualApprovalHandler
100
+ });
@@ -0,0 +1,32 @@
1
+ import type { ApprovalHandler } from '@dexto/core';
2
+ import type { ApprovalCoordinator } from './approval-coordinator.js';
3
+ /**
4
+ * Creates a manual approval handler that uses ApprovalCoordinator for server communication.
5
+ *
6
+ * This handler emits `approval:request` and waits for `approval:response` via the coordinator,
7
+ * enabling SSE-based approval flows where:
8
+ * 1. Handler emits approval:request → Coordinator → SSE endpoint forwards to client
9
+ * 2. Client sends decision via POST /api/approvals/{approvalId}
10
+ * 3. API route emits approval:response → Coordinator → Handler resolves
11
+ *
12
+ * The returned handler implements the optional cancellation methods (cancel, cancelAll, getPending)
13
+ * for managing pending approval requests.
14
+ *
15
+ * Timeouts are handled per-request using the timeout value from ApprovalRequest, which
16
+ * is set by ApprovalManager based on the request type (tool confirmation vs elicitation).
17
+ *
18
+ * @param coordinator The approval coordinator for request/response communication
19
+ * @returns ApprovalHandler with cancellation support
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const coordinator = new ApprovalCoordinator();
24
+ * const handler = createManualApprovalHandler(coordinator);
25
+ * agent.setApprovalHandler(handler);
26
+ *
27
+ * // Later, cancel a specific approval (if handler supports it)
28
+ * handler.cancel?.('approval-id-123');
29
+ * ```
30
+ */
31
+ export declare function createManualApprovalHandler(coordinator: ApprovalCoordinator): ApprovalHandler;
32
+ //# sourceMappingURL=manual-approval-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manual-approval-handler.d.ts","sourceRoot":"","sources":["../../src/approval/manual-approval-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAqC,MAAM,aAAa,CAAC;AAEtF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,mBAAmB,GAAG,eAAe,CAiH7F"}
@@ -0,0 +1,76 @@
1
+ import { ApprovalStatus, DenialReason } from "@dexto/core";
2
+ function createManualApprovalHandler(coordinator) {
3
+ const pendingApprovals = /* @__PURE__ */ new Map();
4
+ const handleApproval = (request) => {
5
+ return new Promise((resolve) => {
6
+ const effectiveTimeout = request.timeout;
7
+ const timer = setTimeout(() => {
8
+ cleanup();
9
+ pendingApprovals.delete(request.approvalId);
10
+ const timeoutResponse = {
11
+ approvalId: request.approvalId,
12
+ status: ApprovalStatus.CANCELLED,
13
+ sessionId: request.sessionId,
14
+ reason: DenialReason.TIMEOUT,
15
+ message: `Approval request timed out after ${effectiveTimeout}ms`,
16
+ timeoutMs: effectiveTimeout
17
+ };
18
+ coordinator.emitResponse(timeoutResponse);
19
+ resolve(timeoutResponse);
20
+ }, effectiveTimeout);
21
+ let cleanupListener = null;
22
+ const cleanup = () => {
23
+ clearTimeout(timer);
24
+ if (cleanupListener) {
25
+ cleanupListener();
26
+ cleanupListener = null;
27
+ }
28
+ };
29
+ const listener = (res) => {
30
+ if (res.approvalId === request.approvalId) {
31
+ cleanup();
32
+ pendingApprovals.delete(request.approvalId);
33
+ resolve(res);
34
+ }
35
+ };
36
+ coordinator.on("approval:response", listener);
37
+ cleanupListener = () => coordinator.off("approval:response", listener);
38
+ pendingApprovals.set(request.approvalId, {
39
+ cleanup,
40
+ resolve,
41
+ request
42
+ });
43
+ coordinator.emitRequest(request);
44
+ });
45
+ };
46
+ const handler = Object.assign(handleApproval, {
47
+ cancel: (approvalId) => {
48
+ const pending = pendingApprovals.get(approvalId);
49
+ if (pending) {
50
+ pending.cleanup();
51
+ pendingApprovals.delete(approvalId);
52
+ const cancelResponse = {
53
+ approvalId,
54
+ status: ApprovalStatus.CANCELLED,
55
+ sessionId: pending.request.sessionId,
56
+ reason: DenialReason.SYSTEM_CANCELLED,
57
+ message: "Approval request was cancelled"
58
+ };
59
+ coordinator.emitResponse(cancelResponse);
60
+ pending.resolve(cancelResponse);
61
+ }
62
+ },
63
+ cancelAll: () => {
64
+ for (const [approvalId] of pendingApprovals) {
65
+ handler.cancel?.(approvalId);
66
+ }
67
+ },
68
+ getPending: () => {
69
+ return Array.from(pendingApprovals.keys());
70
+ }
71
+ });
72
+ return handler;
73
+ }
74
+ export {
75
+ createManualApprovalHandler
76
+ };
@@ -0,0 +1,271 @@
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_sse_subscriber_exports = {};
20
+ __export(a2a_sse_subscriber_exports, {
21
+ A2ASseEventSubscriber: () => A2ASseEventSubscriber
22
+ });
23
+ module.exports = __toCommonJS(a2a_sse_subscriber_exports);
24
+ var import_events = require("events");
25
+ var import_core2 = require("@dexto/core");
26
+ class A2ASseEventSubscriber {
27
+ connections = /* @__PURE__ */ new Map();
28
+ eventBus;
29
+ globalAbortController;
30
+ /**
31
+ * Subscribe to agent event bus.
32
+ * Sets up global event listeners that broadcast to all SSE connections.
33
+ *
34
+ * @param eventBus Agent event bus to subscribe to
35
+ */
36
+ subscribe(eventBus) {
37
+ this.globalAbortController?.abort();
38
+ this.globalAbortController = new AbortController();
39
+ const { signal } = this.globalAbortController;
40
+ const MAX_SHARED_SIGNAL_LISTENERS = 20;
41
+ (0, import_events.setMaxListeners)(MAX_SHARED_SIGNAL_LISTENERS, signal);
42
+ this.eventBus = eventBus;
43
+ eventBus.on(
44
+ "llm:thinking",
45
+ (payload) => {
46
+ this.broadcastToTask(payload.sessionId, "task.thinking", {
47
+ taskId: payload.sessionId
48
+ });
49
+ },
50
+ { signal }
51
+ );
52
+ eventBus.on(
53
+ "llm:chunk",
54
+ (payload) => {
55
+ this.broadcastToTask(payload.sessionId, "task.chunk", {
56
+ taskId: payload.sessionId,
57
+ type: payload.chunkType,
58
+ content: payload.content,
59
+ isComplete: payload.isComplete
60
+ });
61
+ },
62
+ { signal }
63
+ );
64
+ eventBus.on(
65
+ "llm:tool-call",
66
+ (payload) => {
67
+ this.broadcastToTask(payload.sessionId, "task.toolCall", {
68
+ taskId: payload.sessionId,
69
+ toolName: payload.toolName,
70
+ args: payload.args,
71
+ callId: payload.callId
72
+ });
73
+ },
74
+ { signal }
75
+ );
76
+ eventBus.on(
77
+ "llm:tool-result",
78
+ (payload) => {
79
+ const data = {
80
+ taskId: payload.sessionId,
81
+ toolName: payload.toolName,
82
+ callId: payload.callId,
83
+ success: payload.success,
84
+ sanitized: payload.sanitized
85
+ };
86
+ if (payload.rawResult !== void 0) {
87
+ data.rawResult = payload.rawResult;
88
+ }
89
+ this.broadcastToTask(payload.sessionId, "task.toolResult", data);
90
+ },
91
+ { signal }
92
+ );
93
+ eventBus.on(
94
+ "llm:response",
95
+ (payload) => {
96
+ this.broadcastToTask(payload.sessionId, "task.message", {
97
+ taskId: payload.sessionId,
98
+ message: {
99
+ role: "agent",
100
+ content: [{ type: "text", text: payload.content }],
101
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
102
+ },
103
+ tokenUsage: payload.tokenUsage,
104
+ provider: payload.provider,
105
+ model: payload.model
106
+ });
107
+ },
108
+ { signal }
109
+ );
110
+ eventBus.on(
111
+ "llm:error",
112
+ (payload) => {
113
+ this.broadcastToTask(payload.sessionId, "task.error", {
114
+ taskId: payload.sessionId,
115
+ error: {
116
+ message: payload.error.message,
117
+ recoverable: payload.recoverable
118
+ }
119
+ });
120
+ },
121
+ { signal }
122
+ );
123
+ eventBus.on(
124
+ "session:reset",
125
+ (payload) => {
126
+ this.broadcastToTask(payload.sessionId, "task.reset", {
127
+ taskId: payload.sessionId
128
+ });
129
+ },
130
+ { signal }
131
+ );
132
+ import_core2.logger.debug("A2ASseEventSubscriber subscribed to agent events");
133
+ }
134
+ /**
135
+ * Create a new SSE stream for a specific task.
136
+ *
137
+ * Returns a ReadableStream that emits SSE events for the task.
138
+ *
139
+ * @param taskId Task/Session ID to stream events for
140
+ * @returns ReadableStream for SSE connection
141
+ */
142
+ createStream(taskId) {
143
+ const connectionId = `${taskId}-${Date.now()}`;
144
+ return new ReadableStream({
145
+ start: (controller) => {
146
+ const connection = {
147
+ taskId,
148
+ controller,
149
+ abortController: new AbortController(),
150
+ connectedAt: Date.now()
151
+ };
152
+ this.connections.set(connectionId, connection);
153
+ import_core2.logger.debug(`SSE connection opened for task ${taskId}`);
154
+ this.sendSSEEvent(controller, "connected", {
155
+ taskId,
156
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
157
+ });
158
+ const keepaliveInterval = setInterval(() => {
159
+ try {
160
+ this.sendSSEComment(controller, "keepalive");
161
+ } catch (_error) {
162
+ clearInterval(keepaliveInterval);
163
+ }
164
+ }, 3e4);
165
+ connection.abortController.signal.addEventListener("abort", () => {
166
+ clearInterval(keepaliveInterval);
167
+ });
168
+ },
169
+ cancel: () => {
170
+ const connection = this.connections.get(connectionId);
171
+ if (connection) {
172
+ connection.abortController.abort();
173
+ this.connections.delete(connectionId);
174
+ import_core2.logger.debug(`SSE connection closed for task ${taskId}`);
175
+ }
176
+ }
177
+ });
178
+ }
179
+ /**
180
+ * Broadcast an event to a specific task's SSE connections.
181
+ *
182
+ * @param taskId Task ID to broadcast to
183
+ * @param eventName SSE event name
184
+ * @param data Event data
185
+ */
186
+ broadcastToTask(taskId, eventName, data) {
187
+ let sent = 0;
188
+ for (const [connectionId, connection] of this.connections.entries()) {
189
+ if (connection.taskId === taskId) {
190
+ try {
191
+ this.sendSSEEvent(connection.controller, eventName, data);
192
+ sent++;
193
+ } catch (error) {
194
+ const errorMessage = error instanceof Error ? error.message : String(error);
195
+ import_core2.logger.warn(`Failed to send SSE event to ${connectionId}: ${errorMessage}`);
196
+ connection.abortController.abort();
197
+ this.connections.delete(connectionId);
198
+ }
199
+ }
200
+ }
201
+ if (sent > 0) {
202
+ import_core2.logger.debug(`Broadcast ${eventName} to ${sent} SSE connection(s) for task ${taskId}`);
203
+ }
204
+ }
205
+ /**
206
+ * Send an SSE event to a specific controller.
207
+ *
208
+ * Format: event: name\ndata: json\n\n
209
+ *
210
+ * @param controller Stream controller
211
+ * @param eventName Event name
212
+ * @param data Event data
213
+ */
214
+ sendSSEEvent(controller, eventName, data) {
215
+ const event = `event: ${eventName}
216
+ data: ${JSON.stringify(data)}
217
+
218
+ `;
219
+ controller.enqueue(new TextEncoder().encode(event));
220
+ }
221
+ /**
222
+ * Send an SSE comment (for keepalive).
223
+ *
224
+ * Format: : comment\n
225
+ *
226
+ * @param controller Stream controller
227
+ * @param comment Comment text
228
+ */
229
+ sendSSEComment(controller, comment) {
230
+ const line = `: ${comment}
231
+ `;
232
+ controller.enqueue(new TextEncoder().encode(line));
233
+ }
234
+ /**
235
+ * Close all connections and cleanup.
236
+ */
237
+ cleanup() {
238
+ import_core2.logger.debug(`Cleaning up ${this.connections.size} SSE connections`);
239
+ for (const [_connectionId, connection] of this.connections.entries()) {
240
+ connection.abortController.abort();
241
+ try {
242
+ connection.controller.close();
243
+ } catch (_error) {
244
+ }
245
+ }
246
+ this.connections.clear();
247
+ this.globalAbortController?.abort();
248
+ }
249
+ /**
250
+ * Get active connection count.
251
+ */
252
+ getConnectionCount() {
253
+ return this.connections.size;
254
+ }
255
+ /**
256
+ * Get connection count for a specific task.
257
+ */
258
+ getTaskConnectionCount(taskId) {
259
+ let count = 0;
260
+ for (const connection of this.connections.values()) {
261
+ if (connection.taskId === taskId) {
262
+ count++;
263
+ }
264
+ }
265
+ return count;
266
+ }
267
+ }
268
+ // Annotate the CommonJS export names for ESM import in node:
269
+ 0 && (module.exports = {
270
+ A2ASseEventSubscriber
271
+ });
@@ -0,0 +1,94 @@
1
+ /**
2
+ * A2A SSE (Server-Sent Events) Event Subscriber
3
+ *
4
+ * Subscribes to agent events and streams them to SSE clients for A2A tasks.
5
+ * Uses standard SSE protocol (text/event-stream).
6
+ *
7
+ * Design:
8
+ * - Filters events by taskId/sessionId for targeted streaming
9
+ * - Uses standard SSE format: event: name\ndata: json\n\n
10
+ * - Supports multiple concurrent SSE connections
11
+ */
12
+ import { AgentEventBus } from '@dexto/core';
13
+ /**
14
+ * A2A SSE Event Subscriber
15
+ *
16
+ * Manages Server-Sent Events connections for A2A Protocol task streaming.
17
+ *
18
+ * Usage:
19
+ * ```typescript
20
+ * const sseSubscriber = new A2ASseEventSubscriber();
21
+ * sseSubscriber.subscribe(agent.agentEventBus);
22
+ *
23
+ * // In route handler
24
+ * const stream = sseSubscriber.createStream(taskId);
25
+ * return new Response(stream, {
26
+ * headers: {
27
+ * 'Content-Type': 'text/event-stream',
28
+ * 'Cache-Control': 'no-cache',
29
+ * 'Connection': 'keep-alive'
30
+ * }
31
+ * });
32
+ * ```
33
+ */
34
+ export declare class A2ASseEventSubscriber {
35
+ private connections;
36
+ private eventBus?;
37
+ private globalAbortController?;
38
+ /**
39
+ * Subscribe to agent event bus.
40
+ * Sets up global event listeners that broadcast to all SSE connections.
41
+ *
42
+ * @param eventBus Agent event bus to subscribe to
43
+ */
44
+ subscribe(eventBus: AgentEventBus): void;
45
+ /**
46
+ * Create a new SSE stream for a specific task.
47
+ *
48
+ * Returns a ReadableStream that emits SSE events for the task.
49
+ *
50
+ * @param taskId Task/Session ID to stream events for
51
+ * @returns ReadableStream for SSE connection
52
+ */
53
+ createStream(taskId: string): ReadableStream<Uint8Array>;
54
+ /**
55
+ * Broadcast an event to a specific task's SSE connections.
56
+ *
57
+ * @param taskId Task ID to broadcast to
58
+ * @param eventName SSE event name
59
+ * @param data Event data
60
+ */
61
+ private broadcastToTask;
62
+ /**
63
+ * Send an SSE event to a specific controller.
64
+ *
65
+ * Format: event: name\ndata: json\n\n
66
+ *
67
+ * @param controller Stream controller
68
+ * @param eventName Event name
69
+ * @param data Event data
70
+ */
71
+ private sendSSEEvent;
72
+ /**
73
+ * Send an SSE comment (for keepalive).
74
+ *
75
+ * Format: : comment\n
76
+ *
77
+ * @param controller Stream controller
78
+ * @param comment Comment text
79
+ */
80
+ private sendSSEComment;
81
+ /**
82
+ * Close all connections and cleanup.
83
+ */
84
+ cleanup(): void;
85
+ /**
86
+ * Get active connection count.
87
+ */
88
+ getConnectionCount(): number;
89
+ /**
90
+ * Get connection count for a specific task.
91
+ */
92
+ getTaskConnectionCount(taskId: string): number;
93
+ }
94
+ //# sourceMappingURL=a2a-sse-subscriber.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"a2a-sse-subscriber.d.ts","sourceRoot":"","sources":["../../src/events/a2a-sse-subscriber.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiB5C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,WAAW,CAAyC;IAC5D,OAAO,CAAC,QAAQ,CAAC,CAAgB;IACjC,OAAO,CAAC,qBAAqB,CAAC,CAAkB;IAEhD;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAkHxC;;;;;;;OAOG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC;IAiDxD;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IA0BvB;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;IASpB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAKtB;;OAEG;IACH,OAAO,IAAI,IAAI;IAgBf;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;OAEG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CASjD"}