web-agent-bridge 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.ar.md +7 -0
  2. package/README.md +7 -0
  3. package/package.json +12 -4
  4. package/public/commander-dashboard.html +243 -0
  5. package/public/css/premium.css +317 -317
  6. package/public/demo.html +259 -259
  7. package/public/index.html +644 -592
  8. package/public/llms.txt +1 -0
  9. package/public/mesh-dashboard.html +328 -0
  10. package/public/premium-dashboard.html +2487 -2487
  11. package/public/premium.html +791 -791
  12. package/public/script/wab.min.js +181 -6
  13. package/script/ai-agent-bridge.js +196 -0
  14. package/sdk/agent-mesh.js +449 -0
  15. package/sdk/commander.js +262 -0
  16. package/sdk/index.js +260 -259
  17. package/sdk/package.json +1 -1
  18. package/server/index.js +13 -1
  19. package/server/migrations/002_premium_features.sql +418 -418
  20. package/server/models/db.js +24 -5
  21. package/server/routes/admin-premium.js +671 -671
  22. package/server/routes/commander.js +316 -0
  23. package/server/routes/mesh.js +469 -0
  24. package/server/routes/premium-v2.js +686 -686
  25. package/server/routes/premium.js +724 -724
  26. package/server/services/agent-learning.js +575 -0
  27. package/server/services/agent-memory.js +625 -625
  28. package/server/services/agent-mesh.js +539 -0
  29. package/server/services/agent-symphony.js +711 -0
  30. package/server/services/commander.js +738 -0
  31. package/server/services/edge-compute.js +440 -0
  32. package/server/services/local-ai.js +389 -0
  33. package/server/services/plugins.js +747 -747
  34. package/server/services/self-healing.js +843 -843
  35. package/server/services/swarm.js +788 -788
  36. package/server/services/vision.js +871 -871
  37. package/public/admin/dashboard.html +0 -848
  38. package/public/admin/login.html +0 -84
  39. package/public/video/tutorial.mp4 +0 -0
@@ -0,0 +1,316 @@
1
+ /**
2
+ * Commander Routes — REST API for the Commander Agent System
3
+ *
4
+ * Exposes commander, edge computing, and local AI services through
5
+ * RESTful endpoints. All routes are site-scoped.
6
+ *
7
+ * Sections:
8
+ * /missions — Mission lifecycle (create, launch, list, get)
9
+ * /agents — Commander agent registry
10
+ * /edge — Edge computing node management
11
+ * /local-ai — Local model discovery and inference
12
+ * /stats — Unified statistics
13
+ */
14
+
15
+ const express = require('express');
16
+ const router = express.Router();
17
+
18
+ const commander = require('../services/commander');
19
+ const edge = require('../services/edge-compute');
20
+ const localAI = require('../services/local-ai');
21
+
22
+ // ─── Helpers ─────────────────────────────────────────────────────────
23
+
24
+ function ok(res, data) { res.json({ ok: true, ...data }); }
25
+ function fail(res, status, message) { res.status(status).json({ ok: false, error: message }); }
26
+
27
+ function requireBody(req, res, ...fields) {
28
+ for (const f of fields) {
29
+ if (req.body[f] === undefined || req.body[f] === null) {
30
+ fail(res, 400, `Missing required field: ${f}`);
31
+ return false;
32
+ }
33
+ }
34
+ return true;
35
+ }
36
+
37
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
38
+ // MISSIONS — Task Decomposition & Orchestration
39
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
40
+
41
+ // Launch a full mission (create + execute)
42
+ router.post('/missions/launch', async (req, res) => {
43
+ try {
44
+ if (!requireBody(req, res, 'goal')) return;
45
+ const { siteId, goal, title, strategy, priority, context } = req.body;
46
+ const result = await commander.launchMission(siteId || 'default', title || goal.substring(0, 80), goal, {
47
+ strategy, priority, context,
48
+ });
49
+ ok(res, { mission: result });
50
+ } catch (e) { fail(res, 500, e.message); }
51
+ });
52
+
53
+ // Create a mission (plan only, no execution)
54
+ router.post('/missions', (req, res) => {
55
+ try {
56
+ if (!requireBody(req, res, 'goal')) return;
57
+ const { siteId, goal, title, strategy, priority, context } = req.body;
58
+ const mission = commander.createMission(siteId || 'default', title || goal.substring(0, 80), goal, {
59
+ strategy, priority, context,
60
+ });
61
+ ok(res, { mission });
62
+ } catch (e) { fail(res, 500, e.message); }
63
+ });
64
+
65
+ // Execute an existing mission
66
+ router.post('/missions/:id/execute', async (req, res) => {
67
+ try {
68
+ const result = await commander.executeMission(req.params.id);
69
+ ok(res, { mission: result });
70
+ } catch (e) { fail(res, 500, e.message); }
71
+ });
72
+
73
+ // Get a single mission
74
+ router.get('/missions/:id', (req, res) => {
75
+ try {
76
+ const mission = commander.getMission(req.params.id);
77
+ if (!mission) return fail(res, 404, 'Mission not found');
78
+ ok(res, { mission });
79
+ } catch (e) { fail(res, 500, e.message); }
80
+ });
81
+
82
+ // Get mission tasks
83
+ router.get('/missions/:id/tasks', (req, res) => {
84
+ try {
85
+ const tasks = commander.getMissionTasks(req.params.id);
86
+ ok(res, { tasks });
87
+ } catch (e) { fail(res, 500, e.message); }
88
+ });
89
+
90
+ // List missions
91
+ router.get('/missions', (req, res) => {
92
+ try {
93
+ const siteId = req.query.siteId || 'default';
94
+ const missions = req.query.active === 'true'
95
+ ? commander.getActiveMissions(siteId)
96
+ : commander.getMissions(siteId, parseInt(req.query.limit) || 50);
97
+ ok(res, { missions });
98
+ } catch (e) { fail(res, 500, e.message); }
99
+ });
100
+
101
+ // Get decomposition strategies
102
+ router.get('/strategies', (req, res) => {
103
+ try {
104
+ ok(res, { strategies: commander.getStrategies() });
105
+ } catch (e) { fail(res, 500, e.message); }
106
+ });
107
+
108
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
109
+ // AGENTS — Commander Agent Registry
110
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
111
+
112
+ router.post('/agents', (req, res) => {
113
+ try {
114
+ if (!requireBody(req, res, 'agentType')) return;
115
+ const { siteId, agentType, displayName, capabilities, modelInfo, hardware } = req.body;
116
+ const agent = commander.registerAgent(siteId || 'default', agentType, displayName, capabilities, modelInfo, hardware);
117
+ ok(res, { agent });
118
+ } catch (e) { fail(res, 500, e.message); }
119
+ });
120
+
121
+ router.get('/agents', (req, res) => {
122
+ try {
123
+ const siteId = req.query.siteId || 'default';
124
+ const agents = req.query.capability
125
+ ? commander.getAgentsByCapability(siteId, req.query.capability)
126
+ : commander.getAgents(siteId);
127
+ ok(res, { agents });
128
+ } catch (e) { fail(res, 500, e.message); }
129
+ });
130
+
131
+ router.post('/agents/:id/heartbeat', (req, res) => {
132
+ try {
133
+ commander.agentHeartbeat(req.params.id);
134
+ ok(res, { alive: true });
135
+ } catch (e) { fail(res, 500, e.message); }
136
+ });
137
+
138
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
139
+ // EDGE — Distributed Computing Nodes
140
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
141
+
142
+ // Register an edge node
143
+ router.post('/edge/nodes', (req, res) => {
144
+ try {
145
+ if (!requireBody(req, res, 'hostname')) return;
146
+ const { siteId, hostname, hardware, capabilities } = req.body;
147
+ const node = edge.registerNode(siteId || 'default', hostname, hardware, capabilities);
148
+ ok(res, { node });
149
+ } catch (e) { fail(res, 500, e.message); }
150
+ });
151
+
152
+ // List edge nodes
153
+ router.get('/edge/nodes', (req, res) => {
154
+ try {
155
+ const siteId = req.query.siteId || 'default';
156
+ const nodes = req.query.available === 'true'
157
+ ? edge.getAvailableNodes(siteId)
158
+ : edge.getNodes(siteId);
159
+ ok(res, { nodes });
160
+ } catch (e) { fail(res, 500, e.message); }
161
+ });
162
+
163
+ // Node heartbeat
164
+ router.post('/edge/nodes/:id/heartbeat', (req, res) => {
165
+ try {
166
+ edge.nodeHeartbeat(req.params.id, req.body.currentLoad || 0);
167
+ ok(res, { alive: true });
168
+ } catch (e) { fail(res, 500, e.message); }
169
+ });
170
+
171
+ // Remove node
172
+ router.delete('/edge/nodes/:id', (req, res) => {
173
+ try {
174
+ edge.removeNode(req.params.id);
175
+ ok(res, { removed: req.params.id });
176
+ } catch (e) { fail(res, 500, e.message); }
177
+ });
178
+
179
+ // Submit a task for edge execution
180
+ router.post('/edge/tasks', (req, res) => {
181
+ try {
182
+ if (!requireBody(req, res, 'taskType', 'payload')) return;
183
+ const { taskType, payload, priority, missionId, encrypt, encryptionKey } = req.body;
184
+ const task = edge.submitTask(taskType, payload, { priority, missionId, encrypt, encryptionKey });
185
+ ok(res, { task });
186
+ } catch (e) { fail(res, 500, e.message); }
187
+ });
188
+
189
+ // Distribute queued tasks to available nodes
190
+ router.post('/edge/distribute', (req, res) => {
191
+ try {
192
+ const siteId = req.body.siteId || 'default';
193
+ const result = edge.distributeTask(siteId);
194
+ ok(res, result);
195
+ } catch (e) { fail(res, 500, e.message); }
196
+ });
197
+
198
+ // Complete a task (called by the executing node)
199
+ router.post('/edge/tasks/:id/complete', (req, res) => {
200
+ try {
201
+ const { result, success } = req.body;
202
+ const outcome = edge.completeTask(req.params.id, result, success !== false);
203
+ ok(res, outcome);
204
+ } catch (e) { fail(res, 500, e.message); }
205
+ });
206
+
207
+ // Get tasks for a specific node
208
+ router.get('/edge/tasks', (req, res) => {
209
+ try {
210
+ if (req.query.nodeId) {
211
+ ok(res, { tasks: edge.getNodeTasks(req.query.nodeId) });
212
+ } else if (req.query.missionId) {
213
+ const task = edge.getTask(req.query.missionId);
214
+ ok(res, { tasks: task ? [task] : [] });
215
+ } else {
216
+ fail(res, 400, 'Provide nodeId or missionId query param');
217
+ }
218
+ } catch (e) { fail(res, 500, e.message); }
219
+ });
220
+
221
+ // Get edge swarms
222
+ router.get('/edge/swarms', (req, res) => {
223
+ try {
224
+ const siteId = req.query.siteId || 'default';
225
+ const swarms = req.query.capability
226
+ ? [edge.getSwarmByCapability(siteId, req.query.capability)].filter(Boolean)
227
+ : edge.getSwarms(siteId);
228
+ ok(res, { swarms });
229
+ } catch (e) { fail(res, 500, e.message); }
230
+ });
231
+
232
+ // Edge stats
233
+ router.get('/edge/stats', (req, res) => {
234
+ try {
235
+ ok(res, edge.getStats(req.query.siteId || 'default'));
236
+ } catch (e) { fail(res, 500, e.message); }
237
+ });
238
+
239
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
240
+ // LOCAL AI — Sovereign Model Management
241
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
242
+
243
+ // Discover local models (probe Ollama, llama.cpp, etc.)
244
+ router.post('/local-ai/discover', async (req, res) => {
245
+ try {
246
+ const siteId = req.body.siteId || 'default';
247
+ const result = await localAI.discoverModels(siteId, req.body.customEndpoints);
248
+ ok(res, result);
249
+ } catch (e) { fail(res, 500, e.message); }
250
+ });
251
+
252
+ // Register a model manually
253
+ router.post('/local-ai/models', (req, res) => {
254
+ try {
255
+ if (!requireBody(req, res, 'provider', 'modelName', 'endpoint')) return;
256
+ const { siteId, provider, modelName, endpoint, capabilities, contextWindow } = req.body;
257
+ const model = localAI.registerModel(siteId || 'default', provider, modelName, endpoint, capabilities, contextWindow);
258
+ ok(res, { model });
259
+ } catch (e) { fail(res, 500, e.message); }
260
+ });
261
+
262
+ // Run inference
263
+ router.post('/local-ai/infer', async (req, res) => {
264
+ try {
265
+ if (!requireBody(req, res, 'prompt')) return;
266
+ const { siteId, prompt, capability, modelId, systemPrompt, temperature, maxTokens } = req.body;
267
+ const result = await localAI.infer(siteId || 'default', prompt, {
268
+ capability, modelId, systemPrompt, temperature, maxTokens,
269
+ });
270
+ ok(res, { result });
271
+ } catch (e) { fail(res, 500, e.message); }
272
+ });
273
+
274
+ // List models
275
+ router.get('/local-ai/models', (req, res) => {
276
+ try {
277
+ const siteId = req.query.siteId || 'default';
278
+ const models = req.query.available === 'true'
279
+ ? localAI.getAvailableModels(siteId)
280
+ : localAI.getModels(siteId);
281
+ ok(res, { models });
282
+ } catch (e) { fail(res, 500, e.message); }
283
+ });
284
+
285
+ // Update model status
286
+ router.patch('/local-ai/models/:id', (req, res) => {
287
+ try {
288
+ if (!requireBody(req, res, 'status')) return;
289
+ localAI.updateModelStatus(req.params.id, req.body.status);
290
+ ok(res, { updated: req.params.id });
291
+ } catch (e) { fail(res, 500, e.message); }
292
+ });
293
+
294
+ // Local AI stats
295
+ router.get('/local-ai/stats', (req, res) => {
296
+ try {
297
+ ok(res, localAI.getStats(req.query.siteId || 'default'));
298
+ } catch (e) { fail(res, 500, e.message); }
299
+ });
300
+
301
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
302
+ // UNIFIED STATS
303
+ // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
304
+
305
+ router.get('/stats', (req, res) => {
306
+ try {
307
+ const siteId = req.query.siteId || 'default';
308
+ ok(res, {
309
+ commander: commander.getStats(siteId),
310
+ edge: edge.getStats(siteId),
311
+ localAI: localAI.getStats(siteId),
312
+ });
313
+ } catch (e) { fail(res, 500, e.message); }
314
+ });
315
+
316
+ module.exports = router;