@tjamescouch/agentchat 0.22.1 → 0.23.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 (153) hide show
  1. package/Dockerfile +1 -1
  2. package/dist/bin/agentchat.d.ts +7 -0
  3. package/dist/bin/agentchat.d.ts.map +1 -0
  4. package/dist/bin/agentchat.js +1511 -0
  5. package/dist/bin/agentchat.js.map +1 -0
  6. package/dist/lib/allowlist.d.ts +77 -0
  7. package/dist/lib/allowlist.d.ts.map +1 -0
  8. package/dist/lib/allowlist.js +151 -0
  9. package/dist/lib/allowlist.js.map +1 -0
  10. package/dist/lib/client.d.ts +147 -0
  11. package/dist/lib/client.d.ts.map +1 -0
  12. package/dist/lib/client.js +704 -0
  13. package/dist/lib/client.js.map +1 -0
  14. package/dist/lib/daemon.d.ts +122 -0
  15. package/dist/lib/daemon.d.ts.map +1 -0
  16. package/dist/lib/daemon.js +523 -0
  17. package/dist/lib/daemon.js.map +1 -0
  18. package/dist/lib/deploy/akash.d.ts +271 -0
  19. package/dist/lib/deploy/akash.d.ts.map +1 -0
  20. package/dist/lib/deploy/akash.js +671 -0
  21. package/dist/lib/deploy/akash.js.map +1 -0
  22. package/dist/lib/deploy/config.d.ts +62 -0
  23. package/dist/lib/deploy/config.d.ts.map +1 -0
  24. package/dist/lib/deploy/config.js +116 -0
  25. package/dist/lib/deploy/config.js.map +1 -0
  26. package/dist/lib/deploy/docker.d.ts +37 -0
  27. package/dist/lib/deploy/docker.d.ts.map +1 -0
  28. package/dist/lib/deploy/docker.js +122 -0
  29. package/dist/lib/deploy/docker.js.map +1 -0
  30. package/dist/lib/deploy/index.d.ts +11 -0
  31. package/dist/lib/deploy/index.d.ts.map +1 -0
  32. package/dist/lib/deploy/index.js +11 -0
  33. package/dist/lib/deploy/index.js.map +1 -0
  34. package/dist/lib/escrow-hooks.d.ts +199 -0
  35. package/dist/lib/escrow-hooks.d.ts.map +1 -0
  36. package/dist/lib/escrow-hooks.js +221 -0
  37. package/dist/lib/escrow-hooks.js.map +1 -0
  38. package/dist/lib/identity.d.ts +134 -0
  39. package/dist/lib/identity.d.ts.map +1 -0
  40. package/dist/lib/identity.js +334 -0
  41. package/dist/lib/identity.js.map +1 -0
  42. package/dist/lib/jitter.d.ts +42 -0
  43. package/dist/lib/jitter.d.ts.map +1 -0
  44. package/{lib/jitter.ts → dist/lib/jitter.js} +10 -18
  45. package/dist/lib/jitter.js.map +1 -0
  46. package/dist/lib/proposals.d.ts +223 -0
  47. package/dist/lib/proposals.d.ts.map +1 -0
  48. package/dist/lib/proposals.js +379 -0
  49. package/dist/lib/proposals.js.map +1 -0
  50. package/dist/lib/protocol.d.ts +220 -0
  51. package/dist/lib/protocol.d.ts.map +1 -0
  52. package/dist/lib/protocol.js +507 -0
  53. package/dist/lib/protocol.js.map +1 -0
  54. package/dist/lib/receipts.d.ts +134 -0
  55. package/dist/lib/receipts.d.ts.map +1 -0
  56. package/dist/lib/receipts.js +270 -0
  57. package/dist/lib/receipts.js.map +1 -0
  58. package/dist/lib/reputation.d.ts +250 -0
  59. package/dist/lib/reputation.d.ts.map +1 -0
  60. package/dist/lib/reputation.js +586 -0
  61. package/dist/lib/reputation.js.map +1 -0
  62. package/dist/lib/security.d.ts +27 -0
  63. package/dist/lib/security.d.ts.map +1 -0
  64. package/dist/lib/security.js +150 -0
  65. package/dist/lib/security.js.map +1 -0
  66. package/dist/lib/server/handlers/admin.d.ts +26 -0
  67. package/dist/lib/server/handlers/admin.d.ts.map +1 -0
  68. package/dist/lib/server/handlers/admin.js +76 -0
  69. package/dist/lib/server/handlers/admin.js.map +1 -0
  70. package/dist/lib/server/handlers/identity.d.ts +36 -0
  71. package/dist/lib/server/handlers/identity.d.ts.map +1 -0
  72. package/dist/lib/server/handlers/identity.js +330 -0
  73. package/dist/lib/server/handlers/identity.js.map +1 -0
  74. package/dist/lib/server/handlers/index.d.ts +10 -0
  75. package/dist/lib/server/handlers/index.d.ts.map +1 -0
  76. package/dist/lib/server/handlers/index.js +15 -0
  77. package/dist/lib/server/handlers/index.js.map +1 -0
  78. package/dist/lib/server/handlers/message.d.ts +47 -0
  79. package/dist/lib/server/handlers/message.d.ts.map +1 -0
  80. package/dist/lib/server/handlers/message.js +265 -0
  81. package/dist/lib/server/handlers/message.js.map +1 -0
  82. package/dist/lib/server/handlers/presence.d.ts +18 -0
  83. package/dist/lib/server/handlers/presence.d.ts.map +1 -0
  84. package/dist/lib/server/handlers/presence.js +35 -0
  85. package/dist/lib/server/handlers/presence.js.map +1 -0
  86. package/dist/lib/server/handlers/proposal.d.ts +38 -0
  87. package/dist/lib/server/handlers/proposal.d.ts.map +1 -0
  88. package/dist/lib/server/handlers/proposal.js +273 -0
  89. package/dist/lib/server/handlers/proposal.js.map +1 -0
  90. package/dist/lib/server/handlers/skills.d.ts +22 -0
  91. package/dist/lib/server/handlers/skills.d.ts.map +1 -0
  92. package/dist/lib/server/handlers/skills.js +119 -0
  93. package/dist/lib/server/handlers/skills.js.map +1 -0
  94. package/dist/lib/server-directory.d.ts +85 -0
  95. package/dist/lib/server-directory.d.ts.map +1 -0
  96. package/dist/lib/server-directory.js +177 -0
  97. package/dist/lib/server-directory.js.map +1 -0
  98. package/dist/lib/server.d.ts +162 -0
  99. package/dist/lib/server.d.ts.map +1 -0
  100. package/dist/lib/server.js +602 -0
  101. package/dist/lib/server.js.map +1 -0
  102. package/dist/lib/types.d.ts +461 -0
  103. package/dist/lib/types.d.ts.map +1 -0
  104. package/dist/lib/types.js +98 -0
  105. package/dist/lib/types.js.map +1 -0
  106. package/package.json +22 -13
  107. package/bin/agentchat.js +0 -1617
  108. package/bin/agentchat.ts +0 -1812
  109. package/lib/allowlist.js +0 -162
  110. package/lib/chat.py +0 -241
  111. package/lib/client.js +0 -821
  112. package/lib/client.ts +0 -877
  113. package/lib/daemon.js +0 -562
  114. package/lib/daemon.ts +0 -662
  115. package/lib/deploy/akash.js +0 -811
  116. package/lib/deploy/config.js +0 -128
  117. package/lib/deploy/docker.js +0 -132
  118. package/lib/deploy/index.js +0 -24
  119. package/lib/elo_swarm.py +0 -569
  120. package/lib/escrow-hooks.js +0 -237
  121. package/lib/escrow-hooks.ts +0 -391
  122. package/lib/identity.js +0 -376
  123. package/lib/identity.ts +0 -412
  124. package/lib/jitter.js +0 -54
  125. package/lib/proposals.js +0 -426
  126. package/lib/proposals.ts +0 -612
  127. package/lib/protocol.js +0 -516
  128. package/lib/receipts.js +0 -294
  129. package/lib/receipts.ts +0 -359
  130. package/lib/reputation.js +0 -664
  131. package/lib/reputation.ts +0 -790
  132. package/lib/security.js +0 -183
  133. package/lib/server/handlers/admin.js +0 -94
  134. package/lib/server/handlers/identity.js +0 -258
  135. package/lib/server/handlers/index.js +0 -42
  136. package/lib/server/handlers/message.js +0 -319
  137. package/lib/server/handlers/presence.js +0 -45
  138. package/lib/server/handlers/proposal.js +0 -358
  139. package/lib/server/handlers/skills.js +0 -141
  140. package/lib/server-directory.js +0 -190
  141. package/lib/server-directory.ts +0 -232
  142. package/lib/server.js +0 -633
  143. package/lib/server.ts +0 -698
  144. package/lib/supervisor/USAGE.md +0 -110
  145. package/lib/supervisor/agent-health.sh +0 -107
  146. package/lib/supervisor/agent-monitor.sh +0 -123
  147. package/lib/supervisor/agent-supervisor.sh +0 -135
  148. package/lib/supervisor/agentctl.sh +0 -266
  149. package/lib/supervisor/god-backup.sh +0 -126
  150. package/lib/supervisor/god-watchdog.sh +0 -107
  151. package/lib/supervisor/killswitch.sh +0 -43
  152. package/lib/supervisor/notify.sh +0 -19
  153. package/lib/types.ts +0 -433
@@ -0,0 +1,334 @@
1
+ /**
2
+ * AgentChat Identity Module
3
+ * Ed25519 key generation, storage, and signing
4
+ */
5
+ import crypto from 'crypto';
6
+ import fs from 'fs/promises';
7
+ import path from 'path';
8
+ // Default identity file location
9
+ export const DEFAULT_IDENTITY_PATH = path.join(process.cwd(), '.agentchat', 'identity.json');
10
+ /**
11
+ * Generate stable agent ID from pubkey
12
+ * Returns first 8 chars of SHA256 hash (hex)
13
+ */
14
+ export function pubkeyToAgentId(pubkey) {
15
+ const hash = crypto.createHash('sha256').update(pubkey).digest('hex');
16
+ return hash.substring(0, 8);
17
+ }
18
+ /**
19
+ * Validate Ed25519 public key in PEM format
20
+ */
21
+ export function isValidPubkey(pubkey) {
22
+ if (!pubkey || typeof pubkey !== 'string')
23
+ return false;
24
+ try {
25
+ const keyObj = crypto.createPublicKey(pubkey);
26
+ return keyObj.asymmetricKeyType === 'ed25519';
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ /**
33
+ * AgentChat Identity
34
+ * Represents an agent's Ed25519 keypair and associated metadata
35
+ */
36
+ export class Identity {
37
+ name;
38
+ pubkey;
39
+ privkey;
40
+ created;
41
+ rotations;
42
+ // Lazy-load crypto key objects
43
+ _publicKey = null;
44
+ _privateKey = null;
45
+ constructor(data) {
46
+ this.name = data.name;
47
+ this.pubkey = data.pubkey;
48
+ this.privkey = data.privkey || null;
49
+ this.created = data.created;
50
+ this.rotations = data.rotations || [];
51
+ }
52
+ /**
53
+ * Generate new Ed25519 keypair
54
+ */
55
+ static generate(name) {
56
+ const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519');
57
+ return new Identity({
58
+ name,
59
+ pubkey: publicKey.export({ type: 'spki', format: 'pem' }),
60
+ privkey: privateKey.export({ type: 'pkcs8', format: 'pem' }),
61
+ created: new Date().toISOString()
62
+ });
63
+ }
64
+ /**
65
+ * Load identity from JSON file
66
+ */
67
+ static async load(filePath = DEFAULT_IDENTITY_PATH) {
68
+ const data = await fs.readFile(filePath, 'utf-8');
69
+ const parsed = JSON.parse(data);
70
+ // Handle both old format (publicKey/privateKey) and new format (pubkey/privkey)
71
+ return new Identity({
72
+ name: parsed.name,
73
+ pubkey: parsed.pubkey || parsed.publicKey,
74
+ privkey: parsed.privkey || parsed.privateKey,
75
+ created: parsed.created,
76
+ rotations: parsed.rotations
77
+ });
78
+ }
79
+ /**
80
+ * Save identity to JSON file
81
+ */
82
+ async save(filePath = DEFAULT_IDENTITY_PATH) {
83
+ // Ensure directory exists
84
+ const dir = path.dirname(filePath);
85
+ await fs.mkdir(dir, { recursive: true });
86
+ const data = {
87
+ publicKey: this.pubkey,
88
+ privateKey: this.privkey || '',
89
+ agentId: this.getAgentId(),
90
+ name: this.name,
91
+ created: this.created,
92
+ rotations: this.rotations.length > 0 ? this.rotations : undefined
93
+ };
94
+ await fs.writeFile(filePath, JSON.stringify(data, null, 2), {
95
+ mode: 0o600 // Owner read/write only
96
+ });
97
+ }
98
+ /**
99
+ * Check if identity file exists
100
+ */
101
+ static async exists(filePath = DEFAULT_IDENTITY_PATH) {
102
+ try {
103
+ await fs.access(filePath);
104
+ return true;
105
+ }
106
+ catch {
107
+ return false;
108
+ }
109
+ }
110
+ /**
111
+ * Get fingerprint (first 16 chars of SHA256 hash of pubkey)
112
+ */
113
+ getFingerprint() {
114
+ const hash = crypto.createHash('sha256').update(this.pubkey).digest('hex');
115
+ return hash.substring(0, 16);
116
+ }
117
+ /**
118
+ * Get stable agent ID (first 8 chars of fingerprint)
119
+ */
120
+ getAgentId() {
121
+ return pubkeyToAgentId(this.pubkey);
122
+ }
123
+ /**
124
+ * Sign data with private key
125
+ * Returns base64-encoded signature
126
+ */
127
+ sign(data) {
128
+ if (!this.privkey) {
129
+ throw new Error('Private key not available (identity was loaded from export)');
130
+ }
131
+ if (!this._privateKey) {
132
+ this._privateKey = crypto.createPrivateKey(this.privkey);
133
+ }
134
+ const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
135
+ const signature = crypto.sign(null, buffer, this._privateKey);
136
+ return signature.toString('base64');
137
+ }
138
+ /**
139
+ * Verify a signature
140
+ * Static method for verifying any message
141
+ */
142
+ static verify(data, signature, pubkey) {
143
+ try {
144
+ const keyObj = crypto.createPublicKey(pubkey);
145
+ const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
146
+ const sigBuffer = Buffer.from(signature, 'base64');
147
+ return crypto.verify(null, buffer, keyObj, sigBuffer);
148
+ }
149
+ catch {
150
+ return false;
151
+ }
152
+ }
153
+ /**
154
+ * Export for sharing (pubkey only, no private key)
155
+ */
156
+ export() {
157
+ return {
158
+ name: this.name,
159
+ pubkey: this.pubkey,
160
+ created: this.created,
161
+ rotations: this.rotations
162
+ };
163
+ }
164
+ /**
165
+ * Rotate to a new keypair
166
+ * Signs the new public key with the old private key for chain of custody
167
+ * @returns Rotation record with old_pubkey, new_pubkey, signature, timestamp
168
+ */
169
+ rotate() {
170
+ if (!this.privkey) {
171
+ throw new Error('Private key not available - cannot rotate');
172
+ }
173
+ // Generate new keypair
174
+ const { publicKey, privateKey } = crypto.generateKeyPairSync('ed25519');
175
+ const newPubkey = publicKey.export({ type: 'spki', format: 'pem' });
176
+ const newPrivkey = privateKey.export({ type: 'pkcs8', format: 'pem' });
177
+ // Use same timestamp for both signing and record
178
+ const timestamp = new Date().toISOString();
179
+ // Create rotation record content to sign
180
+ const rotationContent = JSON.stringify({
181
+ old_pubkey: this.pubkey,
182
+ new_pubkey: newPubkey,
183
+ timestamp
184
+ });
185
+ // Sign with old private key
186
+ const signature = this.sign(rotationContent);
187
+ // Create rotation record
188
+ const rotationRecord = {
189
+ old_pubkey: this.pubkey,
190
+ old_agent_id: this.getAgentId(),
191
+ new_pubkey: newPubkey,
192
+ new_agent_id: pubkeyToAgentId(newPubkey),
193
+ signature,
194
+ timestamp
195
+ };
196
+ // Update identity with new keys
197
+ this.rotations.push(rotationRecord);
198
+ this.pubkey = newPubkey;
199
+ this.privkey = newPrivkey;
200
+ this._publicKey = null;
201
+ this._privateKey = null;
202
+ return rotationRecord;
203
+ }
204
+ /**
205
+ * Verify a rotation record
206
+ * Checks that the signature is valid using the old public key
207
+ */
208
+ static verifyRotation(record) {
209
+ try {
210
+ const rotationContent = JSON.stringify({
211
+ old_pubkey: record.old_pubkey,
212
+ new_pubkey: record.new_pubkey,
213
+ timestamp: record.timestamp
214
+ });
215
+ return Identity.verify(rotationContent, record.signature, record.old_pubkey);
216
+ }
217
+ catch {
218
+ return false;
219
+ }
220
+ }
221
+ /**
222
+ * Verify the entire rotation chain
223
+ */
224
+ verifyRotationChain() {
225
+ const errors = [];
226
+ if (this.rotations.length === 0) {
227
+ return { valid: true, errors: [] };
228
+ }
229
+ // Verify each rotation in sequence
230
+ for (let i = 0; i < this.rotations.length; i++) {
231
+ const record = this.rotations[i];
232
+ // Verify signature
233
+ if (!Identity.verifyRotation(record)) {
234
+ errors.push(`Rotation ${i + 1}: Invalid signature`);
235
+ continue;
236
+ }
237
+ // Verify chain continuity (each new_pubkey should match next old_pubkey)
238
+ if (i < this.rotations.length - 1) {
239
+ const nextRecord = this.rotations[i + 1];
240
+ if (record.new_pubkey !== nextRecord.old_pubkey) {
241
+ errors.push(`Rotation ${i + 1}: Chain break - new_pubkey doesn't match next old_pubkey`);
242
+ }
243
+ }
244
+ }
245
+ // Verify final pubkey matches current identity
246
+ const lastRotation = this.rotations[this.rotations.length - 1];
247
+ if (lastRotation.new_pubkey !== this.pubkey) {
248
+ errors.push('Final rotation new_pubkey does not match current identity pubkey');
249
+ }
250
+ return {
251
+ valid: errors.length === 0,
252
+ errors
253
+ };
254
+ }
255
+ /**
256
+ * Get the original (genesis) public key before any rotations
257
+ */
258
+ getOriginalPubkey() {
259
+ if (this.rotations.length === 0) {
260
+ return this.pubkey;
261
+ }
262
+ return this.rotations[0].old_pubkey;
263
+ }
264
+ /**
265
+ * Get the original (genesis) agent ID
266
+ */
267
+ getOriginalAgentId() {
268
+ return pubkeyToAgentId(this.getOriginalPubkey());
269
+ }
270
+ /**
271
+ * Generate a signed revocation notice for this identity
272
+ * A revocation notice declares that the key should no longer be trusted
273
+ */
274
+ revoke(reason = 'revoked') {
275
+ if (!this.privkey) {
276
+ throw new Error('Private key not available - cannot create revocation notice');
277
+ }
278
+ const timestamp = new Date().toISOString();
279
+ // Create revocation content to sign
280
+ const revocationContent = JSON.stringify({
281
+ type: 'REVOCATION',
282
+ pubkey: this.pubkey,
283
+ agent_id: this.getAgentId(),
284
+ reason,
285
+ timestamp
286
+ });
287
+ // Sign with the key being revoked (proves ownership)
288
+ const signature = this.sign(revocationContent);
289
+ const notice = {
290
+ type: 'REVOCATION',
291
+ pubkey: this.pubkey,
292
+ agent_id: this.getAgentId(),
293
+ fingerprint: this.getFingerprint(),
294
+ reason,
295
+ timestamp,
296
+ signature,
297
+ rotations: this.rotations.length > 0 ? this.rotations : undefined,
298
+ original_agent_id: this.rotations.length > 0 ? this.getOriginalAgentId() : undefined
299
+ };
300
+ return notice;
301
+ }
302
+ /**
303
+ * Verify a revocation notice
304
+ * Checks that the signature is valid using the pubkey in the notice
305
+ */
306
+ static verifyRevocation(notice) {
307
+ if (!notice || notice.type !== 'REVOCATION') {
308
+ return false;
309
+ }
310
+ try {
311
+ const revocationContent = JSON.stringify({
312
+ type: 'REVOCATION',
313
+ pubkey: notice.pubkey,
314
+ agent_id: notice.agent_id,
315
+ reason: notice.reason,
316
+ timestamp: notice.timestamp
317
+ });
318
+ return Identity.verify(revocationContent, notice.signature, notice.pubkey);
319
+ }
320
+ catch {
321
+ return false;
322
+ }
323
+ }
324
+ /**
325
+ * Check if a pubkey has been revoked by checking against a revocation notice
326
+ */
327
+ static isRevoked(pubkey, notice) {
328
+ if (!Identity.verifyRevocation(notice)) {
329
+ return false;
330
+ }
331
+ return notice.pubkey === pubkey;
332
+ }
333
+ }
334
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../lib/identity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Jitter utilities for preventing thundering herd and deadlock in distributed systems
3
+ */
4
+ /**
5
+ * Add jitter to a timeout value to prevent thundering herd / deadlock
6
+ * When multiple agents use the same timeout, they all wake up at once.
7
+ * Adding jitter spreads out the wakeups, breaking symmetry.
8
+ *
9
+ * @param baseMs - Base timeout in milliseconds
10
+ * @param jitterPercent - Jitter percentage (0.0 to 1.0), default 0.2 (20%)
11
+ * @returns Jittered timeout value (minimum 100ms)
12
+ *
13
+ * @example
14
+ * // With 20% jitter, a 10000ms timeout becomes 8000-12000ms
15
+ * addJitter(10000, 0.2) // Returns value between 8000 and 12000
16
+ *
17
+ * @example
18
+ * // Prevent deadlock in listen loops
19
+ * const timeout = addJitter(60000, 0.2); // 48-72 seconds
20
+ * setTimeout(checkForMessages, timeout);
21
+ */
22
+ export declare function addJitter(baseMs: number, jitterPercent?: number): number;
23
+ /**
24
+ * Calculate exponential backoff with jitter
25
+ * Useful for reconnection attempts
26
+ *
27
+ * @param attempt - Current attempt number (0-based)
28
+ * @param baseMs - Base delay in milliseconds (default 1000)
29
+ * @param maxMs - Maximum delay cap (default 60000)
30
+ * @param jitterPercent - Jitter percentage (default 0.2)
31
+ * @returns Delay with exponential backoff and jitter
32
+ *
33
+ * @example
34
+ * // Reconnection with backoff
35
+ * let attempt = 0;
36
+ * function reconnect() {
37
+ * const delay = exponentialBackoffWithJitter(attempt++);
38
+ * setTimeout(doReconnect, delay);
39
+ * }
40
+ */
41
+ export declare function exponentialBackoffWithJitter(attempt: number, baseMs?: number, maxMs?: number, jitterPercent?: number): number;
42
+ //# sourceMappingURL=jitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jitter.d.ts","sourceRoot":"","sources":["../../lib/jitter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,GAAE,MAAY,GAAG,MAAM,CAQ7E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,MAAM,GAAE,MAAa,EACrB,KAAK,GAAE,MAAc,EACrB,aAAa,GAAE,MAAY,GAC1B,MAAM,CAGR"}
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Jitter utilities for preventing thundering herd and deadlock in distributed systems
3
3
  */
4
-
5
4
  /**
6
5
  * Add jitter to a timeout value to prevent thundering herd / deadlock
7
6
  * When multiple agents use the same timeout, they all wake up at once.
@@ -20,16 +19,13 @@
20
19
  * const timeout = addJitter(60000, 0.2); // 48-72 seconds
21
20
  * setTimeout(checkForMessages, timeout);
22
21
  */
23
- export function addJitter(baseMs: number, jitterPercent: number = 0.2): number {
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
22
+ export function addJitter(baseMs, jitterPercent = 0.2) {
23
+ // Clamp jitter percent to valid range
24
+ const clampedJitter = Math.max(0, Math.min(1, jitterPercent));
25
+ const jitterAmount = baseMs * clampedJitter;
26
+ const jitter = (Math.random() - 0.5) * 2 * jitterAmount; // +/- jitterAmount
27
+ return Math.max(100, Math.round(baseMs + jitter)); // Min 100ms
31
28
  }
32
-
33
29
  /**
34
30
  * Calculate exponential backoff with jitter
35
31
  * Useful for reconnection attempts
@@ -48,12 +44,8 @@ export function addJitter(baseMs: number, jitterPercent: number = 0.2): number {
48
44
  * setTimeout(doReconnect, delay);
49
45
  * }
50
46
  */
51
- export function exponentialBackoffWithJitter(
52
- attempt: number,
53
- baseMs: number = 1000,
54
- maxMs: number = 60000,
55
- jitterPercent: number = 0.2
56
- ): number {
57
- const exponentialDelay = Math.min(baseMs * Math.pow(2, attempt), maxMs);
58
- return addJitter(exponentialDelay, jitterPercent);
47
+ export function exponentialBackoffWithJitter(attempt, baseMs = 1000, maxMs = 60000, jitterPercent = 0.2) {
48
+ const exponentialDelay = Math.min(baseMs * Math.pow(2, attempt), maxMs);
49
+ return addJitter(exponentialDelay, jitterPercent);
59
50
  }
51
+ //# sourceMappingURL=jitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jitter.js","sourceRoot":"","sources":["../../lib/jitter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,gBAAwB,GAAG;IACnE,sCAAsC;IACtC,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC;IAE9D,MAAM,YAAY,GAAG,MAAM,GAAG,aAAa,CAAC;IAC5C,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,CAAC,mBAAmB;IAE5E,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY;AACjE,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,4BAA4B,CAC1C,OAAe,EACf,SAAiB,IAAI,EACrB,QAAgB,KAAK,EACrB,gBAAwB,GAAG;IAE3B,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;IACxE,OAAO,SAAS,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * AgentChat Proposals Module
3
+ * Handles structured negotiation between agents
4
+ *
5
+ * Proposals enable agents to make verifiable, signed commitments
6
+ * for work, services, or payments.
7
+ */
8
+ export interface ProposalInput {
9
+ id?: string;
10
+ from: string;
11
+ to: string;
12
+ task: string;
13
+ amount?: number | null;
14
+ currency?: string | null;
15
+ payment_code?: string | null;
16
+ terms?: string | null;
17
+ expires?: number | null;
18
+ sig: string;
19
+ elo_stake?: number | null;
20
+ }
21
+ export interface StoredProposal {
22
+ id: string;
23
+ from: string;
24
+ to: string;
25
+ task: string;
26
+ amount: number | null;
27
+ currency: string | null;
28
+ payment_code: string | null;
29
+ terms: string | null;
30
+ expires: number | null;
31
+ status: string;
32
+ created_at: number;
33
+ updated_at: number;
34
+ sig: string;
35
+ proposer_stake: number | null;
36
+ acceptor_stake: number | null;
37
+ stakes_escrowed: boolean;
38
+ response_sig: string | null;
39
+ response_payment_code: string | null;
40
+ completed_at: number | null;
41
+ completion_proof: string | null;
42
+ dispute_reason: string | null;
43
+ reject_reason?: string | null;
44
+ completion_sig?: string;
45
+ completed_by?: string;
46
+ dispute_sig?: string;
47
+ disputed_by?: string;
48
+ disputed_at?: number;
49
+ }
50
+ export interface ProposalResult {
51
+ proposal?: StoredProposal;
52
+ error?: string;
53
+ status?: string;
54
+ }
55
+ export interface ListOptions {
56
+ status?: string;
57
+ role?: 'from' | 'to';
58
+ limit?: number;
59
+ }
60
+ export interface ProposalStats {
61
+ total: number;
62
+ byStatus: Record<string, number>;
63
+ agents: number;
64
+ }
65
+ export interface FormattedProposal {
66
+ id: string;
67
+ from: string;
68
+ to: string;
69
+ task: string;
70
+ amount: number | null;
71
+ currency: string | null;
72
+ payment_code: string | null;
73
+ terms: string | null;
74
+ expires: number | null;
75
+ status: string;
76
+ created_at: number;
77
+ sig: string;
78
+ elo_stake: number | null;
79
+ }
80
+ export interface ProposalResponseBase {
81
+ proposal_id: string;
82
+ status: string;
83
+ updated_at: number;
84
+ }
85
+ export interface AcceptResponse extends ProposalResponseBase {
86
+ from: string;
87
+ to: string;
88
+ payment_code: string | null;
89
+ sig: string | null;
90
+ proposer_stake: number | null;
91
+ acceptor_stake: number | null;
92
+ }
93
+ export interface RejectResponse extends ProposalResponseBase {
94
+ from: string;
95
+ to: string;
96
+ reason: string | null | undefined;
97
+ sig: string | null;
98
+ }
99
+ export interface CompleteResponse extends ProposalResponseBase {
100
+ from: string;
101
+ to: string;
102
+ completed_by: string | undefined;
103
+ completed_at: number | null;
104
+ proof: string | null;
105
+ sig: string | undefined;
106
+ elo_stakes: {
107
+ proposer: number;
108
+ acceptor: number;
109
+ };
110
+ }
111
+ export interface DisputeResponse extends ProposalResponseBase {
112
+ from: string;
113
+ to: string;
114
+ disputed_by: string | undefined;
115
+ disputed_at: number | undefined;
116
+ reason: string | null;
117
+ sig: string | undefined;
118
+ elo_stakes: {
119
+ proposer: number;
120
+ acceptor: number;
121
+ };
122
+ }
123
+ export type ProposalResponse = AcceptResponse | RejectResponse | CompleteResponse | DisputeResponse | ProposalResponseBase;
124
+ /**
125
+ * In-memory proposal store
126
+ * In production, this could be backed by persistence
127
+ */
128
+ export declare class ProposalStore {
129
+ private proposals;
130
+ private byAgent;
131
+ private cleanupInterval;
132
+ constructor();
133
+ /**
134
+ * Create a new proposal
135
+ */
136
+ create(proposal: ProposalInput): StoredProposal;
137
+ /**
138
+ * Get a proposal by ID
139
+ */
140
+ get(id: string): StoredProposal | null;
141
+ /**
142
+ * Accept a proposal
143
+ * @param id - Proposal ID
144
+ * @param acceptorId - Agent accepting the proposal
145
+ * @param sig - Signature of acceptance
146
+ * @param payment_code - Optional payment code
147
+ * @param acceptor_stake - Optional ELO stake from acceptor
148
+ */
149
+ accept(id: string, acceptorId: string, sig: string, payment_code?: string | null, acceptor_stake?: number | null): ProposalResult;
150
+ /**
151
+ * Reject a proposal
152
+ */
153
+ reject(id: string, rejectorId: string, sig: string, reason?: string | null): ProposalResult;
154
+ /**
155
+ * Mark a proposal as complete
156
+ */
157
+ complete(id: string, completerId: string, sig: string, proof?: string | null): ProposalResult;
158
+ /**
159
+ * Dispute a proposal
160
+ */
161
+ dispute(id: string, disputerId: string, sig: string, reason: string): ProposalResult;
162
+ /**
163
+ * List proposals for an agent
164
+ */
165
+ listByAgent(agentId: string, options?: ListOptions): StoredProposal[];
166
+ /**
167
+ * Index a proposal by agent
168
+ */
169
+ private _indexAgent;
170
+ /**
171
+ * Clean up expired proposals (older than 24 hours after expiration)
172
+ */
173
+ cleanupExpired(): void;
174
+ /**
175
+ * Stop the cleanup interval
176
+ */
177
+ close(): void;
178
+ /**
179
+ * Get stats about the proposal store
180
+ */
181
+ stats(): ProposalStats;
182
+ }
183
+ /**
184
+ * Format a proposal for display/transmission
185
+ */
186
+ export declare function formatProposal(proposal: StoredProposal): FormattedProposal;
187
+ /**
188
+ * Format a proposal response (accept/reject/complete/dispute)
189
+ */
190
+ export declare function formatProposalResponse(proposal: StoredProposal, responseType: 'accept' | 'reject' | 'complete' | 'dispute' | string): ProposalResponse;
191
+ /**
192
+ * Create proposal content string for signing
193
+ * This ensures both parties sign the same canonical data
194
+ */
195
+ export declare function getProposalSigningContent(proposal: {
196
+ to: string;
197
+ task: string;
198
+ amount?: number | null;
199
+ currency?: string | null;
200
+ payment_code?: string | null;
201
+ expires?: number | null;
202
+ elo_stake?: number | null;
203
+ }): string;
204
+ /**
205
+ * Create accept content string for signing
206
+ * @param proposalId - The proposal being accepted
207
+ * @param payment_code - Optional payment code
208
+ * @param elo_stake - Optional ELO stake from acceptor
209
+ */
210
+ export declare function getAcceptSigningContent(proposalId: string, payment_code?: string, elo_stake?: string | number): string;
211
+ /**
212
+ * Create reject content string for signing
213
+ */
214
+ export declare function getRejectSigningContent(proposalId: string, reason?: string): string;
215
+ /**
216
+ * Create complete content string for signing
217
+ */
218
+ export declare function getCompleteSigningContent(proposalId: string, proof?: string): string;
219
+ /**
220
+ * Create dispute content string for signing
221
+ */
222
+ export declare function getDisputeSigningContent(proposalId: string, reason: string): string;
223
+ //# sourceMappingURL=proposals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proposals.d.ts","sourceRoot":"","sources":["../../lib/proposals.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAe,SAAQ,oBAAoB;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAe,SAAQ,oBAAoB;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,MAAM,WAAW,gBAAiB,SAAQ,oBAAoB;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,eAAgB,SAAQ,oBAAoB;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,UAAU,EAAE;QACV,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,MAAM,gBAAgB,GAAG,cAAc,GAAG,cAAc,GAAG,gBAAgB,GAAG,eAAe,GAAG,oBAAoB,CAAC;AAI3H;;;GAGG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,eAAe,CAAwC;;IAa/D;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,aAAa,GAAG,cAAc;IAuC/C;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAetC;;;;;;;OAOG;IACH,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,YAAY,GAAE,MAAM,GAAG,IAAW,EAClC,cAAc,GAAE,MAAM,GAAG,IAAW,GACnC,cAAc;IA6BjB;;OAEG;IACH,MAAM,CACJ,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,MAAM,GAAG,IAAW,GAC3B,cAAc;IAsBjB;;OAEG;IACH,QAAQ,CACN,EAAE,EAAE,MAAM,EACV,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EACX,KAAK,GAAE,MAAM,GAAG,IAAW,GAC1B,cAAc;IAyBjB;;OAEG;IACH,OAAO,CACL,EAAE,EAAE,MAAM,EACV,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,GACb,cAAc;IA0BjB;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,cAAc,EAAE;IA6BzE;;OAEG;IACH,OAAO,CAAC,WAAW;IAOnB;;OAEG;IACH,cAAc,IAAI,IAAI;IAiBtB;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,KAAK,IAAI,aAAa;CAYvB;AAID;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,cAAc,GAAG,iBAAiB,CAgB1E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAClE,gBAAgB,CA6DlB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE;IAClD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,MAAM,CAWT;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,YAAY,GAAE,MAAW,EACzB,SAAS,GAAE,MAAM,GAAG,MAAW,GAC9B,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAW,GAClB,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,KAAK,GAAE,MAAW,GACjB,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GACb,MAAM,CAER"}