@animalabs/agent-framework 0.1.0

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 (212) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +233 -0
  3. package/dist/src/agent.d.ts +130 -0
  4. package/dist/src/agent.d.ts.map +1 -0
  5. package/dist/src/agent.js +406 -0
  6. package/dist/src/agent.js.map +1 -0
  7. package/dist/src/api/mcp-server.d.ts +37 -0
  8. package/dist/src/api/mcp-server.d.ts.map +1 -0
  9. package/dist/src/api/mcp-server.js +598 -0
  10. package/dist/src/api/mcp-server.js.map +1 -0
  11. package/dist/src/api/server.d.ts +83 -0
  12. package/dist/src/api/server.d.ts.map +1 -0
  13. package/dist/src/api/server.js +785 -0
  14. package/dist/src/api/server.js.map +1 -0
  15. package/dist/src/api/types.d.ts +395 -0
  16. package/dist/src/api/types.d.ts.map +1 -0
  17. package/dist/src/api/types.js +5 -0
  18. package/dist/src/api/types.js.map +1 -0
  19. package/dist/src/framework.d.ts +309 -0
  20. package/dist/src/framework.d.ts.map +1 -0
  21. package/dist/src/framework.js +2309 -0
  22. package/dist/src/framework.js.map +1 -0
  23. package/dist/src/gate/event-gate.d.ts +75 -0
  24. package/dist/src/gate/event-gate.d.ts.map +1 -0
  25. package/dist/src/gate/event-gate.js +503 -0
  26. package/dist/src/gate/event-gate.js.map +1 -0
  27. package/dist/src/gate/index.d.ts +3 -0
  28. package/dist/src/gate/index.d.ts.map +1 -0
  29. package/dist/src/gate/index.js +2 -0
  30. package/dist/src/gate/index.js.map +1 -0
  31. package/dist/src/gate/types.d.ts +82 -0
  32. package/dist/src/gate/types.d.ts.map +1 -0
  33. package/dist/src/gate/types.js +9 -0
  34. package/dist/src/gate/types.js.map +1 -0
  35. package/dist/src/index.d.ts +17 -0
  36. package/dist/src/index.d.ts.map +1 -0
  37. package/dist/src/index.js +18 -0
  38. package/dist/src/index.js.map +1 -0
  39. package/dist/src/mcpl/channel-registry.d.ts +141 -0
  40. package/dist/src/mcpl/channel-registry.d.ts.map +1 -0
  41. package/dist/src/mcpl/channel-registry.js +647 -0
  42. package/dist/src/mcpl/channel-registry.js.map +1 -0
  43. package/dist/src/mcpl/checkpoint-manager.d.ts +79 -0
  44. package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -0
  45. package/dist/src/mcpl/checkpoint-manager.js +430 -0
  46. package/dist/src/mcpl/checkpoint-manager.js.map +1 -0
  47. package/dist/src/mcpl/errors.d.ts +52 -0
  48. package/dist/src/mcpl/errors.d.ts.map +1 -0
  49. package/dist/src/mcpl/errors.js +93 -0
  50. package/dist/src/mcpl/errors.js.map +1 -0
  51. package/dist/src/mcpl/feature-set-manager.d.ts +91 -0
  52. package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -0
  53. package/dist/src/mcpl/feature-set-manager.js +250 -0
  54. package/dist/src/mcpl/feature-set-manager.js.map +1 -0
  55. package/dist/src/mcpl/hook-orchestrator.d.ts +51 -0
  56. package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -0
  57. package/dist/src/mcpl/hook-orchestrator.js +217 -0
  58. package/dist/src/mcpl/hook-orchestrator.js.map +1 -0
  59. package/dist/src/mcpl/index.d.ts +14 -0
  60. package/dist/src/mcpl/index.d.ts.map +1 -0
  61. package/dist/src/mcpl/index.js +21 -0
  62. package/dist/src/mcpl/index.js.map +1 -0
  63. package/dist/src/mcpl/inference-router.d.ts +67 -0
  64. package/dist/src/mcpl/inference-router.d.ts.map +1 -0
  65. package/dist/src/mcpl/inference-router.js +249 -0
  66. package/dist/src/mcpl/inference-router.js.map +1 -0
  67. package/dist/src/mcpl/push-handler.d.ts +60 -0
  68. package/dist/src/mcpl/push-handler.d.ts.map +1 -0
  69. package/dist/src/mcpl/push-handler.js +162 -0
  70. package/dist/src/mcpl/push-handler.js.map +1 -0
  71. package/dist/src/mcpl/scope-manager.d.ts +76 -0
  72. package/dist/src/mcpl/scope-manager.d.ts.map +1 -0
  73. package/dist/src/mcpl/scope-manager.js +213 -0
  74. package/dist/src/mcpl/scope-manager.js.map +1 -0
  75. package/dist/src/mcpl/server-connection.d.ts +174 -0
  76. package/dist/src/mcpl/server-connection.d.ts.map +1 -0
  77. package/dist/src/mcpl/server-connection.js +559 -0
  78. package/dist/src/mcpl/server-connection.js.map +1 -0
  79. package/dist/src/mcpl/server-registry.d.ts +63 -0
  80. package/dist/src/mcpl/server-registry.d.ts.map +1 -0
  81. package/dist/src/mcpl/server-registry.js +119 -0
  82. package/dist/src/mcpl/server-registry.js.map +1 -0
  83. package/dist/src/mcpl/types.d.ts +755 -0
  84. package/dist/src/mcpl/types.d.ts.map +1 -0
  85. package/dist/src/mcpl/types.js +48 -0
  86. package/dist/src/mcpl/types.js.map +1 -0
  87. package/dist/src/module-registry.d.ts +93 -0
  88. package/dist/src/module-registry.d.ts.map +1 -0
  89. package/dist/src/module-registry.js +386 -0
  90. package/dist/src/module-registry.js.map +1 -0
  91. package/dist/src/modules/api/index.d.ts +22 -0
  92. package/dist/src/modules/api/index.d.ts.map +1 -0
  93. package/dist/src/modules/api/index.js +63 -0
  94. package/dist/src/modules/api/index.js.map +1 -0
  95. package/dist/src/modules/discord/discord-js-client.d.ts +58 -0
  96. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -0
  97. package/dist/src/modules/discord/discord-js-client.js +273 -0
  98. package/dist/src/modules/discord/discord-js-client.js.map +1 -0
  99. package/dist/src/modules/discord/index.d.ts +82 -0
  100. package/dist/src/modules/discord/index.d.ts.map +1 -0
  101. package/dist/src/modules/discord/index.js +959 -0
  102. package/dist/src/modules/discord/index.js.map +1 -0
  103. package/dist/src/modules/discord/types.d.ts +327 -0
  104. package/dist/src/modules/discord/types.d.ts.map +1 -0
  105. package/dist/src/modules/discord/types.js +5 -0
  106. package/dist/src/modules/discord/types.js.map +1 -0
  107. package/dist/src/modules/index.d.ts +11 -0
  108. package/dist/src/modules/index.d.ts.map +1 -0
  109. package/dist/src/modules/index.js +7 -0
  110. package/dist/src/modules/index.js.map +1 -0
  111. package/dist/src/modules/workspace/index.d.ts +59 -0
  112. package/dist/src/modules/workspace/index.d.ts.map +1 -0
  113. package/dist/src/modules/workspace/index.js +831 -0
  114. package/dist/src/modules/workspace/index.js.map +1 -0
  115. package/dist/src/modules/workspace/sync.d.ts +48 -0
  116. package/dist/src/modules/workspace/sync.d.ts.map +1 -0
  117. package/dist/src/modules/workspace/sync.js +253 -0
  118. package/dist/src/modules/workspace/sync.js.map +1 -0
  119. package/dist/src/modules/workspace/types.d.ts +166 -0
  120. package/dist/src/modules/workspace/types.d.ts.map +1 -0
  121. package/dist/src/modules/workspace/types.js +5 -0
  122. package/dist/src/modules/workspace/types.js.map +1 -0
  123. package/dist/src/modules/workspace/watcher.d.ts +43 -0
  124. package/dist/src/modules/workspace/watcher.d.ts.map +1 -0
  125. package/dist/src/modules/workspace/watcher.js +120 -0
  126. package/dist/src/modules/workspace/watcher.js.map +1 -0
  127. package/dist/src/queue.d.ts +50 -0
  128. package/dist/src/queue.d.ts.map +1 -0
  129. package/dist/src/queue.js +95 -0
  130. package/dist/src/queue.js.map +1 -0
  131. package/dist/src/safe-slice.d.ts +8 -0
  132. package/dist/src/safe-slice.d.ts.map +1 -0
  133. package/dist/src/safe-slice.js +18 -0
  134. package/dist/src/safe-slice.js.map +1 -0
  135. package/dist/src/types/agent.d.ts +118 -0
  136. package/dist/src/types/agent.d.ts.map +1 -0
  137. package/dist/src/types/agent.js +2 -0
  138. package/dist/src/types/agent.js.map +1 -0
  139. package/dist/src/types/events.d.ts +220 -0
  140. package/dist/src/types/events.d.ts.map +1 -0
  141. package/dist/src/types/events.js +2 -0
  142. package/dist/src/types/events.js.map +1 -0
  143. package/dist/src/types/framework.d.ts +184 -0
  144. package/dist/src/types/framework.d.ts.map +1 -0
  145. package/dist/src/types/framework.js +2 -0
  146. package/dist/src/types/framework.js.map +1 -0
  147. package/dist/src/types/index.d.ts +7 -0
  148. package/dist/src/types/index.d.ts.map +1 -0
  149. package/dist/src/types/index.js +7 -0
  150. package/dist/src/types/index.js.map +1 -0
  151. package/dist/src/types/inference-log.d.ts +64 -0
  152. package/dist/src/types/inference-log.d.ts.map +1 -0
  153. package/dist/src/types/inference-log.js +5 -0
  154. package/dist/src/types/inference-log.js.map +1 -0
  155. package/dist/src/types/module.d.ts +302 -0
  156. package/dist/src/types/module.d.ts.map +1 -0
  157. package/dist/src/types/module.js +2 -0
  158. package/dist/src/types/module.js.map +1 -0
  159. package/dist/src/types/trace.d.ts +173 -0
  160. package/dist/src/types/trace.d.ts.map +1 -0
  161. package/dist/src/types/trace.js +2 -0
  162. package/dist/src/types/trace.js.map +1 -0
  163. package/dist/test/event-gate.test.d.ts +2 -0
  164. package/dist/test/event-gate.test.d.ts.map +1 -0
  165. package/dist/test/event-gate.test.js +535 -0
  166. package/dist/test/event-gate.test.js.map +1 -0
  167. package/dist/test/framework.test.d.ts +5 -0
  168. package/dist/test/framework.test.d.ts.map +1 -0
  169. package/dist/test/framework.test.js +738 -0
  170. package/dist/test/framework.test.js.map +1 -0
  171. package/dist/tsconfig.tsbuildinfo +1 -0
  172. package/package.json +58 -0
  173. package/src/agent.ts +512 -0
  174. package/src/api/mcp-server.ts +687 -0
  175. package/src/api/server.ts +1023 -0
  176. package/src/api/types.ts +542 -0
  177. package/src/framework.ts +2784 -0
  178. package/src/gate/event-gate.ts +623 -0
  179. package/src/gate/index.ts +12 -0
  180. package/src/gate/types.ts +112 -0
  181. package/src/index.ts +63 -0
  182. package/src/mcpl/channel-registry.ts +824 -0
  183. package/src/mcpl/checkpoint-manager.ts +545 -0
  184. package/src/mcpl/errors.ts +114 -0
  185. package/src/mcpl/feature-set-manager.ts +333 -0
  186. package/src/mcpl/hook-orchestrator.ts +281 -0
  187. package/src/mcpl/index.ts +134 -0
  188. package/src/mcpl/inference-router.ts +335 -0
  189. package/src/mcpl/push-handler.ts +232 -0
  190. package/src/mcpl/scope-manager.ts +262 -0
  191. package/src/mcpl/server-connection.ts +694 -0
  192. package/src/mcpl/server-registry.ts +144 -0
  193. package/src/mcpl/types.ts +991 -0
  194. package/src/module-registry.ts +547 -0
  195. package/src/modules/api/index.ts +94 -0
  196. package/src/modules/discord/discord-js-client.ts +353 -0
  197. package/src/modules/discord/index.ts +1146 -0
  198. package/src/modules/discord/types.ts +465 -0
  199. package/src/modules/index.ts +43 -0
  200. package/src/modules/workspace/index.ts +969 -0
  201. package/src/modules/workspace/sync.ts +314 -0
  202. package/src/modules/workspace/types.ts +202 -0
  203. package/src/modules/workspace/watcher.ts +142 -0
  204. package/src/queue.ts +106 -0
  205. package/src/safe-slice.ts +18 -0
  206. package/src/types/agent.ts +119 -0
  207. package/src/types/events.ts +252 -0
  208. package/src/types/framework.ts +211 -0
  209. package/src/types/index.ts +6 -0
  210. package/src/types/inference-log.ts +64 -0
  211. package/src/types/module.ts +367 -0
  212. package/src/types/trace.ts +196 -0
@@ -0,0 +1,647 @@
1
+ /**
2
+ * ChannelRegistry — manages MCPL channel lifecycle, incoming messages, and
3
+ * synthesized channel tools.
4
+ *
5
+ * Adapted from battle-tested patterns in Anarchid/agent-framework@mcpl-module-proto.
6
+ *
7
+ * Responsibilities:
8
+ * - Register/unregister channel descriptors from MCPL servers
9
+ * - Auto-open channels on registration
10
+ * - Route incoming messages to the processing queue
11
+ * - Manage typing indicator timers (7s interval for Discord compatibility)
12
+ * - Expose synthesized tools: channel_list, channel_open, channel_close, channel_publish
13
+ * - Build channel context for beforeInference params
14
+ */
15
+ // ============================================================================
16
+ // Typing indicator interval (Discord typing lasts ~10s, so 7s keeps it alive)
17
+ // ============================================================================
18
+ const TYPING_INTERVAL_MS = 7_000;
19
+ // ============================================================================
20
+ // Content Conversion: McplContentBlock → membrane ContentBlock
21
+ // ============================================================================
22
+ /**
23
+ * Convert a single MCPL wire-format content block to a membrane ContentBlock.
24
+ */
25
+ function convertBlock(block) {
26
+ switch (block.type) {
27
+ case 'text':
28
+ return { type: 'text', text: block.text };
29
+ case 'image':
30
+ if (block.data && block.mimeType) {
31
+ return {
32
+ type: 'image',
33
+ source: { type: 'base64', data: block.data, mediaType: block.mimeType },
34
+ };
35
+ }
36
+ if (block.uri) {
37
+ return {
38
+ type: 'image',
39
+ source: { type: 'url', url: block.uri },
40
+ };
41
+ }
42
+ return { type: 'text', text: '[Image: no data]' };
43
+ case 'audio':
44
+ if (block.data && block.mimeType) {
45
+ return {
46
+ type: 'audio',
47
+ source: { type: 'base64', data: block.data, mediaType: block.mimeType },
48
+ };
49
+ }
50
+ return { type: 'text', text: '[Audio: no data]' };
51
+ case 'resource':
52
+ return { type: 'text', text: `[Resource: ${block.uri}]` };
53
+ }
54
+ }
55
+ // ============================================================================
56
+ // Channel Tool Definitions
57
+ // ============================================================================
58
+ const CHANNEL_TOOL_DEFINITIONS = [
59
+ {
60
+ name: 'channel_list',
61
+ description: 'List all available channels',
62
+ inputSchema: { type: 'object', properties: {} },
63
+ },
64
+ {
65
+ name: 'channel_open',
66
+ description: 'Open a channel to start receiving messages',
67
+ inputSchema: {
68
+ type: 'object',
69
+ properties: {
70
+ channelId: { type: 'string', description: 'ID of the channel to open' },
71
+ },
72
+ required: ['channelId'],
73
+ },
74
+ },
75
+ {
76
+ name: 'channel_close',
77
+ description: 'Close a channel to stop receiving messages',
78
+ inputSchema: {
79
+ type: 'object',
80
+ properties: {
81
+ channelId: { type: 'string', description: 'ID of the channel to close' },
82
+ },
83
+ required: ['channelId'],
84
+ },
85
+ },
86
+ {
87
+ name: 'channel_publish',
88
+ description: 'Publish a message to a channel. If channelId is omitted, publishes to the most recent incoming channel.',
89
+ inputSchema: {
90
+ type: 'object',
91
+ properties: {
92
+ channelId: { type: 'string', description: 'ID of the channel to publish to (defaults to the most recent incoming channel)' },
93
+ content: { type: 'string', description: 'Text content to publish' },
94
+ text: { type: 'string', description: 'Alias for content' },
95
+ },
96
+ required: [],
97
+ },
98
+ },
99
+ ];
100
+ // ============================================================================
101
+ // ChannelRegistry
102
+ // ============================================================================
103
+ export class ChannelRegistry {
104
+ serverRegistry;
105
+ featureSetManager;
106
+ pushEventFn;
107
+ emitTraceFn;
108
+ sendTypingFn;
109
+ shouldTriggerInference;
110
+ /** Registered channels, keyed by `{serverId}:{channelId}`. */
111
+ channels = new Map();
112
+ /** Most recent incoming channel ID — used for speech routing / default publish. */
113
+ defaultPublishChannel = null;
114
+ /** Most recent incoming message metadata, used for buildChannelContext. */
115
+ defaultPublishMessageId = null;
116
+ defaultPublishThreadId = undefined;
117
+ /** Per-channel typing indicator timers. */
118
+ typingIntervals = new Map();
119
+ constructor(serverRegistry, featureSetManager, pushEventFn, emitTraceFn, options) {
120
+ this.serverRegistry = serverRegistry;
121
+ this.featureSetManager = featureSetManager;
122
+ this.pushEventFn = pushEventFn;
123
+ this.emitTraceFn = emitTraceFn;
124
+ this.sendTypingFn = options?.sendTypingFn;
125
+ this.shouldTriggerInference = options?.shouldTriggerInference;
126
+ }
127
+ // ==========================================================================
128
+ // Handler Methods (called from framework.ts wireMcplEvents)
129
+ // ==========================================================================
130
+ /**
131
+ * Handle `channels/register` from a server.
132
+ *
133
+ * Registers each channel descriptor in the map and auto-opens them.
134
+ */
135
+ async handleRegister(serverId, params, responder) {
136
+ const registeredIds = [];
137
+ for (const channel of params.channels) {
138
+ const key = `${serverId}:${channel.id}`;
139
+ this.channels.set(key, {
140
+ serverId,
141
+ descriptor: channel,
142
+ open: false,
143
+ });
144
+ registeredIds.push(channel.id);
145
+ }
146
+ // Respond before auto-opening — the server blocks on this response and
147
+ // can't process channels/open until it arrives.
148
+ const result = { registered: registeredIds };
149
+ responder?.respond(result);
150
+ // Auto-open all registered channels
151
+ await this.autoOpenChannels(serverId, params.channels);
152
+ this.emitTraceFn({
153
+ type: 'mcpl:channels-register',
154
+ serverId,
155
+ channelIds: registeredIds,
156
+ count: registeredIds.length,
157
+ });
158
+ }
159
+ /**
160
+ * Handle `channels/changed` notification from a server.
161
+ *
162
+ * Processes added (register + auto-open), removed (delete + stop typing),
163
+ * and updated (replace descriptor) channels.
164
+ */
165
+ async handleChanged(serverId, params) {
166
+ // Process removed channels
167
+ if (params.removed) {
168
+ for (const channelId of params.removed) {
169
+ const key = `${serverId}:${channelId}`;
170
+ this.channels.delete(key);
171
+ this.stopTyping(channelId);
172
+ }
173
+ }
174
+ // Process updated channels (replace descriptor, preserve open state)
175
+ if (params.updated) {
176
+ for (const channel of params.updated) {
177
+ const key = `${serverId}:${channel.id}`;
178
+ const existing = this.channels.get(key);
179
+ if (existing) {
180
+ existing.descriptor = channel;
181
+ }
182
+ }
183
+ }
184
+ // Process added channels (register + auto-open)
185
+ if (params.added) {
186
+ for (const channel of params.added) {
187
+ const key = `${serverId}:${channel.id}`;
188
+ this.channels.set(key, {
189
+ serverId,
190
+ descriptor: channel,
191
+ open: false,
192
+ });
193
+ }
194
+ await this.autoOpenChannels(serverId, params.added);
195
+ }
196
+ this.emitTraceFn({
197
+ type: 'mcpl:channels-changed',
198
+ serverId,
199
+ added: params.added?.map((c) => c.id) ?? [],
200
+ removed: params.removed ?? [],
201
+ updated: params.updated?.map((c) => c.id) ?? [],
202
+ });
203
+ }
204
+ /**
205
+ * Handle `channels/incoming` from a server.
206
+ *
207
+ * Converts each message's content, pushes McplChannelIncomingEvent to the
208
+ * queue, and responds with per-message results.
209
+ */
210
+ handleIncoming(serverId, params, responder) {
211
+ const results = [];
212
+ for (const message of params.messages) {
213
+ // Convert MCPL content blocks to membrane ContentBlocks
214
+ const convertedContent = message.content.map(convertBlock);
215
+ // Track default publish channel (most recent incoming)
216
+ this.defaultPublishChannel = message.channelId;
217
+ this.defaultPublishMessageId = message.messageId;
218
+ this.defaultPublishThreadId = message.threadId;
219
+ // Determine whether to trigger inference
220
+ let triggerInference = true;
221
+ if (this.shouldTriggerInference) {
222
+ const textContent = message.content
223
+ .filter((b) => b.type === 'text')
224
+ .map((b) => b.text)
225
+ .join('\n');
226
+ triggerInference = this.shouldTriggerInference(textContent, {
227
+ ...message.metadata,
228
+ eventType: 'channel:incoming',
229
+ serverId,
230
+ channelId: message.channelId,
231
+ messageId: message.messageId,
232
+ threadId: message.threadId,
233
+ author: message.author,
234
+ });
235
+ }
236
+ // Build the incoming event
237
+ const event = {
238
+ type: 'mcpl:channel-incoming',
239
+ serverId,
240
+ channelId: message.channelId,
241
+ messageId: message.messageId,
242
+ threadId: message.threadId,
243
+ author: message.author,
244
+ content: convertedContent,
245
+ timestamp: message.timestamp,
246
+ metadata: message.metadata,
247
+ triggerInference,
248
+ };
249
+ // Push to the processing queue
250
+ // Cast through unknown because McplChannelIncomingEvent matches the
251
+ // CustomEvent `${string}:${string}` type pattern but lacks an index signature.
252
+ this.pushEventFn(event);
253
+ // Collect per-message result
254
+ results.push({
255
+ messageId: message.messageId,
256
+ accepted: true,
257
+ });
258
+ }
259
+ const result = { results };
260
+ responder?.respond(result);
261
+ this.emitTraceFn({
262
+ type: 'mcpl:channels-incoming',
263
+ serverId,
264
+ messageCount: params.messages.length,
265
+ channelIds: [...new Set(params.messages.map((m) => m.channelId))],
266
+ });
267
+ }
268
+ // ==========================================================================
269
+ // Typing Indicator Management
270
+ // ==========================================================================
271
+ /**
272
+ * Start sending typing indicators for a channel.
273
+ *
274
+ * Sends a typing notification immediately and every 7 seconds thereafter.
275
+ * Discord typing indicators last ~10s, so 7s keeps them alive.
276
+ *
277
+ * No-op if already typing on this channel.
278
+ */
279
+ startTyping(channelId) {
280
+ if (this.typingIntervals.has(channelId)) {
281
+ return; // Already typing
282
+ }
283
+ // Find the channel entry and its server
284
+ const entry = this.findChannelEntry(channelId);
285
+ if (!entry) {
286
+ return;
287
+ }
288
+ // Send typing immediately
289
+ this.sendTypingNotification(entry.serverId, channelId);
290
+ // Set up interval
291
+ const interval = setInterval(() => {
292
+ this.sendTypingNotification(entry.serverId, channelId);
293
+ }, TYPING_INTERVAL_MS);
294
+ this.typingIntervals.set(channelId, interval);
295
+ }
296
+ /**
297
+ * Stop sending typing indicators.
298
+ *
299
+ * If channelId is specified, stops typing on that channel only.
300
+ * If no channelId, stops all typing indicators.
301
+ */
302
+ stopTyping(channelId) {
303
+ if (channelId !== undefined) {
304
+ const interval = this.typingIntervals.get(channelId);
305
+ if (interval) {
306
+ clearInterval(interval);
307
+ this.typingIntervals.delete(channelId);
308
+ }
309
+ }
310
+ else {
311
+ // Clear all typing intervals
312
+ for (const interval of this.typingIntervals.values()) {
313
+ clearInterval(interval);
314
+ }
315
+ this.typingIntervals.clear();
316
+ }
317
+ }
318
+ // ==========================================================================
319
+ // Accessors
320
+ // ==========================================================================
321
+ /**
322
+ * Get the default publish channel ID (most recent incoming channel).
323
+ */
324
+ getDefaultPublishChannel() {
325
+ return this.defaultPublishChannel;
326
+ }
327
+ /**
328
+ * Get all open channels.
329
+ */
330
+ getOpenChannels() {
331
+ const result = [];
332
+ for (const entry of this.channels.values()) {
333
+ if (entry.open) {
334
+ result.push(entry);
335
+ }
336
+ }
337
+ return result;
338
+ }
339
+ // ==========================================================================
340
+ // Synthesized Channel Tools
341
+ // ==========================================================================
342
+ /**
343
+ * Get synthesized tool definitions for channel operations.
344
+ */
345
+ getChannelTools() {
346
+ return CHANNEL_TOOL_DEFINITIONS;
347
+ }
348
+ /**
349
+ * Handle a call to one of the synthesized channel tools.
350
+ */
351
+ async handleChannelToolCall(toolName, input) {
352
+ switch (toolName) {
353
+ case 'channel_list':
354
+ return this.handleToolList();
355
+ case 'channel_open':
356
+ return this.handleToolOpen(input);
357
+ case 'channel_close':
358
+ return this.handleToolClose(input);
359
+ case 'channel_publish':
360
+ return this.handleToolPublish(input);
361
+ default:
362
+ return { success: false, error: `Unknown channel tool: ${toolName}`, isError: true };
363
+ }
364
+ }
365
+ // ==========================================================================
366
+ // Channel Context for beforeInference
367
+ // ==========================================================================
368
+ /**
369
+ * Build channel context for inclusion in beforeInference params.
370
+ *
371
+ * Returns undefined if no channels are active.
372
+ */
373
+ buildChannelContext() {
374
+ const openChannels = this.getOpenChannels();
375
+ if (openChannels.length === 0 && !this.defaultPublishChannel) {
376
+ return undefined;
377
+ }
378
+ const context = {};
379
+ // Incoming: from defaultPublishChannel if set
380
+ if (this.defaultPublishChannel && this.defaultPublishMessageId) {
381
+ context.incoming = {
382
+ channelId: this.defaultPublishChannel,
383
+ messageId: this.defaultPublishMessageId,
384
+ threadId: this.defaultPublishThreadId,
385
+ };
386
+ }
387
+ // Default outgoing: same as incoming (reply to last channel)
388
+ if (this.defaultPublishChannel) {
389
+ context.defaultOutgoing = {
390
+ channelId: this.defaultPublishChannel,
391
+ };
392
+ }
393
+ // Candidates: all open channel IDs
394
+ if (openChannels.length > 0) {
395
+ context.candidates = openChannels.map((e) => e.descriptor.id);
396
+ }
397
+ return context;
398
+ }
399
+ // ==========================================================================
400
+ // Lifecycle
401
+ // ==========================================================================
402
+ /**
403
+ * Stop all typing intervals and clear all channel registrations.
404
+ */
405
+ stopAll() {
406
+ // Clear all typing intervals
407
+ for (const interval of this.typingIntervals.values()) {
408
+ clearInterval(interval);
409
+ }
410
+ this.typingIntervals.clear();
411
+ // Clear channels map
412
+ this.channels.clear();
413
+ // Reset default publish tracking
414
+ this.defaultPublishChannel = null;
415
+ this.defaultPublishMessageId = null;
416
+ this.defaultPublishThreadId = undefined;
417
+ }
418
+ // ==========================================================================
419
+ // Private: Auto-open channels
420
+ // ==========================================================================
421
+ async autoOpenChannels(serverId, channels) {
422
+ const server = this.serverRegistry.getServer(serverId);
423
+ if (!server)
424
+ return;
425
+ for (const channel of channels) {
426
+ const key = `${serverId}:${channel.id}`;
427
+ try {
428
+ await server.sendChannelsOpen({
429
+ type: channel.type,
430
+ address: channel.address,
431
+ });
432
+ const entry = this.channels.get(key);
433
+ if (entry) {
434
+ entry.open = true;
435
+ }
436
+ }
437
+ catch (err) {
438
+ this.emitTraceFn({
439
+ type: 'mcpl:channel-open-failed',
440
+ serverId,
441
+ channelId: channel.id,
442
+ error: err.message,
443
+ });
444
+ }
445
+ }
446
+ }
447
+ // ==========================================================================
448
+ // Private: Typing notification
449
+ // ==========================================================================
450
+ /**
451
+ * Send a typing notification for a channel.
452
+ *
453
+ * Uses the sendTypingFn callback if provided. If not, this is a no-op
454
+ * (typing timer lifecycle is still managed for when the callback is wired).
455
+ */
456
+ sendTypingNotification(serverId, channelId) {
457
+ if (this.sendTypingFn) {
458
+ this.sendTypingFn(serverId, channelId);
459
+ }
460
+ // TODO: When server-connection exposes a public sendNotification or
461
+ // sendTyping method, wire it here directly instead of using a callback.
462
+ }
463
+ // ==========================================================================
464
+ // Private: Channel Lookup
465
+ // ==========================================================================
466
+ /**
467
+ * Find a channel entry by channelId (searches across all servers).
468
+ * Returns the first match.
469
+ */
470
+ findChannelEntry(channelId) {
471
+ for (const [key, entry] of this.channels) {
472
+ if (entry.descriptor.id === channelId) {
473
+ return entry;
474
+ }
475
+ }
476
+ return undefined;
477
+ }
478
+ /**
479
+ * Find the composite key for a channel by its channelId.
480
+ */
481
+ findChannelKey(channelId) {
482
+ for (const [key, entry] of this.channels) {
483
+ if (entry.descriptor.id === channelId) {
484
+ return key;
485
+ }
486
+ }
487
+ return undefined;
488
+ }
489
+ // ==========================================================================
490
+ // Private: Tool Handlers
491
+ // ==========================================================================
492
+ handleToolList() {
493
+ const allChannels = [];
494
+ for (const entry of this.channels.values()) {
495
+ allChannels.push({
496
+ id: entry.descriptor.id,
497
+ type: entry.descriptor.type,
498
+ label: entry.descriptor.label,
499
+ direction: entry.descriptor.direction,
500
+ open: entry.open,
501
+ serverId: entry.serverId,
502
+ });
503
+ }
504
+ return {
505
+ success: true,
506
+ data: allChannels,
507
+ };
508
+ }
509
+ async handleToolOpen(input) {
510
+ const entry = this.findChannelEntry(input.channelId);
511
+ if (!entry) {
512
+ return {
513
+ success: false,
514
+ error: `Channel not found: ${input.channelId}`,
515
+ isError: true,
516
+ };
517
+ }
518
+ if (entry.open) {
519
+ return {
520
+ success: true,
521
+ data: { channelId: input.channelId, status: 'already open' },
522
+ };
523
+ }
524
+ const server = this.serverRegistry.getServer(entry.serverId);
525
+ if (!server) {
526
+ return {
527
+ success: false,
528
+ error: `Server not found: ${entry.serverId}`,
529
+ isError: true,
530
+ };
531
+ }
532
+ try {
533
+ await server.sendChannelsOpen({
534
+ type: entry.descriptor.type,
535
+ address: entry.descriptor.address,
536
+ });
537
+ entry.open = true;
538
+ return {
539
+ success: true,
540
+ data: { channelId: input.channelId, status: 'opened' },
541
+ };
542
+ }
543
+ catch (err) {
544
+ return {
545
+ success: false,
546
+ error: `Failed to open channel: ${err.message}`,
547
+ isError: true,
548
+ };
549
+ }
550
+ }
551
+ async handleToolClose(input) {
552
+ const entry = this.findChannelEntry(input.channelId);
553
+ if (!entry) {
554
+ return {
555
+ success: false,
556
+ error: `Channel not found: ${input.channelId}`,
557
+ isError: true,
558
+ };
559
+ }
560
+ if (!entry.open) {
561
+ return {
562
+ success: true,
563
+ data: { channelId: input.channelId, status: 'already closed' },
564
+ };
565
+ }
566
+ const server = this.serverRegistry.getServer(entry.serverId);
567
+ if (!server) {
568
+ return {
569
+ success: false,
570
+ error: `Server not found: ${entry.serverId}`,
571
+ isError: true,
572
+ };
573
+ }
574
+ try {
575
+ await server.sendChannelsClose({ channelId: input.channelId });
576
+ entry.open = false;
577
+ this.stopTyping(input.channelId);
578
+ return {
579
+ success: true,
580
+ data: { channelId: input.channelId, status: 'closed' },
581
+ };
582
+ }
583
+ catch (err) {
584
+ return {
585
+ success: false,
586
+ error: `Failed to close channel: ${err.message}`,
587
+ isError: true,
588
+ };
589
+ }
590
+ }
591
+ async handleToolPublish(input) {
592
+ // Resolve content: accept both `content` and `text` (backward compat)
593
+ const messageText = input.content ?? input.text;
594
+ if (!messageText) {
595
+ return {
596
+ success: false,
597
+ error: 'Either content or text parameter is required',
598
+ isError: true,
599
+ };
600
+ }
601
+ // Resolve channelId: default to most recent incoming channel
602
+ const channelId = input.channelId ?? this.defaultPublishChannel;
603
+ if (!channelId) {
604
+ return {
605
+ success: false,
606
+ error: 'No channelId specified and no default channel available',
607
+ isError: true,
608
+ };
609
+ }
610
+ const entry = this.findChannelEntry(channelId);
611
+ if (!entry) {
612
+ return {
613
+ success: false,
614
+ error: `Channel not found: ${channelId}`,
615
+ isError: true,
616
+ };
617
+ }
618
+ const server = this.serverRegistry.getServer(entry.serverId);
619
+ if (!server) {
620
+ return {
621
+ success: false,
622
+ error: `Server not found: ${entry.serverId}`,
623
+ isError: true,
624
+ };
625
+ }
626
+ try {
627
+ const publishParams = {
628
+ conversationId: '', // Framework will fill this when wired
629
+ channelId,
630
+ content: [{ type: 'text', text: messageText }],
631
+ };
632
+ const result = await server.sendChannelsPublish(publishParams);
633
+ return {
634
+ success: true,
635
+ data: result ?? { delivered: true },
636
+ };
637
+ }
638
+ catch (err) {
639
+ return {
640
+ success: false,
641
+ error: `Failed to publish to channel: ${err.message}`,
642
+ isError: true,
643
+ };
644
+ }
645
+ }
646
+ }
647
+ //# sourceMappingURL=channel-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel-registry.js","sourceRoot":"","sources":["../../../src/mcpl/channel-registry.ts"],"names":[],"mappings":"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"}