@tjamescouch/agentchat 0.22.0 → 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 (135) 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 → dist/lib}/jitter.js +16 -19
  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/lib/chat.py +0 -241
  109. package/lib/client.js +0 -821
  110. package/lib/daemon.js +0 -562
  111. package/lib/deploy/akash.js +0 -811
  112. package/lib/deploy/config.js +0 -128
  113. package/lib/deploy/docker.js +0 -132
  114. package/lib/deploy/index.js +0 -24
  115. package/lib/elo_swarm.py +0 -569
  116. package/lib/escrow-hooks.js +0 -237
  117. package/lib/identity.js +0 -376
  118. package/lib/proposals.js +0 -426
  119. package/lib/protocol.js +0 -484
  120. package/lib/receipts.js +0 -294
  121. package/lib/reputation.js +0 -664
  122. package/lib/security.js +0 -183
  123. package/lib/server/handlers/identity.js +0 -242
  124. package/lib/server/handlers/index.js +0 -42
  125. package/lib/server/handlers/message.js +0 -306
  126. package/lib/server/handlers/presence.js +0 -44
  127. package/lib/server/handlers/proposal.js +0 -358
  128. package/lib/server/handlers/skills.js +0 -141
  129. package/lib/server-directory.js +0 -181
  130. package/lib/server.js +0 -528
  131. package/lib/supervisor/USAGE.md +0 -110
  132. package/lib/supervisor/agent-supervisor.sh +0 -135
  133. package/lib/supervisor/agentctl.sh +0 -250
  134. package/lib/supervisor/killswitch.sh +0 -36
  135. package/lib/supervisor/notify.sh +0 -19
package/lib/proposals.js DELETED
@@ -1,426 +0,0 @@
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
-
9
- import { generateProposalId, ProposalStatus } from './protocol.js';
10
-
11
- /**
12
- * In-memory proposal store
13
- * In production, this could be backed by persistence
14
- */
15
- export class ProposalStore {
16
- constructor() {
17
- // Map of proposal_id -> proposal object
18
- this.proposals = new Map();
19
-
20
- // Index by agent for quick lookups
21
- this.byAgent = new Map(); // agent_id -> Set of proposal_ids
22
-
23
- // Cleanup expired proposals periodically
24
- this.cleanupInterval = setInterval(() => this.cleanupExpired(), 60000);
25
- }
26
-
27
- /**
28
- * Create a new proposal
29
- */
30
- create(proposal) {
31
- const id = proposal.id || generateProposalId();
32
- const now = Date.now();
33
-
34
- const stored = {
35
- id,
36
- from: proposal.from,
37
- to: proposal.to,
38
- task: proposal.task,
39
- amount: proposal.amount || null,
40
- currency: proposal.currency || null,
41
- payment_code: proposal.payment_code || null,
42
- terms: proposal.terms || null,
43
- expires: proposal.expires ? now + (proposal.expires * 1000) : null,
44
- status: ProposalStatus.PENDING,
45
- created_at: now,
46
- updated_at: now,
47
- sig: proposal.sig,
48
- // ELO staking
49
- proposer_stake: proposal.elo_stake || null,
50
- acceptor_stake: null,
51
- stakes_escrowed: false,
52
- // Response tracking
53
- response_sig: null,
54
- response_payment_code: null,
55
- completed_at: null,
56
- completion_proof: null,
57
- dispute_reason: null
58
- };
59
-
60
- this.proposals.set(id, stored);
61
-
62
- // Index by both agents
63
- this._indexAgent(proposal.from, id);
64
- this._indexAgent(proposal.to, id);
65
-
66
- return stored;
67
- }
68
-
69
- /**
70
- * Get a proposal by ID
71
- */
72
- get(id) {
73
- const proposal = this.proposals.get(id);
74
- if (!proposal) return null;
75
-
76
- // Check expiration
77
- if (proposal.expires && Date.now() > proposal.expires) {
78
- if (proposal.status === ProposalStatus.PENDING) {
79
- proposal.status = ProposalStatus.EXPIRED;
80
- proposal.updated_at = Date.now();
81
- }
82
- }
83
-
84
- return proposal;
85
- }
86
-
87
- /**
88
- * Accept a proposal
89
- * @param {string} id - Proposal ID
90
- * @param {string} acceptorId - Agent accepting the proposal
91
- * @param {string} sig - Signature of acceptance
92
- * @param {string} payment_code - Optional payment code
93
- * @param {number} acceptor_stake - Optional ELO stake from acceptor
94
- */
95
- accept(id, acceptorId, sig, payment_code = null, acceptor_stake = null) {
96
- const proposal = this.get(id);
97
- if (!proposal) {
98
- return { error: 'PROPOSAL_NOT_FOUND' };
99
- }
100
-
101
- if (proposal.status !== ProposalStatus.PENDING) {
102
- return { error: 'PROPOSAL_NOT_PENDING', status: proposal.status };
103
- }
104
-
105
- if (proposal.to !== acceptorId) {
106
- return { error: 'NOT_PROPOSAL_RECIPIENT' };
107
- }
108
-
109
- if (proposal.expires && Date.now() > proposal.expires) {
110
- proposal.status = ProposalStatus.EXPIRED;
111
- proposal.updated_at = Date.now();
112
- return { error: 'PROPOSAL_EXPIRED' };
113
- }
114
-
115
- proposal.status = ProposalStatus.ACCEPTED;
116
- proposal.response_sig = sig;
117
- proposal.response_payment_code = payment_code;
118
- proposal.acceptor_stake = acceptor_stake;
119
- proposal.updated_at = Date.now();
120
-
121
- return { proposal };
122
- }
123
-
124
- /**
125
- * Reject a proposal
126
- */
127
- reject(id, rejectorId, sig, reason = null) {
128
- const proposal = this.get(id);
129
- if (!proposal) {
130
- return { error: 'PROPOSAL_NOT_FOUND' };
131
- }
132
-
133
- if (proposal.status !== ProposalStatus.PENDING) {
134
- return { error: 'PROPOSAL_NOT_PENDING', status: proposal.status };
135
- }
136
-
137
- if (proposal.to !== rejectorId) {
138
- return { error: 'NOT_PROPOSAL_RECIPIENT' };
139
- }
140
-
141
- proposal.status = ProposalStatus.REJECTED;
142
- proposal.response_sig = sig;
143
- proposal.reject_reason = reason;
144
- proposal.updated_at = Date.now();
145
-
146
- return { proposal };
147
- }
148
-
149
- /**
150
- * Mark a proposal as complete
151
- */
152
- complete(id, completerId, sig, proof = null) {
153
- const proposal = this.get(id);
154
- if (!proposal) {
155
- return { error: 'PROPOSAL_NOT_FOUND' };
156
- }
157
-
158
- if (proposal.status !== ProposalStatus.ACCEPTED) {
159
- return { error: 'PROPOSAL_NOT_ACCEPTED', status: proposal.status };
160
- }
161
-
162
- // Either party can mark as complete
163
- if (proposal.from !== completerId && proposal.to !== completerId) {
164
- return { error: 'NOT_PROPOSAL_PARTY' };
165
- }
166
-
167
- proposal.status = ProposalStatus.COMPLETED;
168
- proposal.completed_at = Date.now();
169
- proposal.completion_proof = proof;
170
- proposal.completion_sig = sig;
171
- proposal.completed_by = completerId;
172
- proposal.updated_at = Date.now();
173
-
174
- return { proposal };
175
- }
176
-
177
- /**
178
- * Dispute a proposal
179
- */
180
- dispute(id, disputerId, sig, reason) {
181
- const proposal = this.get(id);
182
- if (!proposal) {
183
- return { error: 'PROPOSAL_NOT_FOUND' };
184
- }
185
-
186
- // Can only dispute accepted proposals
187
- if (proposal.status !== ProposalStatus.ACCEPTED) {
188
- return { error: 'PROPOSAL_NOT_ACCEPTED', status: proposal.status };
189
- }
190
-
191
- // Either party can dispute
192
- if (proposal.from !== disputerId && proposal.to !== disputerId) {
193
- return { error: 'NOT_PROPOSAL_PARTY' };
194
- }
195
-
196
- proposal.status = ProposalStatus.DISPUTED;
197
- proposal.dispute_reason = reason;
198
- proposal.dispute_sig = sig;
199
- proposal.disputed_by = disputerId;
200
- proposal.disputed_at = Date.now();
201
- proposal.updated_at = Date.now();
202
-
203
- return { proposal };
204
- }
205
-
206
- /**
207
- * List proposals for an agent
208
- */
209
- listByAgent(agentId, options = {}) {
210
- const ids = this.byAgent.get(agentId) || new Set();
211
- let proposals = Array.from(ids).map(id => this.get(id)).filter(Boolean);
212
-
213
- // Filter by status
214
- if (options.status) {
215
- proposals = proposals.filter(p => p.status === options.status);
216
- }
217
-
218
- // Filter by role (from/to)
219
- if (options.role === 'from') {
220
- proposals = proposals.filter(p => p.from === agentId);
221
- } else if (options.role === 'to') {
222
- proposals = proposals.filter(p => p.to === agentId);
223
- }
224
-
225
- // Sort by created_at descending
226
- proposals.sort((a, b) => b.created_at - a.created_at);
227
-
228
- // Limit
229
- if (options.limit) {
230
- proposals = proposals.slice(0, options.limit);
231
- }
232
-
233
- return proposals;
234
- }
235
-
236
- /**
237
- * Index a proposal by agent
238
- */
239
- _indexAgent(agentId, proposalId) {
240
- if (!this.byAgent.has(agentId)) {
241
- this.byAgent.set(agentId, new Set());
242
- }
243
- this.byAgent.get(agentId).add(proposalId);
244
- }
245
-
246
- /**
247
- * Clean up expired proposals (older than 24 hours after expiration)
248
- */
249
- cleanupExpired() {
250
- const cutoff = Date.now() - (24 * 60 * 60 * 1000);
251
-
252
- for (const [id, proposal] of this.proposals) {
253
- if (proposal.expires && proposal.expires < cutoff) {
254
- this.proposals.delete(id);
255
-
256
- // Remove from agent indices
257
- const fromSet = this.byAgent.get(proposal.from);
258
- if (fromSet) fromSet.delete(id);
259
-
260
- const toSet = this.byAgent.get(proposal.to);
261
- if (toSet) toSet.delete(id);
262
- }
263
- }
264
- }
265
-
266
- /**
267
- * Stop the cleanup interval
268
- */
269
- close() {
270
- if (this.cleanupInterval) {
271
- clearInterval(this.cleanupInterval);
272
- this.cleanupInterval = null;
273
- }
274
- }
275
-
276
- /**
277
- * Get stats about the proposal store
278
- */
279
- stats() {
280
- const byStatus = {};
281
- for (const proposal of this.proposals.values()) {
282
- byStatus[proposal.status] = (byStatus[proposal.status] || 0) + 1;
283
- }
284
-
285
- return {
286
- total: this.proposals.size,
287
- byStatus,
288
- agents: this.byAgent.size
289
- };
290
- }
291
- }
292
-
293
- /**
294
- * Format a proposal for display/transmission
295
- */
296
- export function formatProposal(proposal) {
297
- return {
298
- id: proposal.id,
299
- from: proposal.from,
300
- to: proposal.to,
301
- task: proposal.task,
302
- amount: proposal.amount,
303
- currency: proposal.currency,
304
- payment_code: proposal.payment_code,
305
- terms: proposal.terms,
306
- expires: proposal.expires,
307
- status: proposal.status,
308
- created_at: proposal.created_at,
309
- sig: proposal.sig,
310
- elo_stake: proposal.proposer_stake
311
- };
312
- }
313
-
314
- /**
315
- * Format a proposal response (accept/reject/complete/dispute)
316
- */
317
- export function formatProposalResponse(proposal, responseType) {
318
- const base = {
319
- proposal_id: proposal.id,
320
- status: proposal.status,
321
- updated_at: proposal.updated_at
322
- };
323
-
324
- switch (responseType) {
325
- case 'accept':
326
- return {
327
- ...base,
328
- from: proposal.from,
329
- to: proposal.to,
330
- payment_code: proposal.response_payment_code,
331
- sig: proposal.response_sig,
332
- proposer_stake: proposal.proposer_stake,
333
- acceptor_stake: proposal.acceptor_stake
334
- };
335
-
336
- case 'reject':
337
- return {
338
- ...base,
339
- from: proposal.from,
340
- to: proposal.to,
341
- reason: proposal.reject_reason,
342
- sig: proposal.response_sig
343
- };
344
-
345
- case 'complete':
346
- return {
347
- ...base,
348
- from: proposal.from,
349
- to: proposal.to,
350
- completed_by: proposal.completed_by,
351
- completed_at: proposal.completed_at,
352
- proof: proposal.completion_proof,
353
- sig: proposal.completion_sig,
354
- elo_stakes: {
355
- proposer: proposal.proposer_stake || 0,
356
- acceptor: proposal.acceptor_stake || 0
357
- }
358
- };
359
-
360
- case 'dispute':
361
- return {
362
- ...base,
363
- from: proposal.from,
364
- to: proposal.to,
365
- disputed_by: proposal.disputed_by,
366
- disputed_at: proposal.disputed_at,
367
- reason: proposal.dispute_reason,
368
- sig: proposal.dispute_sig,
369
- elo_stakes: {
370
- proposer: proposal.proposer_stake || 0,
371
- acceptor: proposal.acceptor_stake || 0
372
- }
373
- };
374
-
375
- default:
376
- return base;
377
- }
378
- }
379
-
380
- /**
381
- * Create proposal content string for signing
382
- * This ensures both parties sign the same canonical data
383
- */
384
- export function getProposalSigningContent(proposal) {
385
- const fields = [
386
- proposal.to,
387
- proposal.task,
388
- proposal.amount || '',
389
- proposal.currency || '',
390
- proposal.payment_code || '',
391
- proposal.expires || '',
392
- proposal.elo_stake || ''
393
- ];
394
- return fields.join('|');
395
- }
396
-
397
- /**
398
- * Create accept content string for signing
399
- * @param {string} proposalId - The proposal being accepted
400
- * @param {string} payment_code - Optional payment code
401
- * @param {number} elo_stake - Optional ELO stake from acceptor
402
- */
403
- export function getAcceptSigningContent(proposalId, payment_code = '', elo_stake = '') {
404
- return `ACCEPT|${proposalId}|${payment_code}|${elo_stake}`;
405
- }
406
-
407
- /**
408
- * Create reject content string for signing
409
- */
410
- export function getRejectSigningContent(proposalId, reason = '') {
411
- return `REJECT|${proposalId}|${reason}`;
412
- }
413
-
414
- /**
415
- * Create complete content string for signing
416
- */
417
- export function getCompleteSigningContent(proposalId, proof = '') {
418
- return `COMPLETE|${proposalId}|${proof}`;
419
- }
420
-
421
- /**
422
- * Create dispute content string for signing
423
- */
424
- export function getDisputeSigningContent(proposalId, reason) {
425
- return `DISPUTE|${proposalId}|${reason}`;
426
- }