eacn3 0.3.3 → 0.5.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 (48) hide show
  1. package/dist/index.d.ts +7 -1
  2. package/dist/index.js +917 -620
  3. package/dist/index.js.map +1 -1
  4. package/dist/server.js +639 -47
  5. package/dist/server.js.map +1 -1
  6. package/dist/src/a2a-server.js +2 -1
  7. package/dist/src/a2a-server.js.map +1 -1
  8. package/dist/src/event-transport.d.ts +31 -0
  9. package/dist/src/event-transport.js +178 -0
  10. package/dist/src/event-transport.js.map +1 -0
  11. package/dist/src/models.d.ts +55 -13
  12. package/dist/src/models.js +1 -1
  13. package/dist/src/models.js.map +1 -1
  14. package/dist/src/network-client.d.ts +1 -1
  15. package/dist/src/network-client.js +4 -5
  16. package/dist/src/network-client.js.map +1 -1
  17. package/dist/src/reverse-control.d.ts +74 -0
  18. package/dist/src/reverse-control.js +609 -0
  19. package/dist/src/reverse-control.js.map +1 -0
  20. package/dist/src/state.d.ts +17 -4
  21. package/dist/src/state.js +134 -12
  22. package/dist/src/state.js.map +1 -1
  23. package/openclaw.plugin.json +1 -1
  24. package/package.json +2 -6
  25. package/scripts/cli.cjs +13 -12
  26. package/skills/eacn3-bid/SKILL.md +2 -2
  27. package/skills/eacn3-bid-zh/SKILL.md +2 -2
  28. package/skills/eacn3-bounty/SKILL.md +7 -7
  29. package/skills/eacn3-bounty-zh/SKILL.md +7 -7
  30. package/skills/eacn3-browse/SKILL.md +1 -1
  31. package/skills/eacn3-budget/SKILL.md +1 -1
  32. package/skills/eacn3-budget-zh/SKILL.md +1 -1
  33. package/skills/eacn3-clarify/SKILL.md +1 -1
  34. package/skills/eacn3-clarify-zh/SKILL.md +1 -1
  35. package/skills/eacn3-collect/SKILL.md +1 -1
  36. package/skills/eacn3-collect-zh/SKILL.md +1 -1
  37. package/skills/eacn3-dashboard/SKILL.md +3 -3
  38. package/skills/eacn3-dashboard-zh/SKILL.md +3 -3
  39. package/skills/eacn3-delegate/SKILL.md +1 -1
  40. package/skills/eacn3-delegate-zh/SKILL.md +1 -1
  41. package/skills/eacn3-execute/SKILL.md +1 -1
  42. package/skills/eacn3-execute-zh/SKILL.md +1 -1
  43. package/skills/eacn3-invite/SKILL.md +1 -1
  44. package/skills/eacn3-invite-zh/SKILL.md +1 -1
  45. package/skills/eacn3-register/SKILL.md +3 -15
  46. package/skills/eacn3-register-zh/SKILL.md +3 -15
  47. package/skills/eacn3-task/SKILL.md +1 -1
  48. package/skills/eacn3-task-zh/SKILL.md +1 -1
@@ -0,0 +1,609 @@
1
+ /**
2
+ * MCP Reverse Control Engine
3
+ *
4
+ * Enables the MCP Server to proactively drive the Host LLM via:
5
+ * 1. Sampling (sampling/createMessage) — ask LLM to reason and decide
6
+ * 2. Notifications — push state updates to Host
7
+ * 3. Enhanced tool results — inject pending events into any tool response (fallback)
8
+ *
9
+ * When push events arrive from the EACN3 network, instead of just buffering
10
+ * them for polling, this engine evaluates each event and may invoke the Host's LLM
11
+ * to make a decision (bid on a task, reply to a message, etc.).
12
+ */
13
+ import * as state from "./state.js";
14
+ import * as net from "./network-client.js";
15
+ // ---------------------------------------------------------------------------
16
+ // Constants
17
+ // ---------------------------------------------------------------------------
18
+ const MAX_SAMPLING_PER_MINUTE = 10;
19
+ const SAMPLING_TIMEOUT_MS = 30_000;
20
+ const PROCESSED_EVENT_TTL_MS = 300_000; // 5 minutes
21
+ const RATE_WINDOW_MS = 60_000;
22
+ // ---------------------------------------------------------------------------
23
+ // State
24
+ // ---------------------------------------------------------------------------
25
+ let mcpServer = null;
26
+ let samplingAvailable = false;
27
+ let configs = {}; // keyed by agent_id
28
+ const processedEvents = [];
29
+ const samplingTimestamps = [];
30
+ /** Pending directives for the enhanced tool result fallback. */
31
+ const pendingDirectives = [];
32
+ // ---------------------------------------------------------------------------
33
+ // Default policies
34
+ // ---------------------------------------------------------------------------
35
+ const DEFAULT_POLICIES = {
36
+ task_broadcast: { method: "sampling" },
37
+ bid_request_confirmation: { method: "sampling" },
38
+ bid_result: { method: "notification" },
39
+ discussion_update: { method: "sampling" },
40
+ subtask_completed: { method: "sampling" },
41
+ task_collected: { method: "notification" },
42
+ task_timeout: { method: "auto_action", autoAction: "report_and_close" },
43
+ adjudication_task: { method: "sampling" },
44
+ direct_message: { method: "sampling" },
45
+ };
46
+ // ---------------------------------------------------------------------------
47
+ // Initialization
48
+ // ---------------------------------------------------------------------------
49
+ /**
50
+ * Initialize the reverse control engine with the MCP server instance.
51
+ * Call this after the MCP server is connected and transport is ready.
52
+ */
53
+ export function init(server) {
54
+ mcpServer = server;
55
+ detectCapabilities();
56
+ }
57
+ /**
58
+ * Detect whether the connected Client supports sampling.
59
+ * Called automatically on init; can be re-called if capabilities change.
60
+ */
61
+ function detectCapabilities() {
62
+ if (!mcpServer)
63
+ return;
64
+ try {
65
+ // The MCP SDK exposes client capabilities after connection handshake.
66
+ // We check if sampling was declared by the client.
67
+ const clientCaps = mcpServer.getClientCapabilities?.()
68
+ ?? mcpServer._clientCapabilities
69
+ ?? mcpServer.clientCapabilities;
70
+ samplingAvailable = !!(clientCaps?.sampling);
71
+ }
72
+ catch {
73
+ samplingAvailable = false;
74
+ }
75
+ console.error(`[ReverseControl] sampling available: ${samplingAvailable}`);
76
+ }
77
+ /**
78
+ * Register reverse control config for an agent.
79
+ * Merges with defaults — only override what you specify.
80
+ */
81
+ export function configure(agentId, partial) {
82
+ configs[agentId] = {
83
+ enabled: partial?.enabled ?? true,
84
+ policies: { ...DEFAULT_POLICIES, ...(partial?.policies ?? {}) },
85
+ };
86
+ }
87
+ /**
88
+ * Remove config when agent unregisters.
89
+ */
90
+ export function unconfigure(agentId) {
91
+ delete configs[agentId];
92
+ }
93
+ // ---------------------------------------------------------------------------
94
+ // Core: Event Processing
95
+ // ---------------------------------------------------------------------------
96
+ /**
97
+ * Main entry point: process a WebSocket event through the reverse control engine.
98
+ * Called by event-transport's callback instead of directly buffering.
99
+ *
100
+ * Returns true if the event was handled (sampling/notification/auto-action).
101
+ * Returns false if it should fall through to normal event buffering.
102
+ */
103
+ export async function handleEvent(agentId, event) {
104
+ const config = configs[agentId];
105
+ if (!config?.enabled)
106
+ return false;
107
+ // Dedup: skip already-processed events
108
+ if (event.msg_id && isAlreadyProcessed(event.msg_id)) {
109
+ return true; // silently skip duplicate
110
+ }
111
+ const policy = config.policies[event.type];
112
+ if (!policy || policy.method === "buffer_only")
113
+ return false;
114
+ switch (policy.method) {
115
+ case "sampling":
116
+ return await handleViaSampling(agentId, event);
117
+ case "notification":
118
+ return handleViaNotification(agentId, event);
119
+ case "auto_action":
120
+ return await handleViaAutoAction(agentId, event, policy.autoAction);
121
+ default:
122
+ return false;
123
+ }
124
+ }
125
+ // ---------------------------------------------------------------------------
126
+ // Sampling
127
+ // ---------------------------------------------------------------------------
128
+ async function handleViaSampling(agentId, event) {
129
+ // If sampling isn't available, queue as directive for tool-result injection
130
+ if (!samplingAvailable || !mcpServer) {
131
+ queueDirective(agentId, event);
132
+ return false; // still buffer the event
133
+ }
134
+ // Rate limiting
135
+ if (!checkRateLimit()) {
136
+ console.error(`[ReverseControl] sampling rate limit reached, queuing directive`);
137
+ queueDirective(agentId, event);
138
+ return false;
139
+ }
140
+ const agent = state.getAgent(agentId);
141
+ if (!agent)
142
+ return false;
143
+ const prompt = buildSamplingPrompt(agentId, agent, event);
144
+ if (!prompt)
145
+ return false;
146
+ try {
147
+ markProcessed(event.msg_id);
148
+ recordSamplingCall();
149
+ const result = await Promise.race([
150
+ requestSampling(prompt),
151
+ timeout(SAMPLING_TIMEOUT_MS),
152
+ ]);
153
+ if (!result) {
154
+ console.error(`[ReverseControl] sampling timed out for ${event.type}`);
155
+ queueDirective(agentId, event);
156
+ return false;
157
+ }
158
+ const decision = parseSamplingResponse(event.type, result);
159
+ if (decision) {
160
+ await executeDecision(agentId, event, decision);
161
+ }
162
+ return true;
163
+ }
164
+ catch (e) {
165
+ console.error(`[ReverseControl] sampling error:`, e.message);
166
+ queueDirective(agentId, event);
167
+ return false;
168
+ }
169
+ }
170
+ /**
171
+ * Build the prompt for a sampling request based on event type.
172
+ */
173
+ function buildSamplingPrompt(agentId, agent, event) {
174
+ const payload = event.payload;
175
+ switch (event.type) {
176
+ case "task_broadcast":
177
+ return [
178
+ `You are agent "${agent.name}" (${agentId}) on the EACN3 network.`,
179
+ `Your domains: [${agent.domains.join(", ")}]`,
180
+ `Your tier: ${agent.tier}`,
181
+ ``,
182
+ `A new task is available:`,
183
+ ` Task ID: ${event.task_id}`,
184
+ ` Domains: [${(payload.domains ?? []).join(", ")}]`,
185
+ ` Budget: ${payload.budget ?? "unknown"} credits`,
186
+ ` Description: ${payload.description ?? "No description"}`,
187
+ ` Level: ${payload.level ?? "general"}`,
188
+ ``,
189
+ `Should you bid on this task? If yes, respond in JSON:`,
190
+ `{"action":"bid","confidence":0.0-1.0,"price":number}`,
191
+ `If no, respond: {"action":"ignore","reason":"..."}`,
192
+ ].join("\n");
193
+ case "direct_message":
194
+ return [
195
+ `You are agent "${agent.name}" (${agentId}) on the EACN3 network.`,
196
+ ``,
197
+ `You received a direct message:`,
198
+ ` From: ${payload.from ?? "unknown"}`,
199
+ ` Content: ${typeof payload.content === "string" ? payload.content : JSON.stringify(payload.content)}`,
200
+ ` Related task: ${event.task_id}`,
201
+ ``,
202
+ `How should you respond? Reply in JSON:`,
203
+ `{"action":"reply","message":"your response here"}`,
204
+ `Or to ignore: {"action":"ignore","reason":"..."}`,
205
+ ].join("\n");
206
+ case "subtask_completed":
207
+ return [
208
+ `You are agent "${agent.name}" (${agentId}) on the EACN3 network.`,
209
+ ``,
210
+ `A subtask you created has completed:`,
211
+ ` Parent task: ${event.task_id}`,
212
+ ` Subtask ID: ${payload.subtask_id ?? "unknown"}`,
213
+ ` Results: ${JSON.stringify(payload.results ?? {}).slice(0, 500)}`,
214
+ ``,
215
+ `What should you do next? Options:`,
216
+ `- Submit your final result: {"action":"custom","tool":"eacn3_submit_result","params":{...}}`,
217
+ `- Create another subtask: {"action":"custom","tool":"eacn3_create_subtask","params":{...}}`,
218
+ `- Ignore for now: {"action":"ignore","reason":"..."}`,
219
+ ].join("\n");
220
+ case "bid_request_confirmation":
221
+ return [
222
+ `You are agent "${agent.name}" (${agentId}) on the EACN3 network.`,
223
+ ``,
224
+ `A bid on your task exceeded the budget:`,
225
+ ` Task: ${event.task_id}`,
226
+ ` Bidder: ${payload.agent_id ?? "unknown"}`,
227
+ ` Bid price: ${payload.price ?? "unknown"} credits`,
228
+ ` Excess: ${payload.excess_amount ?? "unknown"} credits`,
229
+ ``,
230
+ `Approve this over-budget bid? Respond in JSON:`,
231
+ `{"action":"confirm"} or {"action":"decline","reason":"..."}`,
232
+ ].join("\n");
233
+ case "discussion_update":
234
+ return [
235
+ `You are agent "${agent.name}" (${agentId}) on the EACN3 network.`,
236
+ ``,
237
+ `The task initiator posted a discussion update:`,
238
+ ` Task: ${event.task_id}`,
239
+ ` Content: ${JSON.stringify(payload.discussions ?? payload.message ?? {}).slice(0, 500)}`,
240
+ ``,
241
+ `How should you respond? Reply in JSON:`,
242
+ `{"action":"reply","message":"your response"}`,
243
+ `Or: {"action":"ignore"}`,
244
+ ].join("\n");
245
+ case "adjudication_task":
246
+ return [
247
+ `You are agent "${agent.name}" (${agentId}) on the EACN3 network.`,
248
+ ``,
249
+ `You have been asked to adjudicate a dispute:`,
250
+ ` Task: ${event.task_id}`,
251
+ ` Domains: [${(payload.domains ?? []).join(", ")}]`,
252
+ ` Details: ${JSON.stringify(payload.content ?? {}).slice(0, 500)}`,
253
+ ``,
254
+ `Evaluate and respond in JSON:`,
255
+ `{"action":"bid","confidence":0.0-1.0,"price":number}`,
256
+ `Or: {"action":"ignore","reason":"..."}`,
257
+ ].join("\n");
258
+ default:
259
+ return null;
260
+ }
261
+ }
262
+ /**
263
+ * Send a sampling/createMessage request to the Host's LLM.
264
+ */
265
+ async function requestSampling(prompt) {
266
+ if (!mcpServer)
267
+ return null;
268
+ try {
269
+ // Use the MCP server's request method to send sampling/createMessage
270
+ // to the connected client. The client's LLM will process it.
271
+ const result = await mcpServer.createMessage({
272
+ messages: [
273
+ {
274
+ role: "user",
275
+ content: { type: "text", text: prompt },
276
+ },
277
+ ],
278
+ maxTokens: 512,
279
+ });
280
+ // Extract text content from the response
281
+ if (result?.content?.type === "text") {
282
+ return result.content.text;
283
+ }
284
+ if (typeof result?.content === "string") {
285
+ return result.content;
286
+ }
287
+ return null;
288
+ }
289
+ catch (e) {
290
+ console.error(`[ReverseControl] createMessage failed:`, e.message);
291
+ return null;
292
+ }
293
+ }
294
+ /**
295
+ * Parse the LLM's sampling response into a structured decision.
296
+ */
297
+ function parseSamplingResponse(eventType, response) {
298
+ try {
299
+ // Try to extract JSON from the response (LLM may wrap it in markdown)
300
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
301
+ if (!jsonMatch)
302
+ return null;
303
+ const parsed = JSON.parse(jsonMatch[0]);
304
+ const action = parsed.action;
305
+ if (!action)
306
+ return null;
307
+ switch (action) {
308
+ case "bid":
309
+ return {
310
+ action: "bid",
311
+ params: {
312
+ confidence: Math.min(1.0, Math.max(0.0, Number(parsed.confidence) || 0.7)),
313
+ price: Number(parsed.price) || 0,
314
+ },
315
+ };
316
+ case "reply":
317
+ return {
318
+ action: "reply",
319
+ params: { message: String(parsed.message ?? "") },
320
+ };
321
+ case "confirm":
322
+ return { action: "confirm", params: {} };
323
+ case "decline":
324
+ return { action: "decline", params: { reason: parsed.reason } };
325
+ case "ignore":
326
+ return { action: "ignore", params: { reason: parsed.reason } };
327
+ case "custom":
328
+ return {
329
+ action: "custom",
330
+ params: { tool: parsed.tool, params: parsed.params ?? {} },
331
+ };
332
+ default:
333
+ return null;
334
+ }
335
+ }
336
+ catch {
337
+ return null;
338
+ }
339
+ }
340
+ /**
341
+ * Execute a decision made by the LLM via sampling.
342
+ */
343
+ async function executeDecision(agentId, event, decision) {
344
+ const taskId = event.task_id;
345
+ const payload = event.payload;
346
+ try {
347
+ switch (decision.action) {
348
+ case "bid": {
349
+ const { confidence, price } = decision.params;
350
+ await net.submitBid(taskId, agentId, confidence, price);
351
+ state.updateTask({
352
+ task_id: taskId,
353
+ agent_id: agentId,
354
+ role: "executor",
355
+ status: "bidding",
356
+ domains: payload.domains ?? [],
357
+ description_summary: String(payload.description ?? "").slice(0, 100),
358
+ created_at: new Date().toISOString(),
359
+ });
360
+ console.error(`[ReverseControl] auto-bid: task=${taskId} confidence=${confidence} price=${price}`);
361
+ break;
362
+ }
363
+ case "reply": {
364
+ const message = decision.params.message;
365
+ const to = payload.from ?? "";
366
+ if (to && message) {
367
+ const s = state.getState();
368
+ const sid = s.server_card?.server_id ?? "";
369
+ await net.relayMessage({
370
+ from: { network_id: "", server_id: sid, agent_id: agentId },
371
+ to: { network_id: "", server_id: "", agent_id: to },
372
+ content: message,
373
+ });
374
+ state.addMessage(agentId, {
375
+ from: agentId,
376
+ to,
377
+ content: message,
378
+ timestamp: Date.now(),
379
+ direction: "out",
380
+ });
381
+ console.error(`[ReverseControl] auto-reply: to=${to} task=${taskId}`);
382
+ }
383
+ break;
384
+ }
385
+ case "confirm": {
386
+ await net.confirmBudget(taskId, agentId, true);
387
+ console.error(`[ReverseControl] auto-confirm budget: task=${taskId}`);
388
+ break;
389
+ }
390
+ case "decline": {
391
+ await net.confirmBudget(taskId, agentId, false);
392
+ console.error(`[ReverseControl] auto-decline budget: task=${taskId}`);
393
+ break;
394
+ }
395
+ case "custom": {
396
+ // Custom actions are logged but not auto-executed for safety.
397
+ // They're pushed as enhanced events for the agent to pick up.
398
+ state.pushEvents(agentId, [{
399
+ ...event,
400
+ payload: { ...payload, _rc_decision: decision.params },
401
+ received_at: Date.now(),
402
+ }]);
403
+ console.error(`[ReverseControl] custom decision buffered: tool=${decision.params.tool}`);
404
+ break;
405
+ }
406
+ case "ignore":
407
+ console.error(`[ReverseControl] ignored: ${event.type} task=${taskId} reason=${decision.params.reason}`);
408
+ break;
409
+ }
410
+ }
411
+ catch (e) {
412
+ console.error(`[ReverseControl] action execution failed:`, e.message);
413
+ // On failure, ensure the event is still buffered so agent can handle manually
414
+ state.pushEvents(agentId, [event]);
415
+ }
416
+ }
417
+ // ---------------------------------------------------------------------------
418
+ // Notifications
419
+ // ---------------------------------------------------------------------------
420
+ function handleViaNotification(agentId, event) {
421
+ if (!mcpServer)
422
+ return false;
423
+ try {
424
+ markProcessed(event.msg_id);
425
+ // Send a custom notification to the client
426
+ mcpServer.notification({
427
+ method: "notifications/message",
428
+ params: {
429
+ level: event.type === "task_timeout" ? "warning" : "info",
430
+ logger: "eacn3-reverse-control",
431
+ data: {
432
+ type: event.type,
433
+ task_id: event.task_id,
434
+ summary: buildNotificationSummary(event),
435
+ payload: event.payload,
436
+ },
437
+ },
438
+ });
439
+ console.error(`[ReverseControl] notification sent: ${event.type} task=${event.task_id}`);
440
+ return false; // still buffer — notification is supplementary
441
+ }
442
+ catch (e) {
443
+ console.error(`[ReverseControl] notification failed:`, e.message);
444
+ return false;
445
+ }
446
+ }
447
+ function buildNotificationSummary(event) {
448
+ const payload = event.payload;
449
+ switch (event.type) {
450
+ case "task_collected":
451
+ return `Task ${event.task_id} has results ready for retrieval.`;
452
+ case "task_timeout":
453
+ return `Task ${event.task_id} has timed out.`;
454
+ case "bid_result": {
455
+ const p = event.payload;
456
+ return p.accepted
457
+ ? `Your bid on task ${event.task_id} was accepted.`
458
+ : `Your bid on task ${event.task_id} was rejected: ${p.reason ?? "no reason given"}.`;
459
+ }
460
+ default:
461
+ return `Event ${event.type} on task ${event.task_id}.`;
462
+ }
463
+ }
464
+ // ---------------------------------------------------------------------------
465
+ // Auto-Actions
466
+ // ---------------------------------------------------------------------------
467
+ async function handleViaAutoAction(agentId, event, action) {
468
+ markProcessed(event.msg_id);
469
+ switch (action) {
470
+ case "report_and_close":
471
+ // Auto-report timeout and update local state
472
+ state.updateTaskStatus(event.task_id, "no_one");
473
+ try {
474
+ await net.reportEvent(agentId, "task_timeout");
475
+ }
476
+ catch { /* non-critical */ }
477
+ console.error(`[ReverseControl] auto-action: reported timeout for task=${event.task_id}`);
478
+ return true;
479
+ default:
480
+ return false;
481
+ }
482
+ }
483
+ // ---------------------------------------------------------------------------
484
+ // Enhanced Tool Result Injection (Fallback)
485
+ // ---------------------------------------------------------------------------
486
+ /**
487
+ * Queue a directive for injection into the next tool response.
488
+ * Used when sampling is unavailable but the event needs agent attention.
489
+ */
490
+ function queueDirective(agentId, event) {
491
+ const directive = buildDirectiveText(agentId, event);
492
+ if (directive) {
493
+ pendingDirectives.push({
494
+ agentId,
495
+ event,
496
+ directive,
497
+ createdAt: Date.now(),
498
+ });
499
+ }
500
+ }
501
+ function buildDirectiveText(agentId, event) {
502
+ const payload = event.payload;
503
+ switch (event.type) {
504
+ case "task_broadcast":
505
+ return `[ACTION NEEDED] New task ${event.task_id} in domain [${(payload.domains ?? []).join(", ")}] (budget: ${payload.budget ?? "?"}). Consider calling eacn3_submit_bid.`;
506
+ case "direct_message":
507
+ return `[ACTION NEEDED] Message from ${payload.from ?? "unknown"}: "${String(payload.content ?? "").slice(0, 200)}". Consider calling eacn3_send_message to reply.`;
508
+ case "subtask_completed":
509
+ return `[ACTION NEEDED] Subtask ${payload.subtask_id ?? "?"} completed for task ${event.task_id}. Results available. Consider calling eacn3_get_task_results.`;
510
+ case "bid_request_confirmation":
511
+ return `[ACTION NEEDED] Budget exceeded on task ${event.task_id}. Bid price: ${payload.price ?? "?"}. Call eacn3_confirm_budget to approve/reject.`;
512
+ case "discussion_update":
513
+ return `[ACTION NEEDED] New discussion on task ${event.task_id}. Check eacn3_get_task and respond.`;
514
+ default:
515
+ return null;
516
+ }
517
+ }
518
+ /**
519
+ * Drain pending directives for a given agent (or all agents).
520
+ * Called by tool result wrapper to inject into responses.
521
+ *
522
+ * Returns formatted text to append to tool results, or null if none.
523
+ */
524
+ export function drainDirectives(agentId) {
525
+ // Clean expired directives (older than 5 minutes)
526
+ const now = Date.now();
527
+ const cutoff = now - PROCESSED_EVENT_TTL_MS;
528
+ while (pendingDirectives.length > 0 && pendingDirectives[0].createdAt < cutoff) {
529
+ pendingDirectives.shift();
530
+ }
531
+ // Find directives for this agent
532
+ const matching = [];
533
+ const remaining = [];
534
+ for (const d of pendingDirectives) {
535
+ if (!agentId || d.agentId === agentId) {
536
+ matching.push(d);
537
+ }
538
+ else {
539
+ remaining.push(d);
540
+ }
541
+ }
542
+ if (matching.length === 0)
543
+ return null;
544
+ // Remove matched directives
545
+ pendingDirectives.length = 0;
546
+ pendingDirectives.push(...remaining);
547
+ const lines = matching.map((d, i) => `${i + 1}. ${d.directive}`);
548
+ return `\n\n---\n[EACN3 PENDING EVENTS] ${matching.length} event(s) require your attention:\n${lines.join("\n")}`;
549
+ }
550
+ /**
551
+ * Check if there are any pending directives (for deciding whether to inject).
552
+ */
553
+ export function hasPendingDirectives(agentId) {
554
+ if (!agentId)
555
+ return pendingDirectives.length > 0;
556
+ return pendingDirectives.some((d) => d.agentId === agentId);
557
+ }
558
+ // ---------------------------------------------------------------------------
559
+ // Rate Limiting & Dedup
560
+ // ---------------------------------------------------------------------------
561
+ function checkRateLimit() {
562
+ const now = Date.now();
563
+ // Remove timestamps outside the window
564
+ while (samplingTimestamps.length > 0 && samplingTimestamps[0] < now - RATE_WINDOW_MS) {
565
+ samplingTimestamps.shift();
566
+ }
567
+ return samplingTimestamps.length < MAX_SAMPLING_PER_MINUTE;
568
+ }
569
+ function recordSamplingCall() {
570
+ samplingTimestamps.push(Date.now());
571
+ }
572
+ function isAlreadyProcessed(msgId) {
573
+ // Clean old entries
574
+ const cutoff = Date.now() - PROCESSED_EVENT_TTL_MS;
575
+ while (processedEvents.length > 0 && processedEvents[0].processedAt < cutoff) {
576
+ processedEvents.shift();
577
+ }
578
+ return processedEvents.some((e) => e.msgId === msgId);
579
+ }
580
+ function markProcessed(msgId) {
581
+ if (msgId) {
582
+ processedEvents.push({ msgId, processedAt: Date.now() });
583
+ }
584
+ }
585
+ // ---------------------------------------------------------------------------
586
+ // Utility
587
+ // ---------------------------------------------------------------------------
588
+ function timeout(ms) {
589
+ return new Promise((resolve) => setTimeout(() => resolve(null), ms));
590
+ }
591
+ /**
592
+ * Get current reverse control status for debugging.
593
+ */
594
+ export function getStatus() {
595
+ return {
596
+ samplingAvailable,
597
+ configuredAgents: Object.keys(configs),
598
+ pendingDirectiveCount: pendingDirectives.length,
599
+ samplingCallsInWindow: samplingTimestamps.length,
600
+ };
601
+ }
602
+ /**
603
+ * Force re-detection of client capabilities.
604
+ * Useful after reconnection or capability negotiation.
605
+ */
606
+ export function refreshCapabilities() {
607
+ detectCapabilities();
608
+ }
609
+ //# sourceMappingURL=reverse-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverse-control.js","sourceRoot":"","sources":["../../src/reverse-control.ts"],"names":[],"mappings":"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"}