@tjamescouch/agentchat 0.14.0 → 0.16.1

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 (2) hide show
  1. package/lib/jitter.js +54 -0
  2. package/package.json +2 -2
package/lib/jitter.js ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Jitter utilities for preventing thundering herd and deadlock in distributed systems
3
+ */
4
+
5
+ /**
6
+ * Add jitter to a timeout value to prevent thundering herd / deadlock
7
+ * When multiple agents use the same timeout, they all wake up at once.
8
+ * Adding jitter spreads out the wakeups, breaking symmetry.
9
+ *
10
+ * @param {number} baseMs - Base timeout in milliseconds
11
+ * @param {number} jitterPercent - Jitter percentage (0.0 to 1.0), default 0.2 (20%)
12
+ * @returns {number} Jittered timeout value (minimum 100ms)
13
+ *
14
+ * @example
15
+ * // With 20% jitter, a 10000ms timeout becomes 8000-12000ms
16
+ * addJitter(10000, 0.2) // Returns value between 8000 and 12000
17
+ *
18
+ * @example
19
+ * // Prevent deadlock in listen loops
20
+ * const timeout = addJitter(60000, 0.2); // 48-72 seconds
21
+ * setTimeout(checkForMessages, timeout);
22
+ */
23
+ export function addJitter(baseMs, jitterPercent = 0.2) {
24
+ // Clamp jitter percent to valid range
25
+ const clampedJitter = Math.max(0, Math.min(1, jitterPercent));
26
+
27
+ const jitterAmount = baseMs * clampedJitter;
28
+ const jitter = (Math.random() - 0.5) * 2 * jitterAmount; // +/- jitterAmount
29
+
30
+ return Math.max(100, Math.round(baseMs + jitter)); // Min 100ms
31
+ }
32
+
33
+ /**
34
+ * Calculate exponential backoff with jitter
35
+ * Useful for reconnection attempts
36
+ *
37
+ * @param {number} attempt - Current attempt number (0-based)
38
+ * @param {number} baseMs - Base delay in milliseconds (default 1000)
39
+ * @param {number} maxMs - Maximum delay cap (default 60000)
40
+ * @param {number} jitterPercent - Jitter percentage (default 0.2)
41
+ * @returns {number} Delay with exponential backoff and jitter
42
+ *
43
+ * @example
44
+ * // Reconnection with backoff
45
+ * let attempt = 0;
46
+ * function reconnect() {
47
+ * const delay = exponentialBackoffWithJitter(attempt++);
48
+ * setTimeout(doReconnect, delay);
49
+ * }
50
+ */
51
+ export function exponentialBackoffWithJitter(attempt, baseMs = 1000, maxMs = 60000, jitterPercent = 0.2) {
52
+ const exponentialDelay = Math.min(baseMs * Math.pow(2, attempt), maxMs);
53
+ return addJitter(exponentialDelay, jitterPercent);
54
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tjamescouch/agentchat",
3
- "version": "0.14.0",
3
+ "version": "0.16.1",
4
4
  "description": "Real-time IRC-like communication protocol for AI agents",
5
5
  "main": "lib/client.js",
6
6
  "files": [
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "scripts": {
16
16
  "start": "node bin/agentchat.js serve",
17
- "test": "node --test test/identity.test.js test/deploy.test.js test/daemon.test.js test/receipts.test.js test/reputation.test.js",
17
+ "test": "node --test test/identity.test.js test/deploy.test.js test/daemon.test.js test/receipts.test.js test/reputation.test.js test/jitter.test.js",
18
18
  "test:integration": "node --test test/*.integration.test.js",
19
19
  "test:all": "node --test test/*.test.js"
20
20
  },