society-protocol 1.0.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 (271) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/dist/adapters.d.ts +101 -0
  4. package/dist/adapters.d.ts.map +1 -0
  5. package/dist/adapters.js +764 -0
  6. package/dist/adapters.js.map +1 -0
  7. package/dist/agents-md.d.ts +59 -0
  8. package/dist/agents-md.d.ts.map +1 -0
  9. package/dist/agents-md.js +204 -0
  10. package/dist/agents-md.js.map +1 -0
  11. package/dist/autoconfig.d.ts +137 -0
  12. package/dist/autoconfig.d.ts.map +1 -0
  13. package/dist/autoconfig.js +452 -0
  14. package/dist/autoconfig.js.map +1 -0
  15. package/dist/bootstrap.d.ts +68 -0
  16. package/dist/bootstrap.d.ts.map +1 -0
  17. package/dist/bootstrap.js +304 -0
  18. package/dist/bootstrap.js.map +1 -0
  19. package/dist/bridges/a2a-bridge.d.ts +156 -0
  20. package/dist/bridges/a2a-bridge.d.ts.map +1 -0
  21. package/dist/bridges/a2a-bridge.js +337 -0
  22. package/dist/bridges/a2a-bridge.js.map +1 -0
  23. package/dist/bridges/mcp-bridge.d.ts +87 -0
  24. package/dist/bridges/mcp-bridge.d.ts.map +1 -0
  25. package/dist/bridges/mcp-bridge.js +332 -0
  26. package/dist/bridges/mcp-bridge.js.map +1 -0
  27. package/dist/cache.d.ts +130 -0
  28. package/dist/cache.d.ts.map +1 -0
  29. package/dist/cache.js +257 -0
  30. package/dist/cache.js.map +1 -0
  31. package/dist/capsules.d.ts +23 -0
  32. package/dist/capsules.d.ts.map +1 -0
  33. package/dist/capsules.js +75 -0
  34. package/dist/capsules.js.map +1 -0
  35. package/dist/cli/commands.d.ts +8 -0
  36. package/dist/cli/commands.d.ts.map +1 -0
  37. package/dist/cli/commands.js +263 -0
  38. package/dist/cli/commands.js.map +1 -0
  39. package/dist/coc.d.ts +121 -0
  40. package/dist/coc.d.ts.map +1 -0
  41. package/dist/coc.js +629 -0
  42. package/dist/coc.js.map +1 -0
  43. package/dist/coc.test.d.ts +2 -0
  44. package/dist/coc.test.d.ts.map +1 -0
  45. package/dist/coc.test.js +80 -0
  46. package/dist/coc.test.js.map +1 -0
  47. package/dist/compression.d.ts +125 -0
  48. package/dist/compression.d.ts.map +1 -0
  49. package/dist/compression.js +573 -0
  50. package/dist/compression.js.map +1 -0
  51. package/dist/cot-stream.d.ts +220 -0
  52. package/dist/cot-stream.d.ts.map +1 -0
  53. package/dist/cot-stream.js +673 -0
  54. package/dist/cot-stream.js.map +1 -0
  55. package/dist/crypto-wasm.d.ts +100 -0
  56. package/dist/crypto-wasm.d.ts.map +1 -0
  57. package/dist/crypto-wasm.js +229 -0
  58. package/dist/crypto-wasm.js.map +1 -0
  59. package/dist/federation.d.ts +200 -0
  60. package/dist/federation.d.ts.map +1 -0
  61. package/dist/federation.js +691 -0
  62. package/dist/federation.js.map +1 -0
  63. package/dist/federation.test.d.ts +2 -0
  64. package/dist/federation.test.d.ts.map +1 -0
  65. package/dist/federation.test.js +71 -0
  66. package/dist/federation.test.js.map +1 -0
  67. package/dist/gateway/capability-router.d.ts +77 -0
  68. package/dist/gateway/capability-router.d.ts.map +1 -0
  69. package/dist/gateway/capability-router.js +222 -0
  70. package/dist/gateway/capability-router.js.map +1 -0
  71. package/dist/gateway/demand-spawner.d.ts +155 -0
  72. package/dist/gateway/demand-spawner.d.ts.map +1 -0
  73. package/dist/gateway/demand-spawner.js +426 -0
  74. package/dist/gateway/demand-spawner.js.map +1 -0
  75. package/dist/identity.d.ts +46 -0
  76. package/dist/identity.d.ts.map +1 -0
  77. package/dist/identity.js +102 -0
  78. package/dist/identity.js.map +1 -0
  79. package/dist/identity.test.d.ts +2 -0
  80. package/dist/identity.test.d.ts.map +1 -0
  81. package/dist/identity.test.js +45 -0
  82. package/dist/identity.test.js.map +1 -0
  83. package/dist/index.d.ts +36 -0
  84. package/dist/index.d.ts.map +1 -0
  85. package/dist/index.js +1572 -0
  86. package/dist/index.js.map +1 -0
  87. package/dist/integration.d.ts +210 -0
  88. package/dist/integration.d.ts.map +1 -0
  89. package/dist/integration.js +1105 -0
  90. package/dist/integration.js.map +1 -0
  91. package/dist/integration.test.d.ts +2 -0
  92. package/dist/integration.test.d.ts.map +1 -0
  93. package/dist/integration.test.js +155 -0
  94. package/dist/integration.test.js.map +1 -0
  95. package/dist/knowledge.d.ts +219 -0
  96. package/dist/knowledge.d.ts.map +1 -0
  97. package/dist/knowledge.js +543 -0
  98. package/dist/knowledge.js.map +1 -0
  99. package/dist/knowledge.test.d.ts +2 -0
  100. package/dist/knowledge.test.d.ts.map +1 -0
  101. package/dist/knowledge.test.js +72 -0
  102. package/dist/knowledge.test.js.map +1 -0
  103. package/dist/latent-space.d.ts +178 -0
  104. package/dist/latent-space.d.ts.map +1 -0
  105. package/dist/latent-space.js +385 -0
  106. package/dist/latent-space.js.map +1 -0
  107. package/dist/lib.d.ts +30 -0
  108. package/dist/lib.d.ts.map +1 -0
  109. package/dist/lib.js +30 -0
  110. package/dist/lib.js.map +1 -0
  111. package/dist/mcp/server.d.ts +74 -0
  112. package/dist/mcp/server.d.ts.map +1 -0
  113. package/dist/mcp/server.js +1392 -0
  114. package/dist/mcp/server.js.map +1 -0
  115. package/dist/metrics.d.ts +98 -0
  116. package/dist/metrics.d.ts.map +1 -0
  117. package/dist/metrics.js +222 -0
  118. package/dist/metrics.js.map +1 -0
  119. package/dist/p2p.d.ts +87 -0
  120. package/dist/p2p.d.ts.map +1 -0
  121. package/dist/p2p.js +606 -0
  122. package/dist/p2p.js.map +1 -0
  123. package/dist/persona/capabilities.d.ts +17 -0
  124. package/dist/persona/capabilities.d.ts.map +1 -0
  125. package/dist/persona/capabilities.js +224 -0
  126. package/dist/persona/capabilities.js.map +1 -0
  127. package/dist/persona/domains.d.ts +22 -0
  128. package/dist/persona/domains.d.ts.map +1 -0
  129. package/dist/persona/domains.js +176 -0
  130. package/dist/persona/domains.js.map +1 -0
  131. package/dist/persona/embeddings.d.ts +40 -0
  132. package/dist/persona/embeddings.d.ts.map +1 -0
  133. package/dist/persona/embeddings.js +265 -0
  134. package/dist/persona/embeddings.js.map +1 -0
  135. package/dist/persona/engine.d.ts +79 -0
  136. package/dist/persona/engine.d.ts.map +1 -0
  137. package/dist/persona/engine.js +1087 -0
  138. package/dist/persona/engine.js.map +1 -0
  139. package/dist/persona/index.d.ts +11 -0
  140. package/dist/persona/index.d.ts.map +1 -0
  141. package/dist/persona/index.js +11 -0
  142. package/dist/persona/index.js.map +1 -0
  143. package/dist/persona/lifecycle.d.ts +17 -0
  144. package/dist/persona/lifecycle.d.ts.map +1 -0
  145. package/dist/persona/lifecycle.js +36 -0
  146. package/dist/persona/lifecycle.js.map +1 -0
  147. package/dist/persona/retrieval.d.ts +6 -0
  148. package/dist/persona/retrieval.d.ts.map +1 -0
  149. package/dist/persona/retrieval.js +122 -0
  150. package/dist/persona/retrieval.js.map +1 -0
  151. package/dist/persona/sync.d.ts +15 -0
  152. package/dist/persona/sync.d.ts.map +1 -0
  153. package/dist/persona/sync.js +92 -0
  154. package/dist/persona/sync.js.map +1 -0
  155. package/dist/persona/types.d.ts +283 -0
  156. package/dist/persona/types.d.ts.map +1 -0
  157. package/dist/persona/types.js +2 -0
  158. package/dist/persona/types.js.map +1 -0
  159. package/dist/persona/zkp/engine.d.ts +26 -0
  160. package/dist/persona/zkp/engine.d.ts.map +1 -0
  161. package/dist/persona/zkp/engine.js +370 -0
  162. package/dist/persona/zkp/engine.js.map +1 -0
  163. package/dist/persona/zkp/types.d.ts +39 -0
  164. package/dist/persona/zkp/types.d.ts.map +1 -0
  165. package/dist/persona/zkp/types.js +2 -0
  166. package/dist/persona/zkp/types.js.map +1 -0
  167. package/dist/planner.d.ts +114 -0
  168. package/dist/planner.d.ts.map +1 -0
  169. package/dist/planner.js +522 -0
  170. package/dist/planner.js.map +1 -0
  171. package/dist/proactive/checkpoints.d.ts +9 -0
  172. package/dist/proactive/checkpoints.d.ts.map +1 -0
  173. package/dist/proactive/checkpoints.js +20 -0
  174. package/dist/proactive/checkpoints.js.map +1 -0
  175. package/dist/proactive/engine.d.ts +59 -0
  176. package/dist/proactive/engine.d.ts.map +1 -0
  177. package/dist/proactive/engine.js +406 -0
  178. package/dist/proactive/engine.js.map +1 -0
  179. package/dist/proactive/scheduler.d.ts +11 -0
  180. package/dist/proactive/scheduler.d.ts.map +1 -0
  181. package/dist/proactive/scheduler.js +45 -0
  182. package/dist/proactive/scheduler.js.map +1 -0
  183. package/dist/proactive/swarm-controller.d.ts +189 -0
  184. package/dist/proactive/swarm-controller.d.ts.map +1 -0
  185. package/dist/proactive/swarm-controller.js +477 -0
  186. package/dist/proactive/swarm-controller.js.map +1 -0
  187. package/dist/proactive/swarm-registry.d.ts +13 -0
  188. package/dist/proactive/swarm-registry.d.ts.map +1 -0
  189. package/dist/proactive/swarm-registry.js +122 -0
  190. package/dist/proactive/swarm-registry.js.map +1 -0
  191. package/dist/proactive/types.d.ts +145 -0
  192. package/dist/proactive/types.d.ts.map +1 -0
  193. package/dist/proactive/types.js +25 -0
  194. package/dist/proactive/types.js.map +1 -0
  195. package/dist/registry.d.ts +35 -0
  196. package/dist/registry.d.ts.map +1 -0
  197. package/dist/registry.js +88 -0
  198. package/dist/registry.js.map +1 -0
  199. package/dist/reputation.d.ts +123 -0
  200. package/dist/reputation.d.ts.map +1 -0
  201. package/dist/reputation.js +366 -0
  202. package/dist/reputation.js.map +1 -0
  203. package/dist/reputation.test.d.ts +5 -0
  204. package/dist/reputation.test.d.ts.map +1 -0
  205. package/dist/reputation.test.js +265 -0
  206. package/dist/reputation.test.js.map +1 -0
  207. package/dist/rooms.d.ts +96 -0
  208. package/dist/rooms.d.ts.map +1 -0
  209. package/dist/rooms.js +410 -0
  210. package/dist/rooms.js.map +1 -0
  211. package/dist/sdk/client.d.ts +290 -0
  212. package/dist/sdk/client.d.ts.map +1 -0
  213. package/dist/sdk/client.js +1287 -0
  214. package/dist/sdk/client.js.map +1 -0
  215. package/dist/sdk/index.d.ts +32 -0
  216. package/dist/sdk/index.d.ts.map +1 -0
  217. package/dist/sdk/index.js +70 -0
  218. package/dist/sdk/index.js.map +1 -0
  219. package/dist/security.d.ts +230 -0
  220. package/dist/security.d.ts.map +1 -0
  221. package/dist/security.js +652 -0
  222. package/dist/security.js.map +1 -0
  223. package/dist/skills/engine.d.ts +262 -0
  224. package/dist/skills/engine.d.ts.map +1 -0
  225. package/dist/skills/engine.js +788 -0
  226. package/dist/skills/engine.js.map +1 -0
  227. package/dist/skills/engine.test.d.ts +2 -0
  228. package/dist/skills/engine.test.d.ts.map +1 -0
  229. package/dist/skills/engine.test.js +134 -0
  230. package/dist/skills/engine.test.js.map +1 -0
  231. package/dist/skills/parser.d.ts +129 -0
  232. package/dist/skills/parser.d.ts.map +1 -0
  233. package/dist/skills/parser.js +318 -0
  234. package/dist/skills/parser.js.map +1 -0
  235. package/dist/social.d.ts +149 -0
  236. package/dist/social.d.ts.map +1 -0
  237. package/dist/social.js +401 -0
  238. package/dist/social.js.map +1 -0
  239. package/dist/storage-optimized.d.ts +116 -0
  240. package/dist/storage-optimized.d.ts.map +1 -0
  241. package/dist/storage-optimized.js +264 -0
  242. package/dist/storage-optimized.js.map +1 -0
  243. package/dist/storage.d.ts +584 -0
  244. package/dist/storage.d.ts.map +1 -0
  245. package/dist/storage.js +2703 -0
  246. package/dist/storage.js.map +1 -0
  247. package/dist/storage.test.d.ts +2 -0
  248. package/dist/storage.test.d.ts.map +1 -0
  249. package/dist/storage.test.js +78 -0
  250. package/dist/storage.test.js.map +1 -0
  251. package/dist/swp.d.ts +443 -0
  252. package/dist/swp.d.ts.map +1 -0
  253. package/dist/swp.js +223 -0
  254. package/dist/swp.js.map +1 -0
  255. package/dist/swp.test.d.ts +5 -0
  256. package/dist/swp.test.d.ts.map +1 -0
  257. package/dist/swp.test.js +127 -0
  258. package/dist/swp.test.js.map +1 -0
  259. package/dist/templates.d.ts +25 -0
  260. package/dist/templates.d.ts.map +1 -0
  261. package/dist/templates.js +1048 -0
  262. package/dist/templates.js.map +1 -0
  263. package/dist/test-e2e.d.ts +14 -0
  264. package/dist/test-e2e.d.ts.map +1 -0
  265. package/dist/test-e2e.js +266 -0
  266. package/dist/test-e2e.js.map +1 -0
  267. package/dist/workers/research-worker.d.ts +19 -0
  268. package/dist/workers/research-worker.d.ts.map +1 -0
  269. package/dist/workers/research-worker.js +141 -0
  270. package/dist/workers/research-worker.js.map +1 -0
  271. package/package.json +110 -0
@@ -0,0 +1,366 @@
1
+ /**
2
+ * Society Protocol — Reputation System v1.0
3
+ *
4
+ * Decentralized reputation tracking for agents based on:
5
+ * - Task completion history
6
+ * - Quality scores from reviews
7
+ * - On-time delivery rates
8
+ * - Community feedback
9
+ *
10
+ * Uses exponential decay to weight recent performance higher.
11
+ */
12
+ import { EventEmitter } from 'events';
13
+ // ─── Default Configuration ──────────────────────────────────────
14
+ const DEFAULT_CONFIG = {
15
+ decayFactor: 0.95,
16
+ minTasksForReliability: 5,
17
+ weights: {
18
+ quality: 0.35,
19
+ reliability: 0.30,
20
+ responsiveness: 0.20,
21
+ expertise: 0.15,
22
+ },
23
+ };
24
+ // ─── Reputation Engine ──────────────────────────────────────────
25
+ export class ReputationEngine extends EventEmitter {
26
+ storage;
27
+ config;
28
+ cache = new Map();
29
+ dirtyDids = new Set();
30
+ constructor(storage, config = {}) {
31
+ super();
32
+ this.storage = storage;
33
+ this.config = { ...DEFAULT_CONFIG, ...config };
34
+ this.startPeriodicSync();
35
+ }
36
+ // ─── Core API ─────────────────────────────────────────────────
37
+ /**
38
+ * Record the outcome of a task assignment
39
+ */
40
+ async recordTaskOutcome(outcome) {
41
+ // Store raw outcome
42
+ this.storage.saveTaskOutcome(outcome);
43
+ // Mark cache entry as dirty
44
+ this.dirtyDids.add(outcome.did);
45
+ // Emit event for real-time updates
46
+ this.emit('outcome:recorded', outcome);
47
+ // Recalculate if significant event
48
+ if (outcome.status === 'completed' || outcome.status === 'failed') {
49
+ await this.recalculateReputation(outcome.did);
50
+ }
51
+ }
52
+ /**
53
+ * Get current reputation score for a DID
54
+ */
55
+ async getReputation(did) {
56
+ // Check cache first
57
+ const cached = this.cache.get(did);
58
+ if (cached && !this.dirtyDids.has(did)) {
59
+ return cached;
60
+ }
61
+ // Calculate fresh score
62
+ const score = await this.calculateReputation(did);
63
+ this.cache.set(did, score);
64
+ this.dirtyDids.delete(did);
65
+ return score;
66
+ }
67
+ /**
68
+ * Get reputation for multiple DIDs (batch)
69
+ */
70
+ async getReputations(dids) {
71
+ const results = new Map();
72
+ await Promise.all(dids.map(async (did) => {
73
+ const rep = await this.getReputation(did);
74
+ results.set(did, rep);
75
+ }));
76
+ return results;
77
+ }
78
+ /**
79
+ * Rank agents by suitability for a specific task
80
+ */
81
+ async rankAgentsForTask(dids, requirements) {
82
+ const reputations = await this.getReputations(dids);
83
+ const ranked = [];
84
+ for (const [did, rep] of reputations) {
85
+ // Filter by minimum reputation
86
+ if (requirements.minReputation && rep.overall < requirements.minReputation) {
87
+ continue;
88
+ }
89
+ // Calculate task-specific score
90
+ const score = this.calculateTaskScore(rep, requirements);
91
+ ranked.push({ did, score, reputation: rep });
92
+ }
93
+ // Sort by score descending
94
+ ranked.sort((a, b) => b.score - a.score);
95
+ return ranked;
96
+ }
97
+ /**
98
+ * Update reputation based on peer review
99
+ */
100
+ async recordPeerReview(reviewerDid, subjectDid, chainId, stepId, rating, // 0.0 - 1.0
101
+ feedback) {
102
+ this.storage.savePeerReview({
103
+ reviewer_did: reviewerDid,
104
+ subject_did: subjectDid,
105
+ chain_id: chainId,
106
+ step_id: stepId,
107
+ rating,
108
+ feedback,
109
+ timestamp: Date.now(),
110
+ });
111
+ this.dirtyDids.add(subjectDid);
112
+ this.emit('review:received', { subjectDid, reviewerDid, rating });
113
+ }
114
+ /**
115
+ * Get reputation trend over time
116
+ */
117
+ async getReputationHistory(did, days = 30) {
118
+ const outcomes = this.storage.getTaskOutcomes(did, days);
119
+ const history = [];
120
+ // Group by day and calculate running score
121
+ const byDay = this.groupByDay(outcomes);
122
+ for (const [date, dayOutcomes] of byDay) {
123
+ const score = this.calculateScoreFromOutcomes(dayOutcomes);
124
+ history.push({ date, score });
125
+ }
126
+ return history;
127
+ }
128
+ // ─── Calculation Logic ────────────────────────────────────────
129
+ async calculateReputation(did) {
130
+ const outcomes = this.storage.getAllTaskOutcomes(did);
131
+ const reviews = this.storage.getPeerReviews(did);
132
+ const existing = this.storage.getReputationRecord(did);
133
+ if (outcomes.length === 0) {
134
+ return this.getDefaultReputation(did, existing?.display_name);
135
+ }
136
+ // Calculate metrics
137
+ const metrics = this.calculateMetrics(outcomes);
138
+ // Calculate specialty scores
139
+ const specialties = this.calculateSpecialtyScores(outcomes);
140
+ // Calculate overall score
141
+ const overall = this.calculateOverallScore(metrics, specialties, reviews);
142
+ // Determine trust tier
143
+ const trust_tier = this.calculateTrustTier(overall, metrics);
144
+ return {
145
+ did,
146
+ display_name: existing?.display_name,
147
+ overall,
148
+ metrics,
149
+ specialties,
150
+ trust_tier,
151
+ first_seen: existing?.first_seen || outcomes[0]?.timestamp || Date.now(),
152
+ last_updated: Date.now(),
153
+ version: (existing?.version || 0) + 1,
154
+ };
155
+ }
156
+ calculateMetrics(outcomes) {
157
+ const completed = outcomes.filter(o => o.status === 'completed');
158
+ const failed = outcomes.filter(o => o.status === 'failed');
159
+ const cancelled = outcomes.filter(o => o.status === 'cancelled');
160
+ const accepted = outcomes.filter(o => o.accepted);
161
+ // Quality score from reviews and submissions
162
+ const qualityScores = completed
163
+ .map(o => o.quality_score)
164
+ .filter((s) => s !== undefined);
165
+ const avg_quality = qualityScores.length > 0
166
+ ? qualityScores.reduce((a, b) => a + b, 0) / qualityScores.length
167
+ : 0.5; // Neutral default
168
+ // Latency
169
+ const latencies = completed.map(o => o.latency_ms);
170
+ const avg_latency = latencies.length > 0
171
+ ? latencies.reduce((a, b) => a + b, 0) / latencies.length
172
+ : 0;
173
+ // Response rate
174
+ const response_rate = outcomes.length > 0
175
+ ? accepted.length / outcomes.length
176
+ : 0;
177
+ // On-time delivery
178
+ const onTime = completed.filter(o => o.latency_ms <= o.lease_ms);
179
+ const on_time_rate = completed.length > 0
180
+ ? onTime.length / completed.length
181
+ : 0;
182
+ return {
183
+ tasks_completed: completed.length,
184
+ tasks_failed: failed.length,
185
+ tasks_cancelled: cancelled.length,
186
+ avg_quality_score: avg_quality,
187
+ avg_latency_ms: avg_latency,
188
+ response_rate: response_rate,
189
+ on_time_delivery: on_time_rate,
190
+ total_tokens_used: completed.reduce((sum, o) => sum + (o.tokens_used || 0), 0),
191
+ total_cost_usd: completed.reduce((sum, o) => sum + (o.cost_usd || 0), 0),
192
+ };
193
+ }
194
+ calculateSpecialtyScores(outcomes) {
195
+ const bySpecialty = new Map();
196
+ // Group outcomes by specialty
197
+ for (const outcome of outcomes) {
198
+ for (const specialty of outcome.specialties_used) {
199
+ const list = bySpecialty.get(specialty) || [];
200
+ list.push(outcome);
201
+ bySpecialty.set(specialty, list);
202
+ }
203
+ }
204
+ // Calculate score for each specialty
205
+ const scores = [];
206
+ for (const [specialty, specialtyOutcomes] of bySpecialty) {
207
+ const completed = specialtyOutcomes.filter(o => o.status === 'completed');
208
+ const qualityScores = completed
209
+ .map(o => o.quality_score)
210
+ .filter((s) => s !== undefined);
211
+ const avgQuality = qualityScores.length > 0
212
+ ? qualityScores.reduce((a, b) => a + b, 0) / qualityScores.length
213
+ : 0.5;
214
+ // Apply decay based on recency
215
+ const weightedScore = this.applyTemporalDecay(specialtyOutcomes, avgQuality);
216
+ scores.push({
217
+ specialty,
218
+ score: weightedScore,
219
+ tasks_completed: completed.length,
220
+ last_used: Math.max(...specialtyOutcomes.map(o => o.timestamp)),
221
+ });
222
+ }
223
+ // Sort by score descending
224
+ scores.sort((a, b) => b.score - a.score);
225
+ return scores;
226
+ }
227
+ calculateOverallScore(metrics, specialties, reviews) {
228
+ const { weights } = this.config;
229
+ // Quality component (direct scores + peer reviews)
230
+ let qualityScore = metrics.avg_quality_score;
231
+ if (reviews.length > 0) {
232
+ const avgReview = reviews.reduce((a, r) => a + r.rating, 0) / reviews.length;
233
+ qualityScore = (qualityScore + avgReview) / 2;
234
+ }
235
+ // Reliability component
236
+ const totalTasks = metrics.tasks_completed + metrics.tasks_failed;
237
+ const successRate = totalTasks > 0
238
+ ? metrics.tasks_completed / totalTasks
239
+ : 0;
240
+ const reliabilityScore = (successRate * 0.6 +
241
+ metrics.on_time_delivery * 0.3 +
242
+ metrics.response_rate * 0.1);
243
+ // Responsiveness component
244
+ const responsivenessScore = (metrics.response_rate * 0.7 +
245
+ Math.max(0, 1 - metrics.avg_latency_ms / 300000) * 0.3 // Normalize to 5 min
246
+ );
247
+ // Expertise component (top specialty scores)
248
+ const topSpecialties = specialties.slice(0, 3);
249
+ const expertiseScore = topSpecialties.length > 0
250
+ ? topSpecialties.reduce((a, s) => a + s.score, 0) / topSpecialties.length
251
+ : 0.5;
252
+ // Weighted sum
253
+ return (qualityScore * weights.quality +
254
+ reliabilityScore * weights.reliability +
255
+ responsivenessScore * weights.responsiveness +
256
+ expertiseScore * weights.expertise);
257
+ }
258
+ calculateTaskScore(rep, requirements) {
259
+ let score = rep.overall;
260
+ // Boost for specialty match
261
+ if (requirements.specialties) {
262
+ const matches = requirements.specialties.filter(req => rep.specialties.some(s => s.specialty.toLowerCase() === req.toLowerCase()));
263
+ const matchRatio = matches.length / requirements.specialties.length;
264
+ score += matchRatio * 0.2; // Up to 20% boost
265
+ }
266
+ // Penalty for high load (handled separately, but slight preference for idle)
267
+ // This is just a tiebreaker
268
+ return Math.min(1, score);
269
+ }
270
+ calculateTrustTier(overall, metrics) {
271
+ const totalTasks = metrics.tasks_completed + metrics.tasks_failed;
272
+ if (totalTasks < 3 || overall < 0.3)
273
+ return 'unverified';
274
+ if (overall < 0.5)
275
+ return 'bronze';
276
+ if (overall < 0.7)
277
+ return 'silver';
278
+ if (overall < 0.9)
279
+ return 'gold';
280
+ return 'platinum';
281
+ }
282
+ applyTemporalDecay(outcomes, baseScore) {
283
+ const now = Date.now();
284
+ let totalWeight = 0;
285
+ let weightedSum = 0;
286
+ for (const outcome of outcomes) {
287
+ const daysAgo = (now - outcome.timestamp) / (1000 * 60 * 60 * 24);
288
+ const weight = Math.pow(this.config.decayFactor, daysAgo);
289
+ const score = outcome.status === 'completed'
290
+ ? (outcome.quality_score || 0.7)
291
+ : 0;
292
+ weightedSum += score * weight;
293
+ totalWeight += weight;
294
+ }
295
+ return totalWeight > 0 ? weightedSum / totalWeight : baseScore;
296
+ }
297
+ getDefaultReputation(did, displayName) {
298
+ return {
299
+ did,
300
+ display_name: displayName,
301
+ overall: 0.5, // Neutral starting point
302
+ metrics: {
303
+ tasks_completed: 0,
304
+ tasks_failed: 0,
305
+ tasks_cancelled: 0,
306
+ avg_quality_score: 0,
307
+ avg_latency_ms: 0,
308
+ response_rate: 0,
309
+ on_time_delivery: 0,
310
+ total_tokens_used: 0,
311
+ total_cost_usd: 0,
312
+ },
313
+ specialties: [],
314
+ trust_tier: 'unverified',
315
+ first_seen: Date.now(),
316
+ last_updated: Date.now(),
317
+ version: 1,
318
+ };
319
+ }
320
+ // ─── Helpers ──────────────────────────────────────────────────
321
+ async recalculateReputation(did) {
322
+ const score = await this.calculateReputation(did);
323
+ this.cache.set(did, score);
324
+ this.dirtyDids.delete(did);
325
+ this.storage.saveReputation(score);
326
+ this.emit('reputation:updated', score);
327
+ }
328
+ startPeriodicSync() {
329
+ // Sync dirty entries every 30 seconds
330
+ setInterval(() => {
331
+ if (this.dirtyDids.size > 0) {
332
+ Promise.all(Array.from(this.dirtyDids).map(did => this.recalculateReputation(did).catch(console.error)));
333
+ }
334
+ }, 30000);
335
+ }
336
+ groupByDay(outcomes) {
337
+ const groups = new Map();
338
+ for (const outcome of outcomes) {
339
+ const date = new Date(outcome.timestamp).toISOString().split('T')[0];
340
+ const list = groups.get(date) || [];
341
+ list.push(outcome);
342
+ groups.set(date, list);
343
+ }
344
+ return groups;
345
+ }
346
+ calculateScoreFromOutcomes(outcomes) {
347
+ const metrics = this.calculateMetrics(outcomes);
348
+ return this.calculateOverallScore(metrics, [], []);
349
+ }
350
+ }
351
+ // ─── Reputation Utilities ───────────────────────────────────────
352
+ export function formatReputationTier(tier) {
353
+ const icons = {
354
+ unverified: '⚪',
355
+ bronze: '🥉',
356
+ silver: '🥈',
357
+ gold: '🥇',
358
+ platinum: '💎',
359
+ };
360
+ return `${icons[tier]} ${tier.charAt(0).toUpperCase() + tier.slice(1)}`;
361
+ }
362
+ export function isTrusted(rep, minTier = 'bronze') {
363
+ const tiers = ['unverified', 'bronze', 'silver', 'gold', 'platinum'];
364
+ return tiers.indexOf(rep.trust_tier) >= tiers.indexOf(minTier);
365
+ }
366
+ //# sourceMappingURL=reputation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reputation.js","sourceRoot":"","sources":["../src/reputation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Reputation System Tests v1.0
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=reputation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reputation.test.d.ts","sourceRoot":"","sources":["../src/reputation.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Reputation System Tests v1.0
3
+ */
4
+ import { describe, it, expect, beforeEach } from 'vitest';
5
+ import { ReputationEngine, formatReputationTier, isTrusted } from './reputation.js';
6
+ import { Storage } from './storage.js';
7
+ describe('Reputation System v1.0', () => {
8
+ let storage;
9
+ let reputation;
10
+ beforeEach(() => {
11
+ storage = new Storage({ dbPath: ':memory:' });
12
+ reputation = new ReputationEngine(storage, {
13
+ decayFactor: 0.95,
14
+ minTasksForReliability: 3,
15
+ weights: {
16
+ quality: 0.35,
17
+ reliability: 0.30,
18
+ responsiveness: 0.20,
19
+ expertise: 0.15,
20
+ },
21
+ });
22
+ });
23
+ describe('Basic Reputation', () => {
24
+ it('should return default reputation for unknown DID', async () => {
25
+ const rep = await reputation.getReputation('did:key:z123');
26
+ expect(rep.did).toBe('did:key:z123');
27
+ expect(rep.overall).toBe(0.5);
28
+ expect(rep.trust_tier).toBe('unverified');
29
+ expect(rep.metrics.tasks_completed).toBe(0);
30
+ });
31
+ it('should calculate reputation from task outcomes', async () => {
32
+ const did = 'did:key:zAlice';
33
+ // Record successful tasks
34
+ for (let i = 0; i < 5; i++) {
35
+ await reputation.recordTaskOutcome({
36
+ did,
37
+ chain_id: `chain-${i}`,
38
+ step_id: `step-${i}`,
39
+ status: 'completed',
40
+ quality_score: 0.8,
41
+ latency_ms: 50000,
42
+ lease_ms: 120000,
43
+ accepted: true,
44
+ specialties_used: ['coding', 'review'],
45
+ timestamp: Date.now(),
46
+ });
47
+ }
48
+ const rep = await reputation.getReputation(did);
49
+ expect(rep.metrics.tasks_completed).toBe(5);
50
+ expect(rep.metrics.avg_quality_score).toBeCloseTo(0.8, 1);
51
+ expect(rep.metrics.on_time_delivery).toBe(1);
52
+ expect(rep.overall).toBeGreaterThan(0.5);
53
+ });
54
+ it('should penalize failed tasks', async () => {
55
+ const did = 'did:key:zBob';
56
+ // Mix of success and failure
57
+ await reputation.recordTaskOutcome({
58
+ did,
59
+ chain_id: 'chain-1',
60
+ step_id: 'step-1',
61
+ status: 'completed',
62
+ quality_score: 0.9,
63
+ latency_ms: 30000,
64
+ lease_ms: 120000,
65
+ accepted: true,
66
+ specialties_used: ['coding'],
67
+ timestamp: Date.now(),
68
+ });
69
+ await reputation.recordTaskOutcome({
70
+ did,
71
+ chain_id: 'chain-2',
72
+ step_id: 'step-2',
73
+ status: 'failed',
74
+ latency_ms: 10000,
75
+ lease_ms: 120000,
76
+ accepted: true,
77
+ specialties_used: ['coding'],
78
+ timestamp: Date.now(),
79
+ });
80
+ const rep = await reputation.getReputation(did);
81
+ expect(rep.metrics.tasks_completed).toBe(1);
82
+ expect(rep.metrics.tasks_failed).toBe(1);
83
+ expect(rep.overall).toBeLessThan(0.9);
84
+ });
85
+ });
86
+ describe('Specialty Scoring', () => {
87
+ it('should track specialty-specific scores', async () => {
88
+ const did = 'did:key:zCoder';
89
+ await reputation.recordTaskOutcome({
90
+ did,
91
+ chain_id: 'chain-1',
92
+ step_id: 'step-1',
93
+ status: 'completed',
94
+ quality_score: 0.9,
95
+ latency_ms: 30000,
96
+ lease_ms: 120000,
97
+ accepted: true,
98
+ specialties_used: ['python', 'backend'],
99
+ timestamp: Date.now(),
100
+ });
101
+ await reputation.recordTaskOutcome({
102
+ did,
103
+ chain_id: 'chain-2',
104
+ step_id: 'step-2',
105
+ status: 'completed',
106
+ quality_score: 0.6,
107
+ latency_ms: 30000,
108
+ lease_ms: 120000,
109
+ accepted: true,
110
+ specialties_used: ['javascript', 'frontend'],
111
+ timestamp: Date.now(),
112
+ });
113
+ const rep = await reputation.getReputation(did);
114
+ const pythonScore = rep.specialties.find(s => s.specialty === 'python');
115
+ const jsScore = rep.specialties.find(s => s.specialty === 'javascript');
116
+ expect(pythonScore).toBeDefined();
117
+ expect(jsScore).toBeDefined();
118
+ expect(pythonScore.score).toBeGreaterThan(jsScore.score);
119
+ });
120
+ });
121
+ describe('Peer Reviews', () => {
122
+ it('should incorporate peer reviews into reputation', async () => {
123
+ const subjectDid = 'did:key:zSubject';
124
+ const reviewerDid = 'did:key:zReviewer';
125
+ // Complete a task
126
+ await reputation.recordTaskOutcome({
127
+ did: subjectDid,
128
+ chain_id: 'chain-1',
129
+ step_id: 'step-1',
130
+ status: 'completed',
131
+ quality_score: 0.7,
132
+ latency_ms: 30000,
133
+ lease_ms: 120000,
134
+ accepted: true,
135
+ specialties_used: ['coding'],
136
+ timestamp: Date.now(),
137
+ });
138
+ // Add peer review
139
+ await reputation.recordPeerReview(reviewerDid, subjectDid, 'chain-1', 'step-1', 0.95, 'Excellent work!');
140
+ const rep = await reputation.getReputation(subjectDid);
141
+ // Should be higher than just the 0.7 from the task
142
+ expect(rep.overall).toBeGreaterThan(0.7);
143
+ });
144
+ });
145
+ describe('Agent Ranking', () => {
146
+ it('should rank agents by suitability', async () => {
147
+ const agents = ['did:key:zA', 'did:key:zB', 'did:key:zC'];
148
+ // Agent A: Good at python
149
+ await reputation.recordTaskOutcome({
150
+ did: agents[0],
151
+ chain_id: 'c1',
152
+ step_id: 's1',
153
+ status: 'completed',
154
+ quality_score: 0.95,
155
+ latency_ms: 30000,
156
+ lease_ms: 120000,
157
+ accepted: true,
158
+ specialties_used: ['python'],
159
+ timestamp: Date.now(),
160
+ });
161
+ // Agent B: Good at javascript
162
+ await reputation.recordTaskOutcome({
163
+ did: agents[1],
164
+ chain_id: 'c2',
165
+ step_id: 's2',
166
+ status: 'completed',
167
+ quality_score: 0.95,
168
+ latency_ms: 30000,
169
+ lease_ms: 120000,
170
+ accepted: true,
171
+ specialties_used: ['javascript'],
172
+ timestamp: Date.now(),
173
+ });
174
+ // Agent C: No specialties
175
+ await reputation.recordTaskOutcome({
176
+ did: agents[2],
177
+ chain_id: 'c3',
178
+ step_id: 's3',
179
+ status: 'completed',
180
+ quality_score: 0.5,
181
+ latency_ms: 30000,
182
+ lease_ms: 120000,
183
+ accepted: true,
184
+ specialties_used: [],
185
+ timestamp: Date.now(),
186
+ });
187
+ const ranked = await reputation.rankAgentsForTask(agents, {
188
+ specialties: ['python'],
189
+ });
190
+ expect(ranked[0].did).toBe(agents[0]); // Agent A should be first for python
191
+ });
192
+ it('should filter by minimum reputation', async () => {
193
+ const agents = ['did:key:zGood', 'did:key:zBad'];
194
+ // Good agent
195
+ await reputation.recordTaskOutcome({
196
+ did: agents[0],
197
+ chain_id: 'c1',
198
+ step_id: 's1',
199
+ status: 'completed',
200
+ quality_score: 0.95,
201
+ latency_ms: 30000,
202
+ lease_ms: 120000,
203
+ accepted: true,
204
+ specialties_used: ['coding'],
205
+ timestamp: Date.now(),
206
+ });
207
+ // Bad agent
208
+ await reputation.recordTaskOutcome({
209
+ did: agents[1],
210
+ chain_id: 'c2',
211
+ step_id: 's2',
212
+ status: 'failed',
213
+ latency_ms: 30000,
214
+ lease_ms: 120000,
215
+ accepted: true,
216
+ specialties_used: ['coding'],
217
+ timestamp: Date.now(),
218
+ });
219
+ const ranked = await reputation.rankAgentsForTask(agents, {
220
+ minReputation: 0.7,
221
+ });
222
+ expect(ranked.length).toBe(1);
223
+ expect(ranked[0].did).toBe(agents[0]);
224
+ });
225
+ });
226
+ describe('Trust Tiers', () => {
227
+ it('should assign correct trust tiers', async () => {
228
+ const tiers = ['unverified', 'bronze', 'silver', 'gold', 'platinum'];
229
+ for (let i = 0; i < tiers.length; i++) {
230
+ const did = `did:key:z${tiers[i]}`;
231
+ // Create appropriate number of tasks for each tier
232
+ const numTasks = i * 5 + 3;
233
+ for (let j = 0; j < numTasks; j++) {
234
+ await reputation.recordTaskOutcome({
235
+ did,
236
+ chain_id: `c-${i}-${j}`,
237
+ step_id: `s-${i}-${j}`,
238
+ status: 'completed',
239
+ quality_score: 0.5 + (i * 0.1),
240
+ latency_ms: 30000,
241
+ lease_ms: 120000,
242
+ accepted: true,
243
+ specialties_used: ['coding'],
244
+ timestamp: Date.now(),
245
+ });
246
+ }
247
+ const rep = await reputation.getReputation(did);
248
+ expect(rep.trust_tier).toBeDefined();
249
+ }
250
+ });
251
+ });
252
+ describe('Utilities', () => {
253
+ it('should format reputation tiers', () => {
254
+ expect(formatReputationTier('platinum')).toContain('💎');
255
+ expect(formatReputationTier('gold')).toContain('🥇');
256
+ expect(formatReputationTier('unverified')).toContain('⚪');
257
+ });
258
+ it('should check trust correctly', () => {
259
+ expect(isTrusted({ trust_tier: 'gold' }, 'silver')).toBe(true);
260
+ expect(isTrusted({ trust_tier: 'bronze' }, 'silver')).toBe(false);
261
+ expect(isTrusted({ trust_tier: 'platinum' }, 'gold')).toBe(true);
262
+ });
263
+ });
264
+ });
265
+ //# sourceMappingURL=reputation.test.js.map