@ruvector/edge-full 0.1.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.
- package/LICENSE +21 -0
- package/README.md +390 -0
- package/dag/ruvector_dag_wasm.d.ts +105 -0
- package/dag/ruvector_dag_wasm.js +466 -0
- package/dag/ruvector_dag_wasm_bg.wasm +0 -0
- package/dag/ruvector_dag_wasm_bg.wasm.d.ts +20 -0
- package/edge/ruvector_edge.d.ts +351 -0
- package/edge/ruvector_edge.js +1452 -0
- package/edge/ruvector_edge_bg.wasm +0 -0
- package/edge/ruvector_edge_bg.wasm.d.ts +71 -0
- package/generator.html +2009 -0
- package/graph/ruvector_graph_wasm.d.ts +380 -0
- package/graph/ruvector_graph_wasm.js +1787 -0
- package/graph/ruvector_graph_wasm_bg.wasm +0 -0
- package/graph/ruvector_graph_wasm_bg.wasm.d.ts +80 -0
- package/index.d.ts +64 -0
- package/index.js +182 -0
- package/onnx/ruvector_onnx_embeddings_wasm.d.ts +112 -0
- package/onnx/ruvector_onnx_embeddings_wasm.js +635 -0
- package/onnx/ruvector_onnx_embeddings_wasm_bg.js +629 -0
- package/onnx/ruvector_onnx_embeddings_wasm_bg.wasm +0 -0
- package/onnx/ruvector_onnx_embeddings_wasm_bg.wasm.d.ts +29 -0
- package/package.json +86 -0
- package/rvlite/rvlite.d.ts +556 -0
- package/rvlite/rvlite.js +2366 -0
- package/rvlite/rvlite_bg.wasm +0 -0
- package/rvlite/rvlite_bg.wasm.d.ts +128 -0
- package/sona/ruvector_sona.d.ts +513 -0
- package/sona/ruvector_sona.js +1290 -0
- package/sona/ruvector_sona_bg.wasm +0 -0
- package/sona/ruvector_sona_bg.wasm.d.ts +53 -0
package/generator.html
ADDED
|
@@ -0,0 +1,2009 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>@ruvector/edge-full - Swarm Generator</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--bg: #0a0a0f;
|
|
10
|
+
--card: #12121a;
|
|
11
|
+
--border: #2a2a3a;
|
|
12
|
+
--text: #e0e0e0;
|
|
13
|
+
--muted: #888;
|
|
14
|
+
--accent: #6366f1;
|
|
15
|
+
--accent2: #22d3ee;
|
|
16
|
+
--success: #10b981;
|
|
17
|
+
--warning: #f59e0b;
|
|
18
|
+
}
|
|
19
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
20
|
+
body {
|
|
21
|
+
font-family: 'SF Mono', 'Fira Code', monospace;
|
|
22
|
+
background: var(--bg);
|
|
23
|
+
color: var(--text);
|
|
24
|
+
min-height: 100vh;
|
|
25
|
+
padding: 20px;
|
|
26
|
+
}
|
|
27
|
+
.container { max-width: 1400px; margin: 0 auto; }
|
|
28
|
+
h1 {
|
|
29
|
+
font-size: 2rem;
|
|
30
|
+
background: linear-gradient(90deg, var(--accent), var(--accent2));
|
|
31
|
+
-webkit-background-clip: text;
|
|
32
|
+
-webkit-text-fill-color: transparent;
|
|
33
|
+
margin-bottom: 10px;
|
|
34
|
+
}
|
|
35
|
+
.subtitle { color: var(--muted); margin-bottom: 30px; }
|
|
36
|
+
.grid { display: grid; grid-template-columns: 350px 1fr; gap: 20px; }
|
|
37
|
+
@media (max-width: 900px) { .grid { grid-template-columns: 1fr; } }
|
|
38
|
+
|
|
39
|
+
.panel {
|
|
40
|
+
background: var(--card);
|
|
41
|
+
border: 1px solid var(--border);
|
|
42
|
+
border-radius: 12px;
|
|
43
|
+
padding: 20px;
|
|
44
|
+
}
|
|
45
|
+
.panel h2 {
|
|
46
|
+
font-size: 1rem;
|
|
47
|
+
color: var(--accent2);
|
|
48
|
+
margin-bottom: 15px;
|
|
49
|
+
display: flex;
|
|
50
|
+
align-items: center;
|
|
51
|
+
gap: 8px;
|
|
52
|
+
}
|
|
53
|
+
.section { margin-bottom: 20px; }
|
|
54
|
+
.section-title {
|
|
55
|
+
font-size: 0.75rem;
|
|
56
|
+
text-transform: uppercase;
|
|
57
|
+
color: var(--muted);
|
|
58
|
+
margin-bottom: 10px;
|
|
59
|
+
letter-spacing: 1px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.option-grid {
|
|
63
|
+
display: grid;
|
|
64
|
+
grid-template-columns: repeat(2, 1fr);
|
|
65
|
+
gap: 8px;
|
|
66
|
+
}
|
|
67
|
+
.option {
|
|
68
|
+
background: var(--bg);
|
|
69
|
+
border: 1px solid var(--border);
|
|
70
|
+
border-radius: 8px;
|
|
71
|
+
padding: 12px;
|
|
72
|
+
cursor: pointer;
|
|
73
|
+
transition: all 0.2s;
|
|
74
|
+
}
|
|
75
|
+
.option:hover { border-color: var(--accent); }
|
|
76
|
+
.option.selected {
|
|
77
|
+
border-color: var(--accent);
|
|
78
|
+
background: rgba(99, 102, 241, 0.1);
|
|
79
|
+
}
|
|
80
|
+
.option-title { font-size: 0.85rem; font-weight: bold; }
|
|
81
|
+
.option-desc { font-size: 0.7rem; color: var(--muted); margin-top: 4px; }
|
|
82
|
+
|
|
83
|
+
.tag-list { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
84
|
+
.tag {
|
|
85
|
+
background: var(--bg);
|
|
86
|
+
border: 1px solid var(--border);
|
|
87
|
+
border-radius: 4px;
|
|
88
|
+
padding: 4px 10px;
|
|
89
|
+
font-size: 0.75rem;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
transition: all 0.2s;
|
|
92
|
+
}
|
|
93
|
+
.tag:hover { border-color: var(--accent2); }
|
|
94
|
+
.tag.selected {
|
|
95
|
+
background: var(--accent2);
|
|
96
|
+
color: var(--bg);
|
|
97
|
+
border-color: var(--accent2);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.code-panel { position: relative; }
|
|
101
|
+
.code-header {
|
|
102
|
+
display: flex;
|
|
103
|
+
justify-content: space-between;
|
|
104
|
+
align-items: center;
|
|
105
|
+
margin-bottom: 15px;
|
|
106
|
+
}
|
|
107
|
+
.copy-btn {
|
|
108
|
+
background: var(--accent);
|
|
109
|
+
color: white;
|
|
110
|
+
border: none;
|
|
111
|
+
padding: 8px 16px;
|
|
112
|
+
border-radius: 6px;
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
font-family: inherit;
|
|
115
|
+
font-size: 0.8rem;
|
|
116
|
+
}
|
|
117
|
+
.copy-btn:hover { opacity: 0.9; }
|
|
118
|
+
|
|
119
|
+
pre {
|
|
120
|
+
background: #0d0d12;
|
|
121
|
+
border: 1px solid var(--border);
|
|
122
|
+
border-radius: 8px;
|
|
123
|
+
padding: 20px;
|
|
124
|
+
overflow-x: auto;
|
|
125
|
+
font-size: 0.8rem;
|
|
126
|
+
line-height: 1.6;
|
|
127
|
+
max-height: 600px;
|
|
128
|
+
overflow-y: auto;
|
|
129
|
+
}
|
|
130
|
+
code { color: var(--text); }
|
|
131
|
+
.keyword { color: #c792ea; }
|
|
132
|
+
.string { color: #c3e88d; }
|
|
133
|
+
.comment { color: #546e7a; }
|
|
134
|
+
.function { color: #82aaff; }
|
|
135
|
+
.number { color: #f78c6c; }
|
|
136
|
+
.const { color: #89ddff; }
|
|
137
|
+
|
|
138
|
+
.stats {
|
|
139
|
+
display: grid;
|
|
140
|
+
grid-template-columns: repeat(4, 1fr);
|
|
141
|
+
gap: 10px;
|
|
142
|
+
margin-top: 20px;
|
|
143
|
+
}
|
|
144
|
+
.stat {
|
|
145
|
+
background: var(--bg);
|
|
146
|
+
border-radius: 8px;
|
|
147
|
+
padding: 15px;
|
|
148
|
+
text-align: center;
|
|
149
|
+
}
|
|
150
|
+
.stat-value {
|
|
151
|
+
font-size: 1.5rem;
|
|
152
|
+
font-weight: bold;
|
|
153
|
+
color: var(--accent);
|
|
154
|
+
}
|
|
155
|
+
.stat-label { font-size: 0.7rem; color: var(--muted); margin-top: 4px; }
|
|
156
|
+
|
|
157
|
+
.live-demo {
|
|
158
|
+
margin-top: 20px;
|
|
159
|
+
padding: 20px;
|
|
160
|
+
background: var(--bg);
|
|
161
|
+
border-radius: 8px;
|
|
162
|
+
border: 1px solid var(--border);
|
|
163
|
+
}
|
|
164
|
+
.demo-output {
|
|
165
|
+
font-size: 0.8rem;
|
|
166
|
+
color: var(--success);
|
|
167
|
+
white-space: pre-wrap;
|
|
168
|
+
max-height: 200px;
|
|
169
|
+
overflow-y: auto;
|
|
170
|
+
}
|
|
171
|
+
.run-btn {
|
|
172
|
+
background: var(--success);
|
|
173
|
+
color: white;
|
|
174
|
+
border: none;
|
|
175
|
+
padding: 10px 20px;
|
|
176
|
+
border-radius: 6px;
|
|
177
|
+
cursor: pointer;
|
|
178
|
+
font-family: inherit;
|
|
179
|
+
font-size: 0.85rem;
|
|
180
|
+
margin-bottom: 15px;
|
|
181
|
+
}
|
|
182
|
+
.run-btn:hover { opacity: 0.9; }
|
|
183
|
+
.run-btn:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
184
|
+
|
|
185
|
+
.footer {
|
|
186
|
+
margin-top: 30px;
|
|
187
|
+
text-align: center;
|
|
188
|
+
color: var(--muted);
|
|
189
|
+
font-size: 0.8rem;
|
|
190
|
+
}
|
|
191
|
+
.footer a { color: var(--accent); text-decoration: none; }
|
|
192
|
+
</style>
|
|
193
|
+
</head>
|
|
194
|
+
<body>
|
|
195
|
+
<div class="container">
|
|
196
|
+
<h1>@ruvector/edge-full Swarm Generator</h1>
|
|
197
|
+
<p class="subtitle">Generate ready-to-use code for any deployment topology</p>
|
|
198
|
+
|
|
199
|
+
<div class="grid">
|
|
200
|
+
<!-- Left Panel: Configuration -->
|
|
201
|
+
<div class="panel">
|
|
202
|
+
<h2>āļø Configuration</h2>
|
|
203
|
+
|
|
204
|
+
<div class="section">
|
|
205
|
+
<div class="section-title">Topology</div>
|
|
206
|
+
<div class="option-grid" id="topology-options">
|
|
207
|
+
<div class="option selected" data-value="mesh">
|
|
208
|
+
<div class="option-title">šøļø Mesh</div>
|
|
209
|
+
<div class="option-desc">All agents connect to all</div>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="option" data-value="star">
|
|
212
|
+
<div class="option-title">ā Star</div>
|
|
213
|
+
<div class="option-desc">Central coordinator</div>
|
|
214
|
+
</div>
|
|
215
|
+
<div class="option" data-value="hierarchical">
|
|
216
|
+
<div class="option-title">šļø Hierarchical</div>
|
|
217
|
+
<div class="option-desc">Tree structure</div>
|
|
218
|
+
</div>
|
|
219
|
+
<div class="option" data-value="ring">
|
|
220
|
+
<div class="option-title">š Ring</div>
|
|
221
|
+
<div class="option-desc">Circular passing</div>
|
|
222
|
+
</div>
|
|
223
|
+
<div class="option" data-value="gossip">
|
|
224
|
+
<div class="option-title">š¬ Gossip</div>
|
|
225
|
+
<div class="option-desc">Epidemic broadcast</div>
|
|
226
|
+
</div>
|
|
227
|
+
<div class="option" data-value="sharded">
|
|
228
|
+
<div class="option-title">š§© Sharded</div>
|
|
229
|
+
<div class="option-desc">Domain partitioned</div>
|
|
230
|
+
</div>
|
|
231
|
+
</div>
|
|
232
|
+
</div>
|
|
233
|
+
|
|
234
|
+
<div class="section">
|
|
235
|
+
<div class="section-title">Transport</div>
|
|
236
|
+
<div class="option-grid" id="transport-options">
|
|
237
|
+
<div class="option selected" data-value="gun">
|
|
238
|
+
<div class="option-title">š« GUN.js</div>
|
|
239
|
+
<div class="option-desc">Free, offline-first</div>
|
|
240
|
+
</div>
|
|
241
|
+
<div class="option" data-value="webrtc">
|
|
242
|
+
<div class="option-title">š” WebRTC</div>
|
|
243
|
+
<div class="option-desc">Direct P2P</div>
|
|
244
|
+
</div>
|
|
245
|
+
<div class="option" data-value="libp2p">
|
|
246
|
+
<div class="option-title">š libp2p</div>
|
|
247
|
+
<div class="option-desc">IPFS compatible</div>
|
|
248
|
+
</div>
|
|
249
|
+
<div class="option" data-value="nostr">
|
|
250
|
+
<div class="option-title">ā” Nostr</div>
|
|
251
|
+
<div class="option-desc">Relay-based</div>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
|
|
256
|
+
<div class="section">
|
|
257
|
+
<div class="section-title">Use Case</div>
|
|
258
|
+
<div class="option-grid" id="usecase-options">
|
|
259
|
+
<div class="option selected" data-value="ai-assistants">
|
|
260
|
+
<div class="option-title">š¤ AI Assistants</div>
|
|
261
|
+
<div class="option-desc">Multi-agent chat</div>
|
|
262
|
+
</div>
|
|
263
|
+
<div class="option" data-value="data-pipeline">
|
|
264
|
+
<div class="option-title">š Data Pipeline</div>
|
|
265
|
+
<div class="option-desc">Distributed ETL</div>
|
|
266
|
+
</div>
|
|
267
|
+
<div class="option" data-value="gaming">
|
|
268
|
+
<div class="option-title">š® Multiplayer</div>
|
|
269
|
+
<div class="option-desc">Real-time gaming</div>
|
|
270
|
+
</div>
|
|
271
|
+
<div class="option" data-value="iot">
|
|
272
|
+
<div class="option-title">š± IoT Swarm</div>
|
|
273
|
+
<div class="option-desc">Edge devices</div>
|
|
274
|
+
</div>
|
|
275
|
+
<div class="option" data-value="marketplace">
|
|
276
|
+
<div class="option-title">šŖ Marketplace</div>
|
|
277
|
+
<div class="option-desc">Agent trading</div>
|
|
278
|
+
</div>
|
|
279
|
+
<div class="option" data-value="research">
|
|
280
|
+
<div class="option-title">š¬ Research</div>
|
|
281
|
+
<div class="option-desc">Distributed compute</div>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
|
|
286
|
+
<div class="section">
|
|
287
|
+
<div class="section-title">WASM Modules</div>
|
|
288
|
+
<div class="option-grid" id="module-options">
|
|
289
|
+
<div class="option selected" data-value="edge">
|
|
290
|
+
<div class="option-title">š Edge Core</div>
|
|
291
|
+
<div class="option-desc">364KB - Crypto, vectors</div>
|
|
292
|
+
</div>
|
|
293
|
+
<div class="option" data-value="graph">
|
|
294
|
+
<div class="option-title">šøļø Graph DB</div>
|
|
295
|
+
<div class="option-desc">288KB - Neo4j, Cypher</div>
|
|
296
|
+
</div>
|
|
297
|
+
<div class="option" data-value="rvlite">
|
|
298
|
+
<div class="option-title">šļø RVLite</div>
|
|
299
|
+
<div class="option-desc">260KB - SQL/SPARQL</div>
|
|
300
|
+
</div>
|
|
301
|
+
<div class="option" data-value="sona">
|
|
302
|
+
<div class="option-title">š§ SONA</div>
|
|
303
|
+
<div class="option-desc">238KB - LoRA, EWC++</div>
|
|
304
|
+
</div>
|
|
305
|
+
<div class="option" data-value="dag">
|
|
306
|
+
<div class="option-title">š DAG</div>
|
|
307
|
+
<div class="option-desc">132KB - Workflows</div>
|
|
308
|
+
</div>
|
|
309
|
+
<div class="option" data-value="onnx">
|
|
310
|
+
<div class="option-title">š¤ ONNX</div>
|
|
311
|
+
<div class="option-desc">7.1MB - Embeddings</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
<div class="section">
|
|
317
|
+
<div class="section-title">Features</div>
|
|
318
|
+
<div class="tag-list" id="feature-tags">
|
|
319
|
+
<div class="tag selected" data-value="identity">Identity</div>
|
|
320
|
+
<div class="tag selected" data-value="encryption">Encryption</div>
|
|
321
|
+
<div class="tag" data-value="hnsw">HNSW Index</div>
|
|
322
|
+
<div class="tag" data-value="semantic">Semantic Match</div>
|
|
323
|
+
<div class="tag" data-value="raft">Raft Consensus</div>
|
|
324
|
+
<div class="tag" data-value="pq">Post-Quantum</div>
|
|
325
|
+
<div class="tag" data-value="spiking">Spiking NN</div>
|
|
326
|
+
<div class="tag" data-value="compression">Compression</div>
|
|
327
|
+
</div>
|
|
328
|
+
</div>
|
|
329
|
+
|
|
330
|
+
<div class="section">
|
|
331
|
+
<div class="section-title">Exotic Patterns</div>
|
|
332
|
+
<div class="tag-list" id="exotic-tags">
|
|
333
|
+
<div class="tag" data-value="mcp-browser">MCP Tools</div>
|
|
334
|
+
<div class="tag" data-value="byzantine">Byzantine Fault</div>
|
|
335
|
+
<div class="tag" data-value="quantum">Quantum Resistant</div>
|
|
336
|
+
<div class="tag" data-value="neural-consensus">Neural Consensus</div>
|
|
337
|
+
<div class="tag" data-value="swarm-intelligence">Swarm Intel</div>
|
|
338
|
+
<div class="tag" data-value="self-healing">Self-Healing</div>
|
|
339
|
+
<div class="tag" data-value="emergent">Emergent Behavior</div>
|
|
340
|
+
</div>
|
|
341
|
+
</div>
|
|
342
|
+
|
|
343
|
+
<div class="stats">
|
|
344
|
+
<div class="stat">
|
|
345
|
+
<div class="stat-value" id="agent-count">3</div>
|
|
346
|
+
<div class="stat-label">Agents</div>
|
|
347
|
+
</div>
|
|
348
|
+
<div class="stat">
|
|
349
|
+
<div class="stat-value" id="msg-latency">~100ms</div>
|
|
350
|
+
<div class="stat-label">Latency</div>
|
|
351
|
+
</div>
|
|
352
|
+
<div class="stat">
|
|
353
|
+
<div class="stat-value">$0</div>
|
|
354
|
+
<div class="stat-label">Monthly</div>
|
|
355
|
+
</div>
|
|
356
|
+
<div class="stat">
|
|
357
|
+
<div class="stat-value" id="bundle-size">364KB</div>
|
|
358
|
+
<div class="stat-label">Bundle</div>
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
|
|
363
|
+
<!-- Right Panel: Generated Code -->
|
|
364
|
+
<div class="panel code-panel">
|
|
365
|
+
<div class="code-header">
|
|
366
|
+
<h2>š Generated Code</h2>
|
|
367
|
+
<button class="copy-btn" onclick="copyCode()">š Copy Code</button>
|
|
368
|
+
</div>
|
|
369
|
+
<pre><code id="generated-code"></code></pre>
|
|
370
|
+
|
|
371
|
+
<div class="live-demo">
|
|
372
|
+
<button class="run-btn" id="run-btn" onclick="runDemo()">ā¶ļø Run Live Demo</button>
|
|
373
|
+
<div class="demo-output" id="demo-output">Click "Run Live Demo" to execute in browser...</div>
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
376
|
+
</div>
|
|
377
|
+
|
|
378
|
+
<div class="footer">
|
|
379
|
+
<p>
|
|
380
|
+
<a href="https://www.npmjs.com/package/@ruvector/edge">npm</a> ā¢
|
|
381
|
+
<a href="https://github.com/ruvnet/ruvector">GitHub</a> ā¢
|
|
382
|
+
MIT License ⢠$0 Forever
|
|
383
|
+
</p>
|
|
384
|
+
</div>
|
|
385
|
+
</div>
|
|
386
|
+
|
|
387
|
+
<script type="module">
|
|
388
|
+
import init, {
|
|
389
|
+
WasmIdentity,
|
|
390
|
+
WasmCrypto,
|
|
391
|
+
WasmHnswIndex,
|
|
392
|
+
WasmSemanticMatcher,
|
|
393
|
+
WasmRaftNode,
|
|
394
|
+
WasmHybridKeyPair,
|
|
395
|
+
WasmSpikingNetwork,
|
|
396
|
+
WasmQuantizer,
|
|
397
|
+
WasmAdaptiveCompressor
|
|
398
|
+
} from './ruvector_edge.js';
|
|
399
|
+
|
|
400
|
+
let wasmReady = false;
|
|
401
|
+
|
|
402
|
+
// Initialize WASM
|
|
403
|
+
init().then(() => {
|
|
404
|
+
wasmReady = true;
|
|
405
|
+
document.getElementById('run-btn').disabled = false;
|
|
406
|
+
console.log('@ruvector/edge WASM loaded');
|
|
407
|
+
}).catch(err => {
|
|
408
|
+
console.error('WASM load failed:', err);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
// State
|
|
412
|
+
const state = {
|
|
413
|
+
topology: 'mesh',
|
|
414
|
+
transport: 'gun',
|
|
415
|
+
usecase: 'ai-assistants',
|
|
416
|
+
modules: ['edge'],
|
|
417
|
+
features: ['identity', 'encryption'],
|
|
418
|
+
exotic: []
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
// Module sizes in KB
|
|
422
|
+
const moduleSizes = {
|
|
423
|
+
edge: 364,
|
|
424
|
+
graph: 288,
|
|
425
|
+
rvlite: 260,
|
|
426
|
+
sona: 238,
|
|
427
|
+
dag: 132,
|
|
428
|
+
onnx: 7270 // 7.1MB
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
function updateBundleSize() {
|
|
432
|
+
const totalKB = state.modules.reduce((sum, mod) => sum + moduleSizes[mod], 0);
|
|
433
|
+
const sizeStr = totalKB >= 1024 ? `${(totalKB / 1024).toFixed(1)}MB` : `${totalKB}KB`;
|
|
434
|
+
document.getElementById('bundle-size').textContent = sizeStr;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Code templates
|
|
438
|
+
const templates = {
|
|
439
|
+
// Topology patterns
|
|
440
|
+
topologies: {
|
|
441
|
+
mesh: `// Mesh Topology - All agents connected to all
|
|
442
|
+
class MeshSwarm {
|
|
443
|
+
constructor() {
|
|
444
|
+
this.agents = new Map();
|
|
445
|
+
this.matcher = new WasmSemanticMatcher();
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
addAgent(id, capabilities) {
|
|
449
|
+
const identity = WasmIdentity.generate();
|
|
450
|
+
this.agents.set(id, { identity, capabilities });
|
|
451
|
+
this.matcher.register_agent(id, capabilities);
|
|
452
|
+
|
|
453
|
+
// Notify all existing agents
|
|
454
|
+
this.broadcast({ type: 'agent_joined', id, capabilities });
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
broadcast(message) {
|
|
458
|
+
for (const [id, agent] of this.agents) {
|
|
459
|
+
this.sendTo(id, message);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
routeTask(task) {
|
|
464
|
+
return this.matcher.find_best_agent(task);
|
|
465
|
+
}
|
|
466
|
+
}`,
|
|
467
|
+
|
|
468
|
+
star: `// Star Topology - Central coordinator
|
|
469
|
+
class StarSwarm {
|
|
470
|
+
constructor() {
|
|
471
|
+
this.coordinator = WasmIdentity.generate();
|
|
472
|
+
this.workers = new Map();
|
|
473
|
+
this.raft = null;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
initCoordinator(workerIds) {
|
|
477
|
+
this.raft = new WasmRaftNode('coordinator', ['coordinator', ...workerIds]);
|
|
478
|
+
this.raft.start_election();
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
addWorker(id, capabilities) {
|
|
482
|
+
const identity = WasmIdentity.generate();
|
|
483
|
+
this.workers.set(id, { identity, capabilities });
|
|
484
|
+
// Worker only connects to coordinator
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
dispatch(task) {
|
|
488
|
+
// Coordinator routes all tasks
|
|
489
|
+
const workers = Array.from(this.workers.keys());
|
|
490
|
+
return workers[Math.floor(Math.random() * workers.length)];
|
|
491
|
+
}
|
|
492
|
+
}`,
|
|
493
|
+
|
|
494
|
+
hierarchical: `// Hierarchical Topology - Tree structure
|
|
495
|
+
class HierarchicalSwarm {
|
|
496
|
+
constructor(levels = 3) {
|
|
497
|
+
this.levels = levels;
|
|
498
|
+
this.tree = this.buildTree(levels);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
buildTree(depth, prefix = 'node') {
|
|
502
|
+
if (depth === 0) return null;
|
|
503
|
+
return {
|
|
504
|
+
id: prefix,
|
|
505
|
+
identity: WasmIdentity.generate(),
|
|
506
|
+
children: depth > 1 ? [
|
|
507
|
+
this.buildTree(depth - 1, \`\${prefix}-L\`),
|
|
508
|
+
this.buildTree(depth - 1, \`\${prefix}-R\`)
|
|
509
|
+
] : []
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
propagateDown(node, message) {
|
|
514
|
+
if (!node) return;
|
|
515
|
+
console.log(\`\${node.id} received:\`, message);
|
|
516
|
+
node.children.forEach(child => this.propagateDown(child, message));
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
aggregateUp(node, fn) {
|
|
520
|
+
if (!node.children.length) return fn(node);
|
|
521
|
+
const childResults = node.children.map(c => this.aggregateUp(c, fn));
|
|
522
|
+
return fn(node, childResults);
|
|
523
|
+
}
|
|
524
|
+
}`,
|
|
525
|
+
|
|
526
|
+
ring: `// Ring Topology - Circular message passing
|
|
527
|
+
class RingSwarm {
|
|
528
|
+
constructor(size = 5) {
|
|
529
|
+
this.ring = [];
|
|
530
|
+
for (let i = 0; i < size; i++) {
|
|
531
|
+
this.ring.push({
|
|
532
|
+
id: \`node-\${i}\`,
|
|
533
|
+
identity: WasmIdentity.generate(),
|
|
534
|
+
next: null
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
// Connect ring
|
|
538
|
+
for (let i = 0; i < size; i++) {
|
|
539
|
+
this.ring[i].next = this.ring[(i + 1) % size];
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
passMessage(startIdx, message, hops = this.ring.length) {
|
|
544
|
+
let current = this.ring[startIdx];
|
|
545
|
+
for (let i = 0; i < hops; i++) {
|
|
546
|
+
console.log(\`\${current.id} processing:\`, message);
|
|
547
|
+
message = this.transform(current, message);
|
|
548
|
+
current = current.next;
|
|
549
|
+
}
|
|
550
|
+
return message;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
transform(node, message) {
|
|
554
|
+
return { ...message, visited: [...(message.visited || []), node.id] };
|
|
555
|
+
}
|
|
556
|
+
}`,
|
|
557
|
+
|
|
558
|
+
gossip: `// Gossip Protocol - Epidemic broadcast
|
|
559
|
+
class GossipSwarm {
|
|
560
|
+
constructor(fanout = 3) {
|
|
561
|
+
this.fanout = fanout;
|
|
562
|
+
this.nodes = new Map();
|
|
563
|
+
this.seen = new Set();
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
addNode(id) {
|
|
567
|
+
this.nodes.set(id, {
|
|
568
|
+
identity: WasmIdentity.generate(),
|
|
569
|
+
data: new Map()
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
gossip(fromId, key, value) {
|
|
574
|
+
const msgId = \`\${key}-\${Date.now()}\`;
|
|
575
|
+
if (this.seen.has(msgId)) return;
|
|
576
|
+
this.seen.add(msgId);
|
|
577
|
+
|
|
578
|
+
// Update local
|
|
579
|
+
this.nodes.get(fromId).data.set(key, value);
|
|
580
|
+
|
|
581
|
+
// Spread to random peers
|
|
582
|
+
const peers = Array.from(this.nodes.keys()).filter(id => id !== fromId);
|
|
583
|
+
const selected = this.selectRandom(peers, this.fanout);
|
|
584
|
+
|
|
585
|
+
selected.forEach(peerId => {
|
|
586
|
+
setTimeout(() => this.gossip(peerId, key, value), Math.random() * 100);
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
selectRandom(arr, n) {
|
|
591
|
+
return arr.sort(() => Math.random() - 0.5).slice(0, n);
|
|
592
|
+
}
|
|
593
|
+
}`,
|
|
594
|
+
|
|
595
|
+
sharded: `// Sharded Topology - Domain partitioned
|
|
596
|
+
class ShardedSwarm {
|
|
597
|
+
constructor(shardCount = 4) {
|
|
598
|
+
this.shards = new Map();
|
|
599
|
+
for (let i = 0; i < shardCount; i++) {
|
|
600
|
+
this.shards.set(i, {
|
|
601
|
+
id: \`shard-\${i}\`,
|
|
602
|
+
agents: new Map(),
|
|
603
|
+
index: new WasmHnswIndex(128, 16, 200)
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
getShard(key) {
|
|
609
|
+
const hash = this.hash(key);
|
|
610
|
+
return this.shards.get(hash % this.shards.size);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
hash(str) {
|
|
614
|
+
let hash = 0;
|
|
615
|
+
for (let i = 0; i < str.length; i++) {
|
|
616
|
+
hash = ((hash << 5) - hash) + str.charCodeAt(i);
|
|
617
|
+
}
|
|
618
|
+
return Math.abs(hash);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
addAgent(domain, id, embedding) {
|
|
622
|
+
const shard = this.getShard(domain);
|
|
623
|
+
shard.agents.set(id, WasmIdentity.generate());
|
|
624
|
+
shard.index.insert(id, embedding);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
query(domain, embedding, k = 5) {
|
|
628
|
+
const shard = this.getShard(domain);
|
|
629
|
+
return shard.index.search(embedding, k);
|
|
630
|
+
}
|
|
631
|
+
}`
|
|
632
|
+
},
|
|
633
|
+
|
|
634
|
+
// Transport implementations
|
|
635
|
+
transports: {
|
|
636
|
+
gun: `// GUN.js Transport - Free, offline-first
|
|
637
|
+
import Gun from 'gun';
|
|
638
|
+
|
|
639
|
+
const gun = Gun([
|
|
640
|
+
'https://gun-manhattan.herokuapp.com/gun',
|
|
641
|
+
'https://gun-us.herokuapp.com/gun'
|
|
642
|
+
]);
|
|
643
|
+
|
|
644
|
+
const swarm = gun.get('my-ai-swarm');
|
|
645
|
+
|
|
646
|
+
// Publish agent
|
|
647
|
+
function announce(agent) {
|
|
648
|
+
swarm.get('agents').get(agent.id).put({
|
|
649
|
+
id: agent.id,
|
|
650
|
+
publicKey: agent.identity.public_key_hex(),
|
|
651
|
+
capabilities: agent.capabilities,
|
|
652
|
+
online: true,
|
|
653
|
+
timestamp: Date.now()
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// Subscribe to agents
|
|
658
|
+
swarm.get('agents').map().on((data, id) => {
|
|
659
|
+
if (data) console.log('Agent update:', id, data);
|
|
660
|
+
});
|
|
661
|
+
|
|
662
|
+
// Send task
|
|
663
|
+
function sendTask(task) {
|
|
664
|
+
swarm.get('tasks').set({
|
|
665
|
+
id: crypto.randomUUID(),
|
|
666
|
+
...task,
|
|
667
|
+
timestamp: Date.now()
|
|
668
|
+
});
|
|
669
|
+
}`,
|
|
670
|
+
|
|
671
|
+
webrtc: `// WebRTC Transport - Direct P2P
|
|
672
|
+
const rtcConfig = {
|
|
673
|
+
iceServers: [
|
|
674
|
+
{ urls: 'stun:stun.l.google.com:19302' },
|
|
675
|
+
{ urls: 'stun:stun.cloudflare.com:3478' }
|
|
676
|
+
]
|
|
677
|
+
};
|
|
678
|
+
|
|
679
|
+
class WebRTCTransport {
|
|
680
|
+
constructor() {
|
|
681
|
+
this.peers = new Map();
|
|
682
|
+
this.crypto = new WasmCrypto();
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
async connect(peerId, signalChannel) {
|
|
686
|
+
const pc = new RTCPeerConnection(rtcConfig);
|
|
687
|
+
const channel = pc.createDataChannel('swarm');
|
|
688
|
+
|
|
689
|
+
channel.onopen = () => {
|
|
690
|
+
console.log(\`Connected to \${peerId}\`);
|
|
691
|
+
this.peers.set(peerId, { pc, channel });
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
channel.onmessage = (e) => this.handleMessage(peerId, e.data);
|
|
695
|
+
|
|
696
|
+
const offer = await pc.createOffer();
|
|
697
|
+
await pc.setLocalDescription(offer);
|
|
698
|
+
signalChannel.send({ type: 'offer', peerId, offer });
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
send(peerId, message) {
|
|
702
|
+
const peer = this.peers.get(peerId);
|
|
703
|
+
if (peer?.channel?.readyState === 'open') {
|
|
704
|
+
const key = this.getSharedKey(peerId);
|
|
705
|
+
const encrypted = this.crypto.encrypt(key,
|
|
706
|
+
new TextEncoder().encode(JSON.stringify(message)));
|
|
707
|
+
peer.channel.send(encrypted);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}`,
|
|
711
|
+
|
|
712
|
+
libp2p: `// libp2p Transport - IPFS compatible
|
|
713
|
+
import { createLibp2p } from 'libp2p';
|
|
714
|
+
import { webSockets } from '@libp2p/websockets';
|
|
715
|
+
import { noise } from '@chainsafe/libp2p-noise';
|
|
716
|
+
import { gossipsub } from '@chainsafe/libp2p-gossipsub';
|
|
717
|
+
import { kadDHT } from '@libp2p/kad-dht';
|
|
718
|
+
|
|
719
|
+
async function createNode() {
|
|
720
|
+
const node = await createLibp2p({
|
|
721
|
+
transports: [webSockets()],
|
|
722
|
+
connectionEncryption: [noise()],
|
|
723
|
+
pubsub: gossipsub(),
|
|
724
|
+
dht: kadDHT()
|
|
725
|
+
});
|
|
726
|
+
|
|
727
|
+
await node.start();
|
|
728
|
+
return node;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
class Libp2pTransport {
|
|
732
|
+
constructor(node) {
|
|
733
|
+
this.node = node;
|
|
734
|
+
this.topic = 'ruvector-swarm';
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
async subscribe(handler) {
|
|
738
|
+
this.node.pubsub.subscribe(this.topic);
|
|
739
|
+
this.node.pubsub.addEventListener('message', (evt) => {
|
|
740
|
+
if (evt.detail.topic === this.topic) {
|
|
741
|
+
const msg = JSON.parse(new TextDecoder().decode(evt.detail.data));
|
|
742
|
+
handler(msg);
|
|
743
|
+
}
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
async publish(message) {
|
|
748
|
+
await this.node.pubsub.publish(
|
|
749
|
+
this.topic,
|
|
750
|
+
new TextEncoder().encode(JSON.stringify(message))
|
|
751
|
+
);
|
|
752
|
+
}
|
|
753
|
+
}`,
|
|
754
|
+
|
|
755
|
+
nostr: `// Nostr Transport - Relay-based
|
|
756
|
+
import { relayInit, generatePrivateKey, getPublicKey } from 'nostr-tools';
|
|
757
|
+
|
|
758
|
+
const RELAYS = [
|
|
759
|
+
'wss://relay.damus.io',
|
|
760
|
+
'wss://nos.lol',
|
|
761
|
+
'wss://relay.nostr.band'
|
|
762
|
+
];
|
|
763
|
+
|
|
764
|
+
class NostrTransport {
|
|
765
|
+
constructor() {
|
|
766
|
+
this.relays = [];
|
|
767
|
+
this.sk = generatePrivateKey();
|
|
768
|
+
this.pk = getPublicKey(this.sk);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
async connect() {
|
|
772
|
+
for (const url of RELAYS) {
|
|
773
|
+
const relay = relayInit(url);
|
|
774
|
+
await relay.connect();
|
|
775
|
+
this.relays.push(relay);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
subscribe(swarmId, handler) {
|
|
780
|
+
this.relays.forEach(relay => {
|
|
781
|
+
const sub = relay.sub([
|
|
782
|
+
{ kinds: [29000], '#swarm': [swarmId] }
|
|
783
|
+
]);
|
|
784
|
+
sub.on('event', handler);
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
async publish(swarmId, content) {
|
|
789
|
+
const event = {
|
|
790
|
+
kind: 29000,
|
|
791
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
792
|
+
tags: [['swarm', swarmId]],
|
|
793
|
+
content: JSON.stringify(content),
|
|
794
|
+
pubkey: this.pk
|
|
795
|
+
};
|
|
796
|
+
// Sign and publish to all relays
|
|
797
|
+
for (const relay of this.relays) {
|
|
798
|
+
await relay.publish(event);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
}`
|
|
802
|
+
},
|
|
803
|
+
|
|
804
|
+
// Use case implementations
|
|
805
|
+
usecases: {
|
|
806
|
+
'ai-assistants': `// AI Assistant Swarm - Multi-agent chat
|
|
807
|
+
class AIAssistantSwarm {
|
|
808
|
+
constructor() {
|
|
809
|
+
this.agents = new Map();
|
|
810
|
+
this.matcher = new WasmSemanticMatcher();
|
|
811
|
+
this.history = [];
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
registerAssistant(id, specialty) {
|
|
815
|
+
const identity = WasmIdentity.generate();
|
|
816
|
+
this.agents.set(id, { identity, specialty });
|
|
817
|
+
this.matcher.register_agent(id, specialty);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
async chat(userMessage) {
|
|
821
|
+
// Route to best agent
|
|
822
|
+
const bestAgent = this.matcher.find_best_agent(userMessage);
|
|
823
|
+
const agent = this.agents.get(bestAgent);
|
|
824
|
+
|
|
825
|
+
console.log(\`Routing to \${bestAgent}: \${userMessage}\`);
|
|
826
|
+
|
|
827
|
+
// Record in history
|
|
828
|
+
this.history.push({
|
|
829
|
+
role: 'user',
|
|
830
|
+
content: userMessage,
|
|
831
|
+
timestamp: Date.now()
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
// Agent processes (would call LLM API here)
|
|
835
|
+
const response = await this.processWithAgent(agent, userMessage);
|
|
836
|
+
|
|
837
|
+
this.history.push({
|
|
838
|
+
role: bestAgent,
|
|
839
|
+
content: response,
|
|
840
|
+
timestamp: Date.now()
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
return { agent: bestAgent, response };
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
// Example
|
|
848
|
+
const swarm = new AIAssistantSwarm();
|
|
849
|
+
swarm.registerAssistant('coder', 'programming code typescript rust python');
|
|
850
|
+
swarm.registerAssistant('writer', 'writing documentation blog articles');
|
|
851
|
+
swarm.registerAssistant('analyst', 'data analysis statistics charts');`,
|
|
852
|
+
|
|
853
|
+
'data-pipeline': `// Distributed Data Pipeline - ETL Swarm
|
|
854
|
+
class DataPipelineSwarm {
|
|
855
|
+
constructor() {
|
|
856
|
+
this.stages = new Map();
|
|
857
|
+
this.compressor = new WasmAdaptiveCompressor();
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
addStage(name, processFn) {
|
|
861
|
+
this.stages.set(name, {
|
|
862
|
+
identity: WasmIdentity.generate(),
|
|
863
|
+
process: processFn,
|
|
864
|
+
metrics: { processed: 0, errors: 0 }
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
async run(data, pipeline) {
|
|
869
|
+
let current = data;
|
|
870
|
+
|
|
871
|
+
for (const stageName of pipeline) {
|
|
872
|
+
const stage = this.stages.get(stageName);
|
|
873
|
+
console.log(\`Stage \${stageName}: processing \${current.length} items\`);
|
|
874
|
+
|
|
875
|
+
try {
|
|
876
|
+
current = await stage.process(current);
|
|
877
|
+
stage.metrics.processed += current.length;
|
|
878
|
+
} catch (err) {
|
|
879
|
+
stage.metrics.errors++;
|
|
880
|
+
throw err;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
return current;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// Example pipeline
|
|
889
|
+
const pipeline = new DataPipelineSwarm();
|
|
890
|
+
pipeline.addStage('extract', (data) => data.map(d => d.raw));
|
|
891
|
+
pipeline.addStage('transform', (data) => data.filter(d => d.valid));
|
|
892
|
+
pipeline.addStage('load', (data) => { console.log('Loaded:', data.length); return data; });`,
|
|
893
|
+
|
|
894
|
+
gaming: `// Multiplayer Game Swarm - Real-time sync
|
|
895
|
+
class GameSwarm {
|
|
896
|
+
constructor() {
|
|
897
|
+
this.players = new Map();
|
|
898
|
+
this.raft = null;
|
|
899
|
+
this.gameState = { entities: [], tick: 0 };
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
initLobby(playerIds) {
|
|
903
|
+
this.raft = new WasmRaftNode(playerIds[0], playerIds);
|
|
904
|
+
playerIds.forEach(id => {
|
|
905
|
+
this.players.set(id, {
|
|
906
|
+
identity: WasmIdentity.generate(),
|
|
907
|
+
position: { x: 0, y: 0 },
|
|
908
|
+
score: 0
|
|
909
|
+
});
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
electHost() {
|
|
914
|
+
this.raft.start_election();
|
|
915
|
+
// Simulate votes
|
|
916
|
+
this.raft.receive_vote(true);
|
|
917
|
+
this.raft.receive_vote(true);
|
|
918
|
+
return this.raft.state() === 'leader';
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
updatePlayer(playerId, action) {
|
|
922
|
+
const player = this.players.get(playerId);
|
|
923
|
+
const signed = player.identity.sign(
|
|
924
|
+
new TextEncoder().encode(JSON.stringify(action))
|
|
925
|
+
);
|
|
926
|
+
|
|
927
|
+
// Apply action
|
|
928
|
+
if (action.type === 'move') {
|
|
929
|
+
player.position.x += action.dx;
|
|
930
|
+
player.position.y += action.dy;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
this.gameState.tick++;
|
|
934
|
+
return this.gameState;
|
|
935
|
+
}
|
|
936
|
+
}`,
|
|
937
|
+
|
|
938
|
+
iot: `// IoT Swarm - Edge device coordination
|
|
939
|
+
class IoTSwarm {
|
|
940
|
+
constructor() {
|
|
941
|
+
this.devices = new Map();
|
|
942
|
+
this.index = new WasmHnswIndex(64, 8, 100);
|
|
943
|
+
this.quantizer = new WasmQuantizer();
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
registerDevice(id, type, location) {
|
|
947
|
+
const identity = WasmIdentity.generate();
|
|
948
|
+
const embedding = this.createEmbedding(type, location);
|
|
949
|
+
|
|
950
|
+
this.devices.set(id, { identity, type, location, lastSeen: Date.now() });
|
|
951
|
+
this.index.insert(id, embedding);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
createEmbedding(type, location) {
|
|
955
|
+
const vec = new Float32Array(64);
|
|
956
|
+
vec[0] = location.lat / 90;
|
|
957
|
+
vec[1] = location.lng / 180;
|
|
958
|
+
vec[2] = type === 'sensor' ? 1 : 0;
|
|
959
|
+
vec[3] = type === 'actuator' ? 1 : 0;
|
|
960
|
+
return vec;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
findNearbyDevices(location, k = 5) {
|
|
964
|
+
const query = this.createEmbedding('query', location);
|
|
965
|
+
return this.index.search(query, k);
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
broadcastToRegion(location, radius, command) {
|
|
969
|
+
const nearby = this.findNearbyDevices(location, 20);
|
|
970
|
+
nearby.forEach(([id, distance]) => {
|
|
971
|
+
if (distance < radius) {
|
|
972
|
+
console.log(\`Command to \${id}: \${command}\`);
|
|
973
|
+
}
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
}`,
|
|
977
|
+
|
|
978
|
+
marketplace: `// Agent Marketplace - Trading swarm
|
|
979
|
+
class MarketplaceSwarm {
|
|
980
|
+
constructor() {
|
|
981
|
+
this.agents = new Map();
|
|
982
|
+
this.orderBook = { bids: [], asks: [] };
|
|
983
|
+
this.matcher = new WasmSemanticMatcher();
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
registerTrader(id, specialties) {
|
|
987
|
+
const identity = WasmIdentity.generate();
|
|
988
|
+
this.agents.set(id, {
|
|
989
|
+
identity,
|
|
990
|
+
balance: 1000,
|
|
991
|
+
holdings: new Map()
|
|
992
|
+
});
|
|
993
|
+
this.matcher.register_agent(id, specialties);
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
submitOrder(agentId, type, asset, price, quantity) {
|
|
997
|
+
const agent = this.agents.get(agentId);
|
|
998
|
+
const order = {
|
|
999
|
+
id: crypto.randomUUID(),
|
|
1000
|
+
agentId,
|
|
1001
|
+
type,
|
|
1002
|
+
asset,
|
|
1003
|
+
price,
|
|
1004
|
+
quantity,
|
|
1005
|
+
signature: agent.identity.sign(
|
|
1006
|
+
new TextEncoder().encode(\`\${type}:\${asset}:\${price}:\${quantity}\`)
|
|
1007
|
+
),
|
|
1008
|
+
timestamp: Date.now()
|
|
1009
|
+
};
|
|
1010
|
+
|
|
1011
|
+
if (type === 'bid') this.orderBook.bids.push(order);
|
|
1012
|
+
else this.orderBook.asks.push(order);
|
|
1013
|
+
|
|
1014
|
+
return this.matchOrders(asset);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
matchOrders(asset) {
|
|
1018
|
+
// Simple matching logic
|
|
1019
|
+
const bids = this.orderBook.bids.filter(o => o.asset === asset);
|
|
1020
|
+
const asks = this.orderBook.asks.filter(o => o.asset === asset);
|
|
1021
|
+
|
|
1022
|
+
bids.sort((a, b) => b.price - a.price);
|
|
1023
|
+
asks.sort((a, b) => a.price - b.price);
|
|
1024
|
+
|
|
1025
|
+
const trades = [];
|
|
1026
|
+
// Match orders...
|
|
1027
|
+
return trades;
|
|
1028
|
+
}
|
|
1029
|
+
}`,
|
|
1030
|
+
|
|
1031
|
+
research: `// Distributed Research Swarm - Compute grid
|
|
1032
|
+
class ResearchSwarm {
|
|
1033
|
+
constructor() {
|
|
1034
|
+
this.workers = new Map();
|
|
1035
|
+
this.tasks = [];
|
|
1036
|
+
this.results = new Map();
|
|
1037
|
+
this.network = new WasmSpikingNetwork(10, 20, 5);
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
addWorker(id, capabilities) {
|
|
1041
|
+
this.workers.set(id, {
|
|
1042
|
+
identity: WasmIdentity.generate(),
|
|
1043
|
+
capabilities,
|
|
1044
|
+
busy: false,
|
|
1045
|
+
completed: 0
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
submitTask(task) {
|
|
1050
|
+
const taskId = crypto.randomUUID();
|
|
1051
|
+
this.tasks.push({ id: taskId, ...task, status: 'pending' });
|
|
1052
|
+
return taskId;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
schedule() {
|
|
1056
|
+
for (const task of this.tasks.filter(t => t.status === 'pending')) {
|
|
1057
|
+
// Find available worker
|
|
1058
|
+
const available = Array.from(this.workers.entries())
|
|
1059
|
+
.filter(([_, w]) => !w.busy);
|
|
1060
|
+
|
|
1061
|
+
if (available.length > 0) {
|
|
1062
|
+
const [workerId, worker] = available[0];
|
|
1063
|
+
worker.busy = true;
|
|
1064
|
+
task.status = 'running';
|
|
1065
|
+
task.worker = workerId;
|
|
1066
|
+
|
|
1067
|
+
console.log(\`Assigned \${task.id} to \${workerId}\`);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
aggregateResults(taskIds) {
|
|
1073
|
+
// Use spiking network for result fusion
|
|
1074
|
+
const inputs = taskIds.map(id => this.results.has(id));
|
|
1075
|
+
return this.network.forward(inputs);
|
|
1076
|
+
}
|
|
1077
|
+
}`
|
|
1078
|
+
},
|
|
1079
|
+
|
|
1080
|
+
// Exotic patterns
|
|
1081
|
+
exotic: {
|
|
1082
|
+
byzantine: `// Byzantine Fault Tolerance
|
|
1083
|
+
class ByzantineSwarm {
|
|
1084
|
+
constructor(n) {
|
|
1085
|
+
this.n = n;
|
|
1086
|
+
this.f = Math.floor((n - 1) / 3); // Max faulty nodes
|
|
1087
|
+
this.nodes = [];
|
|
1088
|
+
|
|
1089
|
+
for (let i = 0; i < n; i++) {
|
|
1090
|
+
this.nodes.push({
|
|
1091
|
+
id: i,
|
|
1092
|
+
identity: WasmIdentity.generate(),
|
|
1093
|
+
honest: Math.random() > 0.1 // 10% faulty
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
byzantineAgreement(value) {
|
|
1099
|
+
const votes = new Map();
|
|
1100
|
+
|
|
1101
|
+
// Each node broadcasts
|
|
1102
|
+
for (const node of this.nodes) {
|
|
1103
|
+
const vote = node.honest ? value : Math.random() > 0.5;
|
|
1104
|
+
const signed = node.identity.sign(
|
|
1105
|
+
new TextEncoder().encode(String(vote))
|
|
1106
|
+
);
|
|
1107
|
+
votes.set(node.id, { vote, signed });
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// Tally
|
|
1111
|
+
const trueVotes = Array.from(votes.values()).filter(v => v.vote).length;
|
|
1112
|
+
return trueVotes > this.n - this.f;
|
|
1113
|
+
}
|
|
1114
|
+
}`,
|
|
1115
|
+
|
|
1116
|
+
quantum: `// Quantum-Resistant Swarm
|
|
1117
|
+
class QuantumResistantSwarm {
|
|
1118
|
+
constructor() {
|
|
1119
|
+
this.agents = new Map();
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
addAgent(id) {
|
|
1123
|
+
// Use post-quantum hybrid signatures
|
|
1124
|
+
const hybridKey = WasmHybridKeyPair.generate();
|
|
1125
|
+
this.agents.set(id, { hybridKey });
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
signMessage(agentId, message) {
|
|
1129
|
+
const agent = this.agents.get(agentId);
|
|
1130
|
+
// Hybrid signature: Ed25519 + Dilithium-style
|
|
1131
|
+
return agent.hybridKey.sign(message);
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
verifyMessage(agentId, message, signature) {
|
|
1135
|
+
const agent = this.agents.get(agentId);
|
|
1136
|
+
return agent.hybridKey.verify(message, signature);
|
|
1137
|
+
}
|
|
1138
|
+
}`,
|
|
1139
|
+
|
|
1140
|
+
'neural-consensus': `// Neural Consensus - Spiking network voting
|
|
1141
|
+
class NeuralConsensus {
|
|
1142
|
+
constructor(numVoters) {
|
|
1143
|
+
this.network = new WasmSpikingNetwork(numVoters, numVoters * 2, 1);
|
|
1144
|
+
this.voters = [];
|
|
1145
|
+
|
|
1146
|
+
for (let i = 0; i < numVoters; i++) {
|
|
1147
|
+
this.voters.push(WasmIdentity.generate());
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
vote(opinions) {
|
|
1152
|
+
// Convert opinions to spikes
|
|
1153
|
+
const spikes = opinions.map(o => o > 0.5);
|
|
1154
|
+
|
|
1155
|
+
// Process through spiking network
|
|
1156
|
+
const output = this.network.forward(spikes);
|
|
1157
|
+
|
|
1158
|
+
// STDP learning from consensus
|
|
1159
|
+
this.network.stdp_update(spikes, output, 0.01);
|
|
1160
|
+
|
|
1161
|
+
return output[0]; // Consensus decision
|
|
1162
|
+
}
|
|
1163
|
+
}`,
|
|
1164
|
+
|
|
1165
|
+
'swarm-intelligence': `// Swarm Intelligence - Emergent optimization
|
|
1166
|
+
class SwarmIntelligence {
|
|
1167
|
+
constructor(particleCount = 50) {
|
|
1168
|
+
this.particles = [];
|
|
1169
|
+
this.globalBest = null;
|
|
1170
|
+
this.globalBestScore = -Infinity;
|
|
1171
|
+
|
|
1172
|
+
for (let i = 0; i < particleCount; i++) {
|
|
1173
|
+
this.particles.push({
|
|
1174
|
+
identity: WasmIdentity.generate(),
|
|
1175
|
+
position: Array(10).fill(0).map(() => Math.random()),
|
|
1176
|
+
velocity: Array(10).fill(0).map(() => (Math.random() - 0.5) * 0.1),
|
|
1177
|
+
bestPosition: null,
|
|
1178
|
+
bestScore: -Infinity
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
optimize(fitnessFunction, iterations = 100) {
|
|
1184
|
+
for (let i = 0; i < iterations; i++) {
|
|
1185
|
+
for (const particle of this.particles) {
|
|
1186
|
+
const score = fitnessFunction(particle.position);
|
|
1187
|
+
|
|
1188
|
+
if (score > particle.bestScore) {
|
|
1189
|
+
particle.bestScore = score;
|
|
1190
|
+
particle.bestPosition = [...particle.position];
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
if (score > this.globalBestScore) {
|
|
1194
|
+
this.globalBestScore = score;
|
|
1195
|
+
this.globalBest = [...particle.position];
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
// Update velocity and position
|
|
1199
|
+
this.updateParticle(particle);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
return { position: this.globalBest, score: this.globalBestScore };
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
updateParticle(particle) {
|
|
1207
|
+
const w = 0.7, c1 = 1.5, c2 = 1.5;
|
|
1208
|
+
for (let d = 0; d < particle.position.length; d++) {
|
|
1209
|
+
particle.velocity[d] =
|
|
1210
|
+
w * particle.velocity[d] +
|
|
1211
|
+
c1 * Math.random() * (particle.bestPosition[d] - particle.position[d]) +
|
|
1212
|
+
c2 * Math.random() * (this.globalBest[d] - particle.position[d]);
|
|
1213
|
+
particle.position[d] += particle.velocity[d];
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}`,
|
|
1217
|
+
|
|
1218
|
+
'mcp-browser': `// Browser-Based MCP Tools - Collaborative AI
|
|
1219
|
+
class BrowserMCPServer {
|
|
1220
|
+
constructor() {
|
|
1221
|
+
this.tools = new Map();
|
|
1222
|
+
this.resources = new Map();
|
|
1223
|
+
this.identity = null;
|
|
1224
|
+
this.peers = new Map();
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
async init() {
|
|
1228
|
+
await init();
|
|
1229
|
+
this.identity = WasmIdentity.generate();
|
|
1230
|
+
this.crypto = new WasmCrypto();
|
|
1231
|
+
this.index = new WasmHnswIndex(128, 16, 200);
|
|
1232
|
+
this.matcher = new WasmSemanticMatcher();
|
|
1233
|
+
|
|
1234
|
+
// Register built-in tools
|
|
1235
|
+
this.registerBuiltinTools();
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
registerBuiltinTools() {
|
|
1239
|
+
// Agent discovery tool
|
|
1240
|
+
this.registerTool('discover_agents', {
|
|
1241
|
+
description: 'Find agents with specific capabilities',
|
|
1242
|
+
schema: { type: 'object', properties: { query: { type: 'string' } } },
|
|
1243
|
+
handler: async ({ query }) => {
|
|
1244
|
+
return this.matcher.find_best_agent(query);
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
|
|
1248
|
+
// Secure message tool
|
|
1249
|
+
this.registerTool('send_secure_message', {
|
|
1250
|
+
description: 'Send encrypted message to peer',
|
|
1251
|
+
schema: {
|
|
1252
|
+
type: 'object',
|
|
1253
|
+
properties: {
|
|
1254
|
+
peerId: { type: 'string' },
|
|
1255
|
+
message: { type: 'string' }
|
|
1256
|
+
}
|
|
1257
|
+
},
|
|
1258
|
+
handler: async ({ peerId, message }) => {
|
|
1259
|
+
const peer = this.peers.get(peerId);
|
|
1260
|
+
if (!peer) throw new Error('Peer not found');
|
|
1261
|
+
|
|
1262
|
+
const encrypted = this.crypto.encrypt(
|
|
1263
|
+
peer.sharedKey,
|
|
1264
|
+
new TextEncoder().encode(message)
|
|
1265
|
+
);
|
|
1266
|
+
return { encrypted: Array.from(encrypted), size: encrypted.length };
|
|
1267
|
+
}
|
|
1268
|
+
});
|
|
1269
|
+
|
|
1270
|
+
// Vector memory tool
|
|
1271
|
+
this.registerTool('store_memory', {
|
|
1272
|
+
description: 'Store vector in distributed memory',
|
|
1273
|
+
schema: {
|
|
1274
|
+
type: 'object',
|
|
1275
|
+
properties: {
|
|
1276
|
+
key: { type: 'string' },
|
|
1277
|
+
embedding: { type: 'array', items: { type: 'number' } }
|
|
1278
|
+
}
|
|
1279
|
+
},
|
|
1280
|
+
handler: async ({ key, embedding }) => {
|
|
1281
|
+
this.index.insert(key, new Float32Array(embedding));
|
|
1282
|
+
return { stored: key, total: this.index.len() };
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
|
|
1286
|
+
// Semantic search tool
|
|
1287
|
+
this.registerTool('search_memory', {
|
|
1288
|
+
description: 'Search vector memory',
|
|
1289
|
+
schema: {
|
|
1290
|
+
type: 'object',
|
|
1291
|
+
properties: {
|
|
1292
|
+
query: { type: 'array', items: { type: 'number' } },
|
|
1293
|
+
k: { type: 'number', default: 5 }
|
|
1294
|
+
}
|
|
1295
|
+
},
|
|
1296
|
+
handler: async ({ query, k = 5 }) => {
|
|
1297
|
+
return this.index.search(new Float32Array(query), k);
|
|
1298
|
+
}
|
|
1299
|
+
});
|
|
1300
|
+
|
|
1301
|
+
// Sign message tool
|
|
1302
|
+
this.registerTool('sign_message', {
|
|
1303
|
+
description: 'Cryptographically sign a message',
|
|
1304
|
+
schema: { type: 'object', properties: { message: { type: 'string' } } },
|
|
1305
|
+
handler: async ({ message }) => {
|
|
1306
|
+
const sig = this.identity.sign(new TextEncoder().encode(message));
|
|
1307
|
+
return { signature: Array.from(sig), agentId: this.identity.agent_id() };
|
|
1308
|
+
}
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
registerTool(name, { description, schema, handler }) {
|
|
1313
|
+
this.tools.set(name, { description, schema, handler });
|
|
1314
|
+
this.matcher.register_agent(name, description);
|
|
1315
|
+
}
|
|
1316
|
+
|
|
1317
|
+
async handleRequest(request) {
|
|
1318
|
+
const { method, params } = request;
|
|
1319
|
+
|
|
1320
|
+
switch (method) {
|
|
1321
|
+
case 'tools/list':
|
|
1322
|
+
return {
|
|
1323
|
+
tools: Array.from(this.tools.entries()).map(([name, tool]) => ({
|
|
1324
|
+
name,
|
|
1325
|
+
description: tool.description,
|
|
1326
|
+
inputSchema: tool.schema
|
|
1327
|
+
}))
|
|
1328
|
+
};
|
|
1329
|
+
|
|
1330
|
+
case 'tools/call':
|
|
1331
|
+
const tool = this.tools.get(params.name);
|
|
1332
|
+
if (!tool) throw new Error(\`Unknown tool: \${params.name}\`);
|
|
1333
|
+
return { content: [{ type: 'text', text: JSON.stringify(await tool.handler(params.arguments)) }] };
|
|
1334
|
+
|
|
1335
|
+
case 'resources/list':
|
|
1336
|
+
return { resources: Array.from(this.resources.keys()) };
|
|
1337
|
+
|
|
1338
|
+
default:
|
|
1339
|
+
throw new Error(\`Unknown method: \${method}\`);
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// Collaborative MCP Network
|
|
1345
|
+
class MCPCollaborativeNetwork {
|
|
1346
|
+
constructor() {
|
|
1347
|
+
this.servers = new Map();
|
|
1348
|
+
this.raft = null;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
async addServer(id, capabilities) {
|
|
1352
|
+
const server = new BrowserMCPServer();
|
|
1353
|
+
await server.init();
|
|
1354
|
+
this.servers.set(id, server);
|
|
1355
|
+
|
|
1356
|
+
// Update consensus cluster
|
|
1357
|
+
const members = Array.from(this.servers.keys());
|
|
1358
|
+
if (members.length >= 3) {
|
|
1359
|
+
this.raft = new WasmRaftNode(members[0], members);
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
return server;
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
async routeRequest(request) {
|
|
1366
|
+
// Find best server for this request
|
|
1367
|
+
const toolName = request.params?.name;
|
|
1368
|
+
if (toolName) {
|
|
1369
|
+
for (const [id, server] of this.servers) {
|
|
1370
|
+
if (server.tools.has(toolName)) {
|
|
1371
|
+
return { serverId: id, response: await server.handleRequest(request) };
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
// Fallback to first server
|
|
1377
|
+
const [firstId, firstServer] = this.servers.entries().next().value;
|
|
1378
|
+
return { serverId: firstId, response: await firstServer.handleRequest(request) };
|
|
1379
|
+
}
|
|
1380
|
+
}`,
|
|
1381
|
+
|
|
1382
|
+
'self-healing': `// Self-Healing Swarm - Automatic recovery
|
|
1383
|
+
class SelfHealingSwarm {
|
|
1384
|
+
constructor() {
|
|
1385
|
+
this.nodes = new Map();
|
|
1386
|
+
this.heartbeatInterval = 5000;
|
|
1387
|
+
this.failureThreshold = 15000;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
addNode(id) {
|
|
1391
|
+
this.nodes.set(id, {
|
|
1392
|
+
identity: WasmIdentity.generate(),
|
|
1393
|
+
lastHeartbeat: Date.now(),
|
|
1394
|
+
status: 'healthy',
|
|
1395
|
+
backup: null
|
|
1396
|
+
});
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
heartbeat(nodeId) {
|
|
1400
|
+
const node = this.nodes.get(nodeId);
|
|
1401
|
+
if (node) {
|
|
1402
|
+
node.lastHeartbeat = Date.now();
|
|
1403
|
+
node.status = 'healthy';
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
checkHealth() {
|
|
1408
|
+
const now = Date.now();
|
|
1409
|
+
for (const [id, node] of this.nodes) {
|
|
1410
|
+
if (now - node.lastHeartbeat > this.failureThreshold) {
|
|
1411
|
+
console.log(\`Node \${id} failed! Initiating recovery...\`);
|
|
1412
|
+
this.recover(id);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
recover(nodeId) {
|
|
1418
|
+
const failed = this.nodes.get(nodeId);
|
|
1419
|
+
failed.status = 'failed';
|
|
1420
|
+
|
|
1421
|
+
// Elect replacement
|
|
1422
|
+
const healthy = Array.from(this.nodes.entries())
|
|
1423
|
+
.filter(([_, n]) => n.status === 'healthy');
|
|
1424
|
+
|
|
1425
|
+
if (healthy.length > 0) {
|
|
1426
|
+
const [replacementId, replacement] = healthy[0];
|
|
1427
|
+
replacement.backup = nodeId;
|
|
1428
|
+
console.log(\`Node \${replacementId} taking over for \${nodeId}\`);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
}`,
|
|
1432
|
+
|
|
1433
|
+
emergent: `// Emergent Behavior - Agent evolution
|
|
1434
|
+
class EmergentSwarm {
|
|
1435
|
+
constructor(populationSize = 20) {
|
|
1436
|
+
this.population = [];
|
|
1437
|
+
this.generation = 0;
|
|
1438
|
+
|
|
1439
|
+
for (let i = 0; i < populationSize; i++) {
|
|
1440
|
+
this.population.push({
|
|
1441
|
+
identity: WasmIdentity.generate(),
|
|
1442
|
+
genes: Array(10).fill(0).map(() => Math.random()),
|
|
1443
|
+
fitness: 0
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
evolve(fitnessFunction, generations = 50) {
|
|
1449
|
+
for (let g = 0; g < generations; g++) {
|
|
1450
|
+
// Evaluate fitness
|
|
1451
|
+
for (const agent of this.population) {
|
|
1452
|
+
agent.fitness = fitnessFunction(agent.genes);
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
// Sort by fitness
|
|
1456
|
+
this.population.sort((a, b) => b.fitness - a.fitness);
|
|
1457
|
+
|
|
1458
|
+
// Selection and reproduction
|
|
1459
|
+
const elite = this.population.slice(0, 5);
|
|
1460
|
+
const children = [];
|
|
1461
|
+
|
|
1462
|
+
while (children.length < this.population.length - elite.length) {
|
|
1463
|
+
const parent1 = elite[Math.floor(Math.random() * elite.length)];
|
|
1464
|
+
const parent2 = elite[Math.floor(Math.random() * elite.length)];
|
|
1465
|
+
children.push(this.crossover(parent1, parent2));
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
this.population = [...elite, ...children];
|
|
1469
|
+
this.generation++;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
return this.population[0]; // Best agent
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
crossover(parent1, parent2) {
|
|
1476
|
+
const child = {
|
|
1477
|
+
identity: WasmIdentity.generate(),
|
|
1478
|
+
genes: [],
|
|
1479
|
+
fitness: 0
|
|
1480
|
+
};
|
|
1481
|
+
|
|
1482
|
+
for (let i = 0; i < parent1.genes.length; i++) {
|
|
1483
|
+
child.genes[i] = Math.random() > 0.5 ? parent1.genes[i] : parent2.genes[i];
|
|
1484
|
+
// Mutation
|
|
1485
|
+
if (Math.random() < 0.1) {
|
|
1486
|
+
child.genes[i] += (Math.random() - 0.5) * 0.2;
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
return child;
|
|
1491
|
+
}
|
|
1492
|
+
}`
|
|
1493
|
+
}
|
|
1494
|
+
};
|
|
1495
|
+
|
|
1496
|
+
// Generate code
|
|
1497
|
+
function generateCode() {
|
|
1498
|
+
const hasMultipleModules = state.modules.length > 1 || !state.modules.includes('edge');
|
|
1499
|
+
const packageName = hasMultipleModules ? '@ruvector/edge-full' : '@ruvector/edge';
|
|
1500
|
+
|
|
1501
|
+
let code = `// ${packageName} - Generated Swarm Configuration
|
|
1502
|
+
// Topology: ${state.topology} | Transport: ${state.transport} | Use Case: ${state.usecase}
|
|
1503
|
+
// Modules: ${state.modules.join(', ')} | Features: ${state.features.join(', ')}${state.exotic.length ? '\n// Exotic: ' + state.exotic.join(', ') : ''}
|
|
1504
|
+
`;
|
|
1505
|
+
|
|
1506
|
+
// Generate imports based on selected modules
|
|
1507
|
+
if (state.modules.includes('edge')) {
|
|
1508
|
+
code += `
|
|
1509
|
+
import init, {
|
|
1510
|
+
WasmIdentity,
|
|
1511
|
+
WasmCrypto,
|
|
1512
|
+
${state.features.includes('hnsw') ? ' WasmHnswIndex,\n' : ''}${state.features.includes('semantic') ? ' WasmSemanticMatcher,\n' : ''}${state.features.includes('raft') ? ' WasmRaftNode,\n' : ''}${state.features.includes('pq') ? ' WasmHybridKeyPair,\n' : ''}${state.features.includes('spiking') ? ' WasmSpikingNetwork,\n' : ''}${state.features.includes('compression') ? ' WasmQuantizer,\n WasmAdaptiveCompressor,\n' : ''}} from '${packageName}${hasMultipleModules ? '/edge' : ''}';
|
|
1513
|
+
`;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
if (state.modules.includes('graph')) {
|
|
1517
|
+
code += `
|
|
1518
|
+
import graphInit, { WasmGraphStore } from '${packageName}/graph';
|
|
1519
|
+
`;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
if (state.modules.includes('rvlite')) {
|
|
1523
|
+
code += `
|
|
1524
|
+
import rvliteInit, { Database } from '${packageName}/rvlite';
|
|
1525
|
+
`;
|
|
1526
|
+
}
|
|
1527
|
+
|
|
1528
|
+
if (state.modules.includes('sona')) {
|
|
1529
|
+
code += `
|
|
1530
|
+
import sonaInit, { SonaEngine, ReasoningBank } from '${packageName}/sona';
|
|
1531
|
+
`;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
if (state.modules.includes('dag')) {
|
|
1535
|
+
code += `
|
|
1536
|
+
import dagInit, { Dag } from '${packageName}/dag';
|
|
1537
|
+
`;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
if (state.modules.includes('onnx')) {
|
|
1541
|
+
code += `
|
|
1542
|
+
import onnxInit, { WasmEmbedder } from '${packageName}/onnx';
|
|
1543
|
+
`;
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
// Init calls
|
|
1547
|
+
code += `
|
|
1548
|
+
// Initialize WASM modules
|
|
1549
|
+
await Promise.all([
|
|
1550
|
+
${state.modules.includes('edge') ? ' init(),\n' : ''}${state.modules.includes('graph') ? ' graphInit(),\n' : ''}${state.modules.includes('rvlite') ? ' rvliteInit(),\n' : ''}${state.modules.includes('sona') ? ' sonaInit(),\n' : ''}${state.modules.includes('dag') ? ' dagInit(),\n' : ''}${state.modules.includes('onnx') ? ' onnxInit(),\n' : ''}]);
|
|
1551
|
+
`;
|
|
1552
|
+
|
|
1553
|
+
// Add topology section
|
|
1554
|
+
code += `
|
|
1555
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1556
|
+
// TOPOLOGY: ${state.topology.toUpperCase()}
|
|
1557
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1558
|
+
|
|
1559
|
+
${templates.topologies[state.topology]}
|
|
1560
|
+
|
|
1561
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1562
|
+
// TRANSPORT: ${state.transport.toUpperCase()}
|
|
1563
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1564
|
+
|
|
1565
|
+
${templates.transports[state.transport]}
|
|
1566
|
+
|
|
1567
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1568
|
+
// USE CASE: ${state.usecase.toUpperCase().replace('-', ' ')}
|
|
1569
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1570
|
+
|
|
1571
|
+
${templates.usecases[state.usecase]}`;
|
|
1572
|
+
|
|
1573
|
+
// Add module-specific sections
|
|
1574
|
+
if (state.modules.includes('graph')) {
|
|
1575
|
+
code += `
|
|
1576
|
+
|
|
1577
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1578
|
+
// GRAPH DATABASE (Neo4j-style)
|
|
1579
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1580
|
+
|
|
1581
|
+
class SwarmGraph {
|
|
1582
|
+
constructor() {
|
|
1583
|
+
this.store = new WasmGraphStore();
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
// Create agent nodes
|
|
1587
|
+
addAgent(id, type, capabilities) {
|
|
1588
|
+
this.store.run_cypher(\`CREATE (a:Agent {id: '\${id}', type: '\${type}'})\`);
|
|
1589
|
+
capabilities.forEach(cap => {
|
|
1590
|
+
this.store.run_cypher(\`MATCH (a:Agent {id: '\${id}'}) CREATE (a)-[:HAS_CAPABILITY]->(:Capability {name: '\${cap}'})\`);
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
// Query connected agents
|
|
1595
|
+
findConnectedAgents(agentId) {
|
|
1596
|
+
return this.store.run_cypher(\`MATCH (a:Agent {id: '\${agentId}'})-[:CONNECTED_TO]->(b:Agent) RETURN b\`);
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
// Build agent relationship graph
|
|
1600
|
+
connect(fromId, toId, relationship = 'CONNECTED_TO') {
|
|
1601
|
+
this.store.run_cypher(\`MATCH (a:Agent {id: '\${fromId}'}), (b:Agent {id: '\${toId}'}) CREATE (a)-[:\${relationship}]->(b)\`);
|
|
1602
|
+
}
|
|
1603
|
+
}`;
|
|
1604
|
+
}
|
|
1605
|
+
|
|
1606
|
+
if (state.modules.includes('rvlite')) {
|
|
1607
|
+
code += `
|
|
1608
|
+
|
|
1609
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1610
|
+
// VECTOR DATABASE (SQL/SPARQL/Cypher)
|
|
1611
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1612
|
+
|
|
1613
|
+
class SwarmMemory {
|
|
1614
|
+
constructor() {
|
|
1615
|
+
this.db = new Database();
|
|
1616
|
+
this.db.execute(\`
|
|
1617
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
1618
|
+
id TEXT PRIMARY KEY,
|
|
1619
|
+
agent_id TEXT,
|
|
1620
|
+
content TEXT,
|
|
1621
|
+
embedding BLOB,
|
|
1622
|
+
timestamp INTEGER
|
|
1623
|
+
)
|
|
1624
|
+
\`);
|
|
1625
|
+
}
|
|
1626
|
+
|
|
1627
|
+
// Store memory with embedding
|
|
1628
|
+
async store(agentId, content, embedding) {
|
|
1629
|
+
const id = crypto.randomUUID();
|
|
1630
|
+
this.db.execute(\`INSERT INTO memories VALUES (?, ?, ?, ?, ?)\`,
|
|
1631
|
+
[id, agentId, content, embedding, Date.now()]);
|
|
1632
|
+
return id;
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
// Semantic search across all agent memories
|
|
1636
|
+
async search(queryEmbedding, limit = 10) {
|
|
1637
|
+
return this.db.execute(\`
|
|
1638
|
+
SELECT * FROM memories
|
|
1639
|
+
ORDER BY vector_distance(embedding, ?)
|
|
1640
|
+
LIMIT ?
|
|
1641
|
+
\`, [queryEmbedding, limit]);
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
// SPARQL query for complex relationships
|
|
1645
|
+
sparql(query) {
|
|
1646
|
+
return this.db.sparql(query);
|
|
1647
|
+
}
|
|
1648
|
+
}`;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
if (state.modules.includes('sona')) {
|
|
1652
|
+
code += `
|
|
1653
|
+
|
|
1654
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1655
|
+
// SELF-OPTIMIZING NEURAL ARCHITECTURE (SONA)
|
|
1656
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1657
|
+
|
|
1658
|
+
class SwarmBrain {
|
|
1659
|
+
constructor() {
|
|
1660
|
+
this.engine = new SonaEngine();
|
|
1661
|
+
this.reasoningBank = new ReasoningBank();
|
|
1662
|
+
}
|
|
1663
|
+
|
|
1664
|
+
// Route task to best agent using neural routing
|
|
1665
|
+
async route(task, availableAgents) {
|
|
1666
|
+
const decision = await this.engine.route_request({
|
|
1667
|
+
task,
|
|
1668
|
+
agents: availableAgents.map(a => ({ id: a.id, capabilities: a.capabilities }))
|
|
1669
|
+
});
|
|
1670
|
+
|
|
1671
|
+
// Learn from routing decisions
|
|
1672
|
+
this.reasoningBank.record_trajectory({
|
|
1673
|
+
state: task,
|
|
1674
|
+
action: decision.selected_agent,
|
|
1675
|
+
timestamp: Date.now()
|
|
1676
|
+
});
|
|
1677
|
+
|
|
1678
|
+
return decision;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
// Apply LoRA fine-tuning based on feedback
|
|
1682
|
+
async adapt(feedback) {
|
|
1683
|
+
await this.engine.apply_lora_update({
|
|
1684
|
+
positive_examples: feedback.successes,
|
|
1685
|
+
negative_examples: feedback.failures
|
|
1686
|
+
});
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
// Get routing confidence
|
|
1690
|
+
getConfidence(task) {
|
|
1691
|
+
return this.engine.estimate_confidence(task);
|
|
1692
|
+
}
|
|
1693
|
+
}`;
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
if (state.modules.includes('dag')) {
|
|
1697
|
+
code += `
|
|
1698
|
+
|
|
1699
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1700
|
+
// WORKFLOW DAG (Task Orchestration)
|
|
1701
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1702
|
+
|
|
1703
|
+
class SwarmWorkflow {
|
|
1704
|
+
constructor() {
|
|
1705
|
+
this.dag = new Dag();
|
|
1706
|
+
this.tasks = new Map();
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
// Define workflow steps
|
|
1710
|
+
addStep(id, executor, dependencies = []) {
|
|
1711
|
+
this.dag.add_node(id);
|
|
1712
|
+
this.tasks.set(id, { executor, status: 'pending' });
|
|
1713
|
+
dependencies.forEach(dep => this.dag.add_edge(dep, id));
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
// Get execution order
|
|
1717
|
+
getExecutionOrder() {
|
|
1718
|
+
return this.dag.topological_sort();
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
// Execute workflow
|
|
1722
|
+
async execute() {
|
|
1723
|
+
const order = this.getExecutionOrder();
|
|
1724
|
+
const results = new Map();
|
|
1725
|
+
|
|
1726
|
+
for (const stepId of order) {
|
|
1727
|
+
const task = this.tasks.get(stepId);
|
|
1728
|
+
task.status = 'running';
|
|
1729
|
+
|
|
1730
|
+
// Get results from dependencies
|
|
1731
|
+
const deps = this.dag.get_dependencies(stepId);
|
|
1732
|
+
const depResults = deps.map(d => results.get(d));
|
|
1733
|
+
|
|
1734
|
+
// Execute step
|
|
1735
|
+
results.set(stepId, await task.executor(depResults));
|
|
1736
|
+
task.status = 'complete';
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
return results;
|
|
1740
|
+
}
|
|
1741
|
+
}`;
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
if (state.modules.includes('onnx')) {
|
|
1745
|
+
code += `
|
|
1746
|
+
|
|
1747
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1748
|
+
// ONNX EMBEDDINGS (HuggingFace Models)
|
|
1749
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1750
|
+
|
|
1751
|
+
class SwarmEmbedder {
|
|
1752
|
+
constructor() {
|
|
1753
|
+
this.embedder = null;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
async init(modelName = 'all-MiniLM-L6-v2') {
|
|
1757
|
+
this.embedder = new WasmEmbedder();
|
|
1758
|
+
await this.embedder.load_model(modelName);
|
|
1759
|
+
console.log(\`Loaded embedding model: \${modelName}\`);
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
// Generate embedding for text
|
|
1763
|
+
async embed(text) {
|
|
1764
|
+
return await this.embedder.embed(text);
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
// Batch embed multiple texts (3.8x faster with parallel workers)
|
|
1768
|
+
async embedBatch(texts) {
|
|
1769
|
+
return await this.embedder.embed_batch(texts);
|
|
1770
|
+
}
|
|
1771
|
+
|
|
1772
|
+
// Compute similarity between texts
|
|
1773
|
+
async similarity(text1, text2) {
|
|
1774
|
+
const [emb1, emb2] = await this.embedBatch([text1, text2]);
|
|
1775
|
+
return this.cosineSimilarity(emb1, emb2);
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
cosineSimilarity(a, b) {
|
|
1779
|
+
let dot = 0, normA = 0, normB = 0;
|
|
1780
|
+
for (let i = 0; i < a.length; i++) {
|
|
1781
|
+
dot += a[i] * b[i];
|
|
1782
|
+
normA += a[i] * a[i];
|
|
1783
|
+
normB += b[i] * b[i];
|
|
1784
|
+
}
|
|
1785
|
+
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
1786
|
+
}
|
|
1787
|
+
}`;
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
// Add exotic patterns
|
|
1791
|
+
for (const exotic of state.exotic) {
|
|
1792
|
+
code += `
|
|
1793
|
+
|
|
1794
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1795
|
+
// EXOTIC: ${exotic.toUpperCase().replace('-', ' ')}
|
|
1796
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1797
|
+
|
|
1798
|
+
${templates.exotic[exotic]}`;
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1801
|
+
code += `
|
|
1802
|
+
|
|
1803
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1804
|
+
// MAIN
|
|
1805
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1806
|
+
|
|
1807
|
+
async function main() {
|
|
1808
|
+
console.log('š Swarm initialized');
|
|
1809
|
+
console.log(' Topology: ${state.topology}');
|
|
1810
|
+
console.log(' Transport: ${state.transport}');
|
|
1811
|
+
console.log(' Use Case: ${state.usecase}');
|
|
1812
|
+
console.log(' Cost: $0/month');
|
|
1813
|
+
|
|
1814
|
+
// Initialize your swarm here...
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
main().catch(console.error);`;
|
|
1818
|
+
|
|
1819
|
+
return code;
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
// Highlight code
|
|
1823
|
+
function highlight(code) {
|
|
1824
|
+
return code
|
|
1825
|
+
.replace(/(\/\/.*)/g, '<span class="comment">$1</span>')
|
|
1826
|
+
.replace(/\b(import|from|export|const|let|var|function|class|async|await|return|if|else|for|while|new|this|extends|constructor|static|get|set)\b/g, '<span class="keyword">$1</span>')
|
|
1827
|
+
.replace(/('.*?'|".*?"|`[^`]*`)/g, '<span class="string">$1</span>')
|
|
1828
|
+
.replace(/\b(\d+\.?\d*)\b/g, '<span class="number">$1</span>')
|
|
1829
|
+
.replace(/\b(WasmIdentity|WasmCrypto|WasmHnswIndex|WasmSemanticMatcher|WasmRaftNode|WasmHybridKeyPair|WasmSpikingNetwork|WasmQuantizer|WasmAdaptiveCompressor|Gun|RTCPeerConnection)\b/g, '<span class="const">$1</span>');
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
// Update display
|
|
1833
|
+
function updateCode() {
|
|
1834
|
+
const code = generateCode();
|
|
1835
|
+
document.getElementById('generated-code').innerHTML = highlight(code);
|
|
1836
|
+
}
|
|
1837
|
+
|
|
1838
|
+
// Event handlers
|
|
1839
|
+
function setupHandlers() {
|
|
1840
|
+
// Topology options
|
|
1841
|
+
document.querySelectorAll('#topology-options .option').forEach(el => {
|
|
1842
|
+
el.addEventListener('click', () => {
|
|
1843
|
+
document.querySelectorAll('#topology-options .option').forEach(e => e.classList.remove('selected'));
|
|
1844
|
+
el.classList.add('selected');
|
|
1845
|
+
state.topology = el.dataset.value;
|
|
1846
|
+
updateCode();
|
|
1847
|
+
});
|
|
1848
|
+
});
|
|
1849
|
+
|
|
1850
|
+
// Transport options
|
|
1851
|
+
document.querySelectorAll('#transport-options .option').forEach(el => {
|
|
1852
|
+
el.addEventListener('click', () => {
|
|
1853
|
+
document.querySelectorAll('#transport-options .option').forEach(e => e.classList.remove('selected'));
|
|
1854
|
+
el.classList.add('selected');
|
|
1855
|
+
state.transport = el.dataset.value;
|
|
1856
|
+
|
|
1857
|
+
// Update latency estimate
|
|
1858
|
+
const latencies = { gun: '~100ms', webrtc: '~50ms', libp2p: '~200ms', nostr: '~150ms' };
|
|
1859
|
+
document.getElementById('msg-latency').textContent = latencies[state.transport];
|
|
1860
|
+
|
|
1861
|
+
updateCode();
|
|
1862
|
+
});
|
|
1863
|
+
});
|
|
1864
|
+
|
|
1865
|
+
// Use case options
|
|
1866
|
+
document.querySelectorAll('#usecase-options .option').forEach(el => {
|
|
1867
|
+
el.addEventListener('click', () => {
|
|
1868
|
+
document.querySelectorAll('#usecase-options .option').forEach(e => e.classList.remove('selected'));
|
|
1869
|
+
el.classList.add('selected');
|
|
1870
|
+
state.usecase = el.dataset.value;
|
|
1871
|
+
updateCode();
|
|
1872
|
+
});
|
|
1873
|
+
});
|
|
1874
|
+
|
|
1875
|
+
// Module options (multi-select)
|
|
1876
|
+
document.querySelectorAll('#module-options .option').forEach(el => {
|
|
1877
|
+
el.addEventListener('click', () => {
|
|
1878
|
+
el.classList.toggle('selected');
|
|
1879
|
+
const value = el.dataset.value;
|
|
1880
|
+
if (el.classList.contains('selected')) {
|
|
1881
|
+
if (!state.modules.includes(value)) {
|
|
1882
|
+
state.modules.push(value);
|
|
1883
|
+
}
|
|
1884
|
+
} else {
|
|
1885
|
+
state.modules = state.modules.filter(m => m !== value);
|
|
1886
|
+
// Always keep at least edge
|
|
1887
|
+
if (state.modules.length === 0) {
|
|
1888
|
+
state.modules = ['edge'];
|
|
1889
|
+
document.querySelector('#module-options .option[data-value="edge"]').classList.add('selected');
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
updateBundleSize();
|
|
1893
|
+
updateCode();
|
|
1894
|
+
});
|
|
1895
|
+
});
|
|
1896
|
+
|
|
1897
|
+
// Feature tags
|
|
1898
|
+
document.querySelectorAll('#feature-tags .tag').forEach(el => {
|
|
1899
|
+
el.addEventListener('click', () => {
|
|
1900
|
+
el.classList.toggle('selected');
|
|
1901
|
+
const value = el.dataset.value;
|
|
1902
|
+
if (el.classList.contains('selected')) {
|
|
1903
|
+
state.features.push(value);
|
|
1904
|
+
} else {
|
|
1905
|
+
state.features = state.features.filter(f => f !== value);
|
|
1906
|
+
}
|
|
1907
|
+
updateCode();
|
|
1908
|
+
});
|
|
1909
|
+
});
|
|
1910
|
+
|
|
1911
|
+
// Exotic tags
|
|
1912
|
+
document.querySelectorAll('#exotic-tags .tag').forEach(el => {
|
|
1913
|
+
el.addEventListener('click', () => {
|
|
1914
|
+
el.classList.toggle('selected');
|
|
1915
|
+
const value = el.dataset.value;
|
|
1916
|
+
if (el.classList.contains('selected')) {
|
|
1917
|
+
state.exotic.push(value);
|
|
1918
|
+
} else {
|
|
1919
|
+
state.exotic = state.exotic.filter(e => e !== value);
|
|
1920
|
+
}
|
|
1921
|
+
updateCode();
|
|
1922
|
+
});
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
// Copy code
|
|
1927
|
+
window.copyCode = function() {
|
|
1928
|
+
const code = generateCode();
|
|
1929
|
+
navigator.clipboard.writeText(code);
|
|
1930
|
+
const btn = document.querySelector('.copy-btn');
|
|
1931
|
+
btn.textContent = 'ā Copied!';
|
|
1932
|
+
setTimeout(() => btn.textContent = 'š Copy Code', 2000);
|
|
1933
|
+
};
|
|
1934
|
+
|
|
1935
|
+
// Run demo
|
|
1936
|
+
window.runDemo = async function() {
|
|
1937
|
+
if (!wasmReady) {
|
|
1938
|
+
document.getElementById('demo-output').textContent = 'WASM not loaded yet...';
|
|
1939
|
+
return;
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
const output = document.getElementById('demo-output');
|
|
1943
|
+
output.textContent = 'š Running live demo...\n\n';
|
|
1944
|
+
|
|
1945
|
+
try {
|
|
1946
|
+
// Create identity
|
|
1947
|
+
const identity = WasmIdentity.generate();
|
|
1948
|
+
output.textContent += `ā Identity created: ${identity.agent_id().slice(0, 16)}...\n`;
|
|
1949
|
+
|
|
1950
|
+
// Test crypto
|
|
1951
|
+
const crypto = new WasmCrypto();
|
|
1952
|
+
const key = crypto.generate_key();
|
|
1953
|
+
const msg = new TextEncoder().encode('Hello Swarm!');
|
|
1954
|
+
const encrypted = crypto.encrypt(key, msg);
|
|
1955
|
+
const decrypted = crypto.decrypt(key, encrypted);
|
|
1956
|
+
output.textContent += `ā Encryption working: ${encrypted.length} bytes\n`;
|
|
1957
|
+
|
|
1958
|
+
// Test signing
|
|
1959
|
+
const sig = identity.sign(msg);
|
|
1960
|
+
const valid = identity.verify(msg, sig);
|
|
1961
|
+
output.textContent += `ā Signature valid: ${valid}\n`;
|
|
1962
|
+
|
|
1963
|
+
// Test features
|
|
1964
|
+
if (state.features.includes('hnsw')) {
|
|
1965
|
+
const index = new WasmHnswIndex(128, 16, 200);
|
|
1966
|
+
index.insert('test', new Float32Array(128).fill(0.5));
|
|
1967
|
+
output.textContent += `ā HNSW index: ${index.len()} vectors\n`;
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
if (state.features.includes('semantic')) {
|
|
1971
|
+
const matcher = new WasmSemanticMatcher();
|
|
1972
|
+
matcher.register_agent('coder', 'programming code');
|
|
1973
|
+
matcher.register_agent('writer', 'documentation writing');
|
|
1974
|
+
const best = matcher.find_best_agent('write some code');
|
|
1975
|
+
output.textContent += `ā Semantic match: "${best}"\n`;
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1978
|
+
if (state.features.includes('raft')) {
|
|
1979
|
+
const raft = new WasmRaftNode('node-1', ['node-1', 'node-2', 'node-3']);
|
|
1980
|
+
raft.start_election();
|
|
1981
|
+
output.textContent += `ā Raft state: ${raft.state()}, term: ${raft.current_term()}\n`;
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
if (state.features.includes('pq')) {
|
|
1985
|
+
const hybrid = WasmHybridKeyPair.generate();
|
|
1986
|
+
const pqSig = hybrid.sign(msg);
|
|
1987
|
+
output.textContent += `ā Post-quantum sig: ${pqSig.length} bytes\n`;
|
|
1988
|
+
}
|
|
1989
|
+
|
|
1990
|
+
if (state.features.includes('spiking')) {
|
|
1991
|
+
const net = new WasmSpikingNetwork(4, 8, 2);
|
|
1992
|
+
const spikes = net.forward([true, false, true, false]);
|
|
1993
|
+
output.textContent += `ā Spiking network: ${spikes.length} outputs\n`;
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
output.textContent += `\nš Demo complete! Topology: ${state.topology}, Transport: ${state.transport}\n`;
|
|
1997
|
+
output.textContent += `š° Monthly cost: $0`;
|
|
1998
|
+
|
|
1999
|
+
} catch (err) {
|
|
2000
|
+
output.textContent += `\nā Error: ${err.message}`;
|
|
2001
|
+
}
|
|
2002
|
+
};
|
|
2003
|
+
|
|
2004
|
+
// Initialize
|
|
2005
|
+
setupHandlers();
|
|
2006
|
+
updateCode();
|
|
2007
|
+
</script>
|
|
2008
|
+
</body>
|
|
2009
|
+
</html>
|