@jungjaehoon/mama-os 0.18.2 → 0.19.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/dist/agent/agent-loop.d.ts +25 -0
- package/dist/agent/agent-loop.d.ts.map +1 -1
- package/dist/agent/agent-loop.js +67 -14
- package/dist/agent/agent-loop.js.map +1 -1
- package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
- package/dist/agent/code-act/host-bridge.js +98 -0
- package/dist/agent/code-act/host-bridge.js.map +1 -1
- package/dist/agent/code-act/type-definition-generator.d.ts.map +1 -1
- package/dist/agent/code-act/type-definition-generator.js +0 -1
- package/dist/agent/code-act/type-definition-generator.js.map +1 -1
- package/dist/agent/gateway-tool-executor.d.ts +36 -1
- package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
- package/dist/agent/gateway-tool-executor.js +938 -54
- package/dist/agent/gateway-tool-executor.js.map +1 -1
- package/dist/agent/gateway-tools.md +9 -0
- package/dist/agent/managed-agent-runtime-sync.d.ts +36 -0
- package/dist/agent/managed-agent-runtime-sync.d.ts.map +1 -0
- package/dist/agent/managed-agent-runtime-sync.js +207 -0
- package/dist/agent/managed-agent-runtime-sync.js.map +1 -0
- package/dist/agent/managed-agent-validation.d.ts +4 -0
- package/dist/agent/managed-agent-validation.d.ts.map +1 -0
- package/dist/agent/managed-agent-validation.js +84 -0
- package/dist/agent/managed-agent-validation.js.map +1 -0
- package/dist/agent/os-agent-capabilities.md +400 -0
- package/dist/agent/skill-loader.d.ts +2 -0
- package/dist/agent/skill-loader.d.ts.map +1 -1
- package/dist/agent/skill-loader.js +28 -0
- package/dist/agent/skill-loader.js.map +1 -1
- package/dist/agent/tool-registry.d.ts.map +1 -1
- package/dist/agent/tool-registry.js +66 -0
- package/dist/agent/tool-registry.js.map +1 -1
- package/dist/agent/types.d.ts +2 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/api/agent-handler.d.ts +34 -0
- package/dist/api/agent-handler.d.ts.map +1 -0
- package/dist/api/agent-handler.js +216 -0
- package/dist/api/agent-handler.js.map +1 -0
- package/dist/api/graph-api-types.d.ts +4 -0
- package/dist/api/graph-api-types.d.ts.map +1 -1
- package/dist/api/graph-api.d.ts +2 -2
- package/dist/api/graph-api.d.ts.map +1 -1
- package/dist/api/graph-api.js +480 -51
- package/dist/api/graph-api.js.map +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +4 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/token-handler.d.ts +1 -0
- package/dist/api/token-handler.d.ts.map +1 -1
- package/dist/api/token-handler.js +4 -3
- package/dist/api/token-handler.js.map +1 -1
- package/dist/api/ui-command-handler.d.ts +48 -0
- package/dist/api/ui-command-handler.d.ts.map +1 -0
- package/dist/api/ui-command-handler.js +160 -0
- package/dist/api/ui-command-handler.js.map +1 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +127 -1
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/config/config-manager.d.ts.map +1 -1
- package/dist/cli/config/config-manager.js +16 -31
- package/dist/cli/config/config-manager.js.map +1 -1
- package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
- package/dist/cli/runtime/agent-loop-init.js +31 -7
- package/dist/cli/runtime/agent-loop-init.js.map +1 -1
- package/dist/cli/runtime/api-routes-init.d.ts +3 -0
- package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
- package/dist/cli/runtime/api-routes-init.js +283 -34
- package/dist/cli/runtime/api-routes-init.js.map +1 -1
- package/dist/cli/runtime/gateway-init.d.ts +2 -1
- package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
- package/dist/cli/runtime/gateway-init.js +5 -1
- package/dist/cli/runtime/gateway-init.js.map +1 -1
- package/dist/connectors/framework/raw-store.d.ts +4 -0
- package/dist/connectors/framework/raw-store.d.ts.map +1 -1
- package/dist/connectors/framework/raw-store.js +33 -10
- package/dist/connectors/framework/raw-store.js.map +1 -1
- package/dist/db/agent-store.d.ts +115 -0
- package/dist/db/agent-store.d.ts.map +1 -0
- package/dist/db/agent-store.js +248 -0
- package/dist/db/agent-store.js.map +1 -0
- package/dist/db/migrations/agent-activity-validation-columns.d.ts +3 -0
- package/dist/db/migrations/agent-activity-validation-columns.d.ts.map +1 -0
- package/dist/db/migrations/agent-activity-validation-columns.js +22 -0
- package/dist/db/migrations/agent-activity-validation-columns.js.map +1 -0
- package/dist/db/migrations/agent-metrics-response-avg.d.ts +3 -0
- package/dist/db/migrations/agent-metrics-response-avg.d.ts.map +1 -0
- package/dist/db/migrations/agent-metrics-response-avg.js +19 -0
- package/dist/db/migrations/agent-metrics-response-avg.js.map +1 -0
- package/dist/db/migrations/agent-store-tables.d.ts +3 -0
- package/dist/db/migrations/agent-store-tables.d.ts.map +1 -0
- package/dist/db/migrations/agent-store-tables.js +59 -0
- package/dist/db/migrations/agent-store-tables.js.map +1 -0
- package/dist/db/migrations/token-usage-agent-version.d.ts +3 -0
- package/dist/db/migrations/token-usage-agent-version.d.ts.map +1 -0
- package/dist/db/migrations/token-usage-agent-version.js +16 -0
- package/dist/db/migrations/token-usage-agent-version.js.map +1 -0
- package/dist/db/migrations/validation-session-tables.d.ts +3 -0
- package/dist/db/migrations/validation-session-tables.d.ts.map +1 -0
- package/dist/db/migrations/validation-session-tables.js +59 -0
- package/dist/db/migrations/validation-session-tables.js.map +1 -0
- package/dist/gateways/message-router.d.ts +10 -0
- package/dist/gateways/message-router.d.ts.map +1 -1
- package/dist/gateways/message-router.js +188 -14
- package/dist/gateways/message-router.js.map +1 -1
- package/dist/gateways/types.d.ts +1 -1
- package/dist/gateways/types.d.ts.map +1 -1
- package/dist/multi-agent/agent-process-manager.js +1 -1
- package/dist/multi-agent/agent-process-manager.js.map +1 -1
- package/dist/multi-agent/conductor-persona.d.ts +13 -0
- package/dist/multi-agent/conductor-persona.d.ts.map +1 -0
- package/dist/multi-agent/conductor-persona.js +157 -0
- package/dist/multi-agent/conductor-persona.js.map +1 -0
- package/dist/multi-agent/dashboard-agent-persona.d.ts +1 -1
- package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
- package/dist/multi-agent/dashboard-agent-persona.js +7 -3
- package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
- package/dist/multi-agent/delegation-manager.d.ts +5 -0
- package/dist/multi-agent/delegation-manager.d.ts.map +1 -1
- package/dist/multi-agent/delegation-manager.js +37 -0
- package/dist/multi-agent/delegation-manager.js.map +1 -1
- package/dist/multi-agent/ultrawork.d.ts +3 -0
- package/dist/multi-agent/ultrawork.d.ts.map +1 -1
- package/dist/multi-agent/ultrawork.js +9 -0
- package/dist/multi-agent/ultrawork.js.map +1 -1
- package/dist/validation/session-service.d.ts +72 -0
- package/dist/validation/session-service.d.ts.map +1 -0
- package/dist/validation/session-service.js +298 -0
- package/dist/validation/session-service.js.map +1 -0
- package/dist/validation/store.d.ts +25 -0
- package/dist/validation/store.d.ts.map +1 -0
- package/dist/validation/store.js +200 -0
- package/dist/validation/store.js.map +1 -0
- package/dist/validation/types.d.ts +119 -0
- package/dist/validation/types.d.ts.map +1 -0
- package/dist/validation/types.js +57 -0
- package/dist/validation/types.js.map +1 -0
- package/package.json +3 -3
- package/public/viewer/js/modules/agents.js +1148 -0
- package/public/viewer/js/modules/chat.js +20 -11
- package/public/viewer/js/modules/connector-feed.js +35 -0
- package/public/viewer/js/modules/dashboard.js +49 -0
- package/public/viewer/js/modules/memory.js +32 -0
- package/public/viewer/js/modules/settings.js +34 -79
- package/public/viewer/js/modules/wiki.js +59 -4
- package/public/viewer/js/utils/api.js +70 -0
- package/public/viewer/js/utils/dom.js +3 -0
- package/public/viewer/js/utils/ui-commands.js +93 -0
- package/public/viewer/log-viewer.html +2 -2
- package/public/viewer/src/modules/agents.ts +1299 -0
- package/public/viewer/src/modules/chat.ts +23 -14
- package/public/viewer/src/modules/connector-feed.ts +35 -0
- package/public/viewer/src/modules/dashboard.ts +50 -0
- package/public/viewer/src/modules/memory.ts +31 -0
- package/public/viewer/src/modules/settings.ts +36 -96
- package/public/viewer/src/modules/wiki.ts +73 -6
- package/public/viewer/src/types/global.d.ts +0 -9
- package/public/viewer/src/utils/api.ts +156 -2
- package/public/viewer/src/utils/dom.ts +6 -1
- package/public/viewer/src/utils/ui-commands.ts +118 -0
- package/public/viewer/viewer.css +105 -10
- package/public/viewer/viewer.html +1868 -777
- package/scripts/generate-gateway-tools.ts +5 -1
- package/public/viewer/js/modules/playground.js +0 -148
- package/public/viewer/js/modules/skills.js +0 -451
- package/public/viewer/src/modules/playground.ts +0 -173
- package/public/viewer/src/modules/skills.ts +0 -491
- package/templates/playgrounds/cron-workflow-lab.html +0 -1601
- package/templates/playgrounds/mama-log-viewer.html +0 -1341
- package/templates/playgrounds/skill-lab-playground.html +0 -1625
- package/templates/playgrounds/wave-visualizer.html +0 -694
- package/templates/skills/playground.md +0 -197
|
@@ -1,694 +0,0 @@
|
|
|
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>Wave Visualizer — MAMA Multi-Agent</title>
|
|
7
|
-
<style>
|
|
8
|
-
:root {
|
|
9
|
-
--bg:#0d1117;--surface:#161b22;--surface2:#1c2333;--surface3:#21262d;
|
|
10
|
-
--border:#30363d;--text:#e6edf3;--text2:#8b949e;--text3:#484f58;
|
|
11
|
-
--accent:#58a6ff;--green:#3fb950;--yellow:#d29922;--red:#f85149;
|
|
12
|
-
--orange:#db6d28;--purple:#bc8cff;--cyan:#39d2c0;--pink:#f778ba;
|
|
13
|
-
}
|
|
14
|
-
*{margin:0;padding:0;box-sizing:border-box}
|
|
15
|
-
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:var(--bg);color:var(--text);height:100vh;display:flex;flex-direction:column;overflow:hidden}
|
|
16
|
-
.header{display:flex;align-items:center;gap:12px;padding:10px 16px;background:var(--surface);border-bottom:1px solid var(--border);flex-shrink:0}
|
|
17
|
-
.header h1{font-size:15px;font-weight:600}
|
|
18
|
-
.header h1 span{color:var(--accent)}
|
|
19
|
-
.hc{display:flex;gap:8px;margin-left:auto;align-items:center}
|
|
20
|
-
.btn{padding:5px 12px;border-radius:6px;border:1px solid var(--border);background:var(--surface2);color:var(--text);font-size:12px;cursor:pointer;font-weight:500;transition:all .15s;white-space:nowrap}
|
|
21
|
-
.btn:hover{background:var(--border)}
|
|
22
|
-
.btn-primary{background:var(--accent);color:#fff;border-color:var(--accent)}
|
|
23
|
-
.btn-sm{padding:3px 8px;font-size:11px}
|
|
24
|
-
.btn-active{background:var(--accent);color:#fff;border-color:var(--accent)}
|
|
25
|
-
.mode-tabs{display:flex;gap:2px;background:var(--bg);border-radius:6px;padding:2px}
|
|
26
|
-
.mode-tab{padding:4px 12px;border:none;border-radius:4px;cursor:pointer;font-size:12px;font-weight:500;background:transparent;color:var(--text2);transition:all .15s}
|
|
27
|
-
.mode-tab.active{background:var(--surface2);color:var(--text)}
|
|
28
|
-
.mode-tab.live-on{background:rgba(63,185,80,.2);color:var(--green)}
|
|
29
|
-
.speed-ctl{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text2)}
|
|
30
|
-
.speed-ctl input[type=range]{width:80px;accent-color:var(--accent)}
|
|
31
|
-
.main{display:flex;flex:1;overflow:hidden}
|
|
32
|
-
.sidebar{width:260px;background:var(--surface);border-right:1px solid var(--border);flex-shrink:0;overflow-y:auto}
|
|
33
|
-
.sidebar::-webkit-scrollbar{width:6px}
|
|
34
|
-
.sidebar::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}
|
|
35
|
-
.content{flex:1;display:flex;flex-direction:column;overflow:hidden}
|
|
36
|
-
.sec{padding:10px 12px;border-bottom:1px solid var(--border)}
|
|
37
|
-
.sec-title{font-size:11px;font-weight:600;color:var(--text2);text-transform:uppercase;letter-spacing:.5px;margin-bottom:8px;display:flex;align-items:center;gap:6px}
|
|
38
|
-
.acard{display:flex;align-items:center;gap:8px;padding:6px 8px;border-radius:6px;margin-bottom:4px;cursor:pointer;transition:background .15s}
|
|
39
|
-
.acard:hover{background:var(--surface2)}
|
|
40
|
-
.adot{width:10px;height:10px;border-radius:50%;flex-shrink:0}
|
|
41
|
-
.aname{font-size:13px;font-weight:500;flex:1}
|
|
42
|
-
.atier{font-size:10px;padding:1px 5px;border-radius:3px;background:var(--surface3);color:var(--text2)}
|
|
43
|
-
.astatus{font-size:11px}
|
|
44
|
-
.online-dot{width:8px;height:8px;border-radius:50%;display:inline-block}
|
|
45
|
-
.online-dot.online{background:var(--green)}
|
|
46
|
-
.online-dot.offline{background:var(--red)}
|
|
47
|
-
.online-dot.busy{background:var(--yellow);animation:lp 1s infinite}
|
|
48
|
-
@keyframes lp{0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(63,185,80,.4)}50%{opacity:.7;box-shadow:0 0 0 4px rgba(63,185,80,0)}}
|
|
49
|
-
.live-dot{width:8px;height:8px;border-radius:50%;background:var(--green);display:inline-block}
|
|
50
|
-
.live-dot.pulse{animation:lp 1.5s infinite}
|
|
51
|
-
.wave-area{flex:1;overflow:auto;padding:16px}
|
|
52
|
-
.wave-area::-webkit-scrollbar{width:8px;height:8px}
|
|
53
|
-
.wave-area::-webkit-scrollbar-thumb{background:var(--border);border-radius:4px}
|
|
54
|
-
.wave-row{display:flex;align-items:stretch;margin-bottom:2px;min-height:60px}
|
|
55
|
-
.wave-label{width:100px;flex-shrink:0;display:flex;flex-direction:column;justify-content:center;align-items:flex-end;padding-right:16px;border-right:2px solid var(--border)}
|
|
56
|
-
.wave-num{font-size:20px;font-weight:700;color:var(--accent)}
|
|
57
|
-
.wave-name{font-size:11px;color:var(--text2);white-space:nowrap}
|
|
58
|
-
.wave-tasks{flex:1;display:flex;gap:6px;padding:8px 16px;flex-wrap:wrap;align-items:center}
|
|
59
|
-
.tcard{display:flex;flex-direction:column;gap:2px;padding:8px 12px;border-radius:8px;border:1px solid var(--border);background:var(--surface);min-width:160px;max-width:260px;cursor:pointer;transition:all .2s;position:relative;overflow:hidden}
|
|
60
|
-
.tcard:hover{border-color:var(--accent);transform:translateY(-1px)}
|
|
61
|
-
.tcard::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;border-radius:3px 0 0 3px}
|
|
62
|
-
.tcard.pending::before{background:var(--text3)}
|
|
63
|
-
.tcard.claimed::before{background:var(--yellow)}
|
|
64
|
-
.tcard.completed::before{background:var(--green)}
|
|
65
|
-
.tcard.failed::before{background:var(--red)}
|
|
66
|
-
.tcard.claimed{border-color:var(--yellow);box-shadow:0 0 12px rgba(210,153,34,.2)}
|
|
67
|
-
.tcard.completed{opacity:.7}
|
|
68
|
-
.tcard.failed{border-color:var(--red);opacity:.85}
|
|
69
|
-
.tagent{display:flex;align-items:center;gap:5px}
|
|
70
|
-
.tagent-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
|
|
71
|
-
.tagent-name{font-size:11px;font-weight:600}
|
|
72
|
-
.tdesc{font-size:12px;color:var(--text2);line-height:1.4;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
|
|
73
|
-
.tmeta{display:flex;align-items:center;gap:6px;margin-top:2px}
|
|
74
|
-
.tstatus{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.3px;padding:1px 5px;border-radius:3px}
|
|
75
|
-
.tstatus.pending{background:rgba(72,79,88,.3);color:var(--text3)}
|
|
76
|
-
.tstatus.claimed{background:rgba(210,153,34,.15);color:var(--yellow)}
|
|
77
|
-
.tstatus.completed{background:rgba(63,185,80,.15);color:var(--green)}
|
|
78
|
-
.tstatus.failed{background:rgba(248,81,73,.15);color:var(--red)}
|
|
79
|
-
.ttime{font-size:10px;color:var(--text3);font-family:'SF Mono',monospace}
|
|
80
|
-
.wconn{display:flex;align-items:center;justify-content:center;padding:0 0 0 100px}
|
|
81
|
-
.cline{width:2px;height:16px;background:var(--border);position:relative}
|
|
82
|
-
.cline::after{content:'\25BC';position:absolute;bottom:-10px;left:50%;transform:translateX(-50%);font-size:8px;color:var(--text3)}
|
|
83
|
-
.pbar{flex-shrink:0;padding:8px 16px;background:var(--surface);border-top:1px solid var(--border);display:flex;align-items:center;gap:12px}
|
|
84
|
-
.ptrack{flex:1;height:6px;background:var(--surface3);border-radius:3px;overflow:hidden;display:flex}
|
|
85
|
-
.pfill{height:100%;transition:width .5s ease}
|
|
86
|
-
.pfill.c{background:var(--green)}.pfill.a{background:var(--yellow)}.pfill.f{background:var(--red)}
|
|
87
|
-
.pstats{display:flex;gap:12px;font-size:12px;color:var(--text2);white-space:nowrap}
|
|
88
|
-
.pstats strong{color:var(--text)}
|
|
89
|
-
.preset-bar{display:flex;gap:6px;padding:8px 12px;border-bottom:1px solid var(--border);flex-wrap:wrap;align-items:center}
|
|
90
|
-
.dpanel{width:280px;background:var(--surface);border-left:1px solid var(--border);padding:12px;overflow-y:auto;flex-shrink:0;display:none}
|
|
91
|
-
.dpanel.show{display:block}
|
|
92
|
-
.dtitle{font-size:14px;font-weight:600;margin-bottom:8px}
|
|
93
|
-
.dfield{margin-bottom:8px}
|
|
94
|
-
.dlabel{font-size:11px;color:var(--text2);text-transform:uppercase;letter-spacing:.3px;margin-bottom:2px}
|
|
95
|
-
.dvalue{font-size:13px}
|
|
96
|
-
.dfiles{list-style:none}
|
|
97
|
-
.dfiles li{font-size:12px;font-family:'SF Mono',monospace;color:var(--cyan);padding:2px 0}
|
|
98
|
-
.ddeps{display:flex;gap:4px;flex-wrap:wrap}
|
|
99
|
-
.ddep{font-size:11px;padding:2px 6px;border-radius:4px;background:var(--surface3);color:var(--text2)}
|
|
100
|
-
.chg-item{display:flex;align-items:center;gap:10px;padding:5px 10px;border-radius:6px;background:var(--bg);margin-bottom:2px;font-size:12px}
|
|
101
|
-
.prompt-output{flex-shrink:0;border-top:1px solid var(--border);background:var(--surface);padding:10px 16px}
|
|
102
|
-
.prompt-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px}
|
|
103
|
-
.prompt-header label{font-size:12px;font-weight:600;color:var(--text2)}
|
|
104
|
-
.prompt-actions{display:flex;gap:6px}
|
|
105
|
-
.prompt-text{font-size:12px;color:var(--text);background:var(--bg);border:1px solid var(--border);border-radius:6px;padding:8px 10px;min-height:36px;max-height:80px;overflow-y:auto;line-height:1.5;font-family:'SF Mono',monospace;white-space:pre-wrap}
|
|
106
|
-
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.5}}
|
|
107
|
-
.tcard.claimed .tstatus{animation:pulse 1.5s infinite}
|
|
108
|
-
</style>
|
|
109
|
-
</head>
|
|
110
|
-
<body>
|
|
111
|
-
<div class="header">
|
|
112
|
-
<h1>🌊 <span>Wave Visualizer</span></h1>
|
|
113
|
-
<div class="hc">
|
|
114
|
-
<div class="mode-tabs">
|
|
115
|
-
<button class="mode-tab active" id="modeSimTab" onclick="switchMode('sim')">Simulation</button>
|
|
116
|
-
<button class="mode-tab" id="modeLiveTab" onclick="switchMode('live')">🔴 Live</button>
|
|
117
|
-
</div>
|
|
118
|
-
<div class="speed-ctl" id="simCtl">
|
|
119
|
-
<span>Speed:</span>
|
|
120
|
-
<input type="range" id="speedSlider" min="1" max="10" value="5">
|
|
121
|
-
<span id="speedLabel">1x</span>
|
|
122
|
-
</div>
|
|
123
|
-
<button class="btn" id="resetBtn" onclick="resetSim()">⟳ Reset</button>
|
|
124
|
-
<button class="btn btn-primary" id="playBtn" onclick="togglePlay()">▶ Play</button>
|
|
125
|
-
</div>
|
|
126
|
-
</div>
|
|
127
|
-
<div style="display:flex;flex-direction:column;flex:1;overflow:hidden">
|
|
128
|
-
<div class="preset-bar" id="presetBar"></div>
|
|
129
|
-
<div class="main">
|
|
130
|
-
<div class="sidebar" id="sidebar"></div>
|
|
131
|
-
<div class="content">
|
|
132
|
-
<div class="wave-area" id="waveArea"></div>
|
|
133
|
-
<div class="pbar">
|
|
134
|
-
<div class="ptrack" id="ptrack"></div>
|
|
135
|
-
<div class="pstats" id="pstats"></div>
|
|
136
|
-
</div>
|
|
137
|
-
</div>
|
|
138
|
-
<div class="dpanel" id="dpanel"></div>
|
|
139
|
-
</div>
|
|
140
|
-
<div class="prompt-output">
|
|
141
|
-
<div class="prompt-header">
|
|
142
|
-
<label>Generated Prompt</label>
|
|
143
|
-
<div class="prompt-actions">
|
|
144
|
-
<button class="btn btn-sm" id="copyPromptBtn" onclick="copyPrompt()">Copy</button>
|
|
145
|
-
<button class="btn btn-sm" id="sendToChatBtn" onclick="sendToChat()">Send to Chat</button>
|
|
146
|
-
</div>
|
|
147
|
-
</div>
|
|
148
|
-
<div id="promptText" class="prompt-text">Select a preset and run the simulation.</div>
|
|
149
|
-
</div>
|
|
150
|
-
</div>
|
|
151
|
-
<script>
|
|
152
|
-
var AC={conductor:'#58a6ff',developer:'#3fb950',reviewer:'#bc8cff',qa:'#f778ba',coder:'#39d2c0',pm:'#d29922',artisan:'#db6d28',critic:'#f85149'};
|
|
153
|
-
var AE={conductor:'🎯',developer:'🔧',reviewer:'👁',qa:'🧪',coder:'💻',pm:'📋',artisan:'🎨',critic:'🔍'};
|
|
154
|
-
|
|
155
|
-
var PRESETS={
|
|
156
|
-
'feature-impl':{name:'🚀 Feature Implementation',desc:'New feature implementation',agents:['conductor','developer','reviewer'],waves:[
|
|
157
|
-
{wave:1,name:'Analysis',tasks:[{id:'t1',agent:'conductor',desc:'Requirements analysis and code exploration',category:'analysis',files:['src/','docs/']},{id:'t2',agent:'developer',desc:'Module dependency mapping',category:'analysis',files:['package.json']}]},
|
|
158
|
-
{wave:2,name:'Planning',tasks:[{id:'t3',agent:'conductor',desc:'Implementation strategy and task distribution',category:'planning',dependsOn:['t1','t2']}]},
|
|
159
|
-
{wave:3,name:'Implementation',tasks:[{id:'t4',agent:'developer',desc:'Core business logic implementation',category:'coding',files:['src/features/auth.ts'],dependsOn:['t3']},{id:'t5',agent:'developer',desc:'API endpoint creation',category:'coding',dependsOn:['t3']},{id:'t6',agent:'developer',desc:'Test writing',category:'testing',dependsOn:['t3']}]},
|
|
160
|
-
{wave:4,name:'Review',tasks:[{id:'t7',agent:'reviewer',desc:'Code quality and security review',category:'review',dependsOn:['t4','t5']},{id:'t8',agent:'reviewer',desc:'Test coverage verification',category:'review',dependsOn:['t6']}]},
|
|
161
|
-
{wave:5,name:'Completion',tasks:[{id:'t9',agent:'conductor',desc:'Final summary and PR preparation',category:'summary',dependsOn:['t7','t8']}]}
|
|
162
|
-
]},
|
|
163
|
-
'bug-fix':{name:'🐛 Bug Fix',desc:'Bug fix',agents:['conductor','developer','qa'],waves:[
|
|
164
|
-
{wave:1,name:'Analysis',tasks:[{id:'t1',agent:'conductor',desc:'Bug report analysis',category:'analysis'},{id:'t2',agent:'qa',desc:'Error log analysis',category:'analysis'}]},
|
|
165
|
-
{wave:2,name:'Planning',tasks:[{id:'t3',agent:'conductor',desc:'Root cause and fix strategy',category:'planning',dependsOn:['t1','t2']}]},
|
|
166
|
-
{wave:3,name:'Implementation',tasks:[{id:'t4',agent:'developer',desc:'Bug fix patch',category:'coding',dependsOn:['t3']},{id:'t5',agent:'developer',desc:'Regression test addition',category:'testing',dependsOn:['t3']}]},
|
|
167
|
-
{wave:4,name:'Review',tasks:[{id:'t6',agent:'qa',desc:'Fix verification',category:'review',dependsOn:['t4','t5']}]},
|
|
168
|
-
{wave:5,name:'Completion',tasks:[{id:'t7',agent:'conductor',desc:'Release notes',category:'summary',dependsOn:['t6']}]}
|
|
169
|
-
]},
|
|
170
|
-
'refactor':{name:'♻️ Refactoring',desc:'Large-scale refactoring',agents:['conductor','developer','coder','reviewer','qa'],waves:[
|
|
171
|
-
{wave:1,name:'Analysis',tasks:[{id:'t1',agent:'conductor',desc:'Refactoring target analysis',category:'analysis'},{id:'t2',agent:'reviewer',desc:'Complexity measurement',category:'analysis'},{id:'t3',agent:'qa',desc:'Test coverage check',category:'analysis'}]},
|
|
172
|
-
{wave:2,name:'Planning',tasks:[{id:'t4',agent:'conductor',desc:'Module separation strategy',category:'planning',dependsOn:['t1','t2','t3']}]},
|
|
173
|
-
{wave:3,name:'Implementation',tasks:[{id:'t5',agent:'developer',desc:'Extract save module',category:'coding',dependsOn:['t4']},{id:'t6',agent:'developer',desc:'Extract recall module',category:'coding',dependsOn:['t4']},{id:'t7',agent:'coder',desc:'Extract suggest module',category:'coding',dependsOn:['t4']},{id:'t8',agent:'coder',desc:'Extract update module',category:'coding',dependsOn:['t4']}]},
|
|
174
|
-
{wave:4,name:'Review',tasks:[{id:'t9',agent:'reviewer',desc:'API compatibility verification',category:'review',dependsOn:['t5','t6','t7','t8']},{id:'t10',agent:'qa',desc:'Full test regression',category:'testing',dependsOn:['t5','t6','t7','t8']}]},
|
|
175
|
-
{wave:5,name:'Completion',tasks:[{id:'t11',agent:'conductor',desc:'Migration guide',category:'summary',dependsOn:['t9','t10']}]}
|
|
176
|
-
]},
|
|
177
|
-
'mama-session':{name:'🧠 MAMA Session',desc:'MAMA OS agent session',agents:['conductor','artisan','critic'],waves:[
|
|
178
|
-
{wave:1,name:'Analysis',tasks:[{id:'t1',agent:'conductor',desc:'Request analysis and context loading',category:'analysis'},{id:'t2',agent:'conductor',desc:'MAMA memory search',category:'analysis'}]},
|
|
179
|
-
{wave:2,name:'Planning',tasks:[{id:'t3',agent:'conductor',desc:'Work planning and agent assignment',category:'planning',dependsOn:['t1','t2']}]},
|
|
180
|
-
{wave:3,name:'Implementation',tasks:[{id:'t4',agent:'artisan',desc:'Code implementation',category:'coding',dependsOn:['t3']},{id:'t5',agent:'artisan',desc:'Test writing',category:'testing',dependsOn:['t3']}]},
|
|
181
|
-
{wave:4,name:'Review',tasks:[{id:'t6',agent:'critic',desc:'Code review and quality verification',category:'review',dependsOn:['t4','t5']}]},
|
|
182
|
-
{wave:5,name:'Completion',tasks:[{id:'t7',agent:'conductor',desc:'Decision saving and summary',category:'summary',dependsOn:['t6']}]}
|
|
183
|
-
]}
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
var S={
|
|
187
|
-
mode:'sim',preset:'feature-impl',tasks:{},curWave:0,playing:false,speed:5,
|
|
188
|
-
selTask:null,timer:null,taskOrder:[],failedTasks:new Set(),
|
|
189
|
-
liveAgents:[],liveDelegations:[],livePolling:null,liveHistory:[],
|
|
190
|
-
lastPoll:null,liveOk:false,prevDelegCount:0,
|
|
191
|
-
prevStates:{},stateChanges:[],activeChains:0,pollCount:0,
|
|
192
|
-
liveTasks:[],waveCounter:0,currentBusy:new Set(),
|
|
193
|
-
pollInFlight:false
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
// === Utilities ===
|
|
197
|
-
function esc(s){return String(s||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,''')}
|
|
198
|
-
function timeAgo(d){var s=(Date.now()-d.getTime())/1000;if(s<5)return'just now';if(s<60)return Math.floor(s)+'s ago';if(s<3600)return Math.floor(s/60)+'m ago';return Math.floor(s/3600)+'h ago'}
|
|
199
|
-
function fmtTime(d){if(!(d instanceof Date))d=new Date(d);return d.toLocaleTimeString('en-US',{hour12:false,hour:'2-digit',minute:'2-digit',second:'2-digit'})}
|
|
200
|
-
|
|
201
|
-
// === Mode Switch ===
|
|
202
|
-
function switchMode(m){
|
|
203
|
-
S.mode=m;
|
|
204
|
-
document.getElementById('modeSimTab').className='mode-tab'+(m==='sim'?' active':'');
|
|
205
|
-
document.getElementById('modeLiveTab').className='mode-tab'+(m==='live'?' live-on':'');
|
|
206
|
-
if(m==='sim'){
|
|
207
|
-
stopLive();
|
|
208
|
-
document.getElementById('simCtl').style.display='flex';
|
|
209
|
-
document.getElementById('resetBtn').style.display='';
|
|
210
|
-
document.getElementById('playBtn').style.display='';
|
|
211
|
-
document.getElementById('playBtn').textContent='▶ Play';
|
|
212
|
-
loadPreset(S.preset);
|
|
213
|
-
} else {
|
|
214
|
-
stopSim();
|
|
215
|
-
document.getElementById('simCtl').style.display='none';
|
|
216
|
-
document.getElementById('resetBtn').style.display='none';
|
|
217
|
-
document.getElementById('playBtn').style.display='none';
|
|
218
|
-
renderLivePresetBar();
|
|
219
|
-
startLive();
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// ====================== LIVE MODE ======================
|
|
224
|
-
function renderLivePresetBar(){
|
|
225
|
-
document.getElementById('presetBar').innerHTML=
|
|
226
|
-
'<span class="live-dot pulse"></span> <span style="font-size:12px;color:var(--green);font-weight:600">LIVE</span>'+
|
|
227
|
-
'<span style="font-size:12px;color:var(--text2);margin-left:8px" id="liveStatus">Connecting...</span>'+
|
|
228
|
-
'<span style="font-size:11px;color:var(--text3);margin-left:auto" id="livePollTime"></span>';
|
|
229
|
-
}
|
|
230
|
-
function startLive(){pollLive();S.livePolling=setInterval(function(){
|
|
231
|
-
if(S.pollInFlight)return;
|
|
232
|
-
S.pollInFlight=true;
|
|
233
|
-
pollLive().finally(function(){S.pollInFlight=false;});
|
|
234
|
-
},3000)}
|
|
235
|
-
function stopLive(){if(S.livePolling){clearInterval(S.livePolling);S.livePolling=null}}
|
|
236
|
-
|
|
237
|
-
async function pollLive(){
|
|
238
|
-
try{
|
|
239
|
-
var ctrl=new AbortController();
|
|
240
|
-
var timeoutId=setTimeout(function(){ctrl.abort();},8000);
|
|
241
|
-
var r=await fetch('/api/multi-agent/status',{signal:ctrl.signal});
|
|
242
|
-
clearTimeout(timeoutId);
|
|
243
|
-
if(!r.ok)throw new Error('API '+r.status);
|
|
244
|
-
var sd=await r.json();
|
|
245
|
-
S.liveAgents=sd.agents||[];
|
|
246
|
-
S.liveDelegations=sd.recentDelegations||[];
|
|
247
|
-
S.activeChains=sd.activeChains||0;
|
|
248
|
-
S.liveOk=true;S.lastPoll=new Date();S.pollCount++;
|
|
249
|
-
|
|
250
|
-
// Detect state changes & build live tasks
|
|
251
|
-
var now=new Date();
|
|
252
|
-
S.liveAgents.forEach(function(a){
|
|
253
|
-
var prev=S.prevStates[a.id];
|
|
254
|
-
if(prev&&prev!==a.status){
|
|
255
|
-
S.stateChanges.unshift({agent:a.id,from:prev,to:a.status,time:now});
|
|
256
|
-
|
|
257
|
-
// Agent became busy → new task starts
|
|
258
|
-
if(a.status==='busy'){
|
|
259
|
-
// If no other agents are busy, this is a new wave
|
|
260
|
-
if(S.currentBusy.size===0)S.waveCounter++;
|
|
261
|
-
S.currentBusy.add(a.id);
|
|
262
|
-
S.liveTasks.push({
|
|
263
|
-
id:'lt-'+S.liveTasks.length,
|
|
264
|
-
agent:a.id,
|
|
265
|
-
model:a.model||'unknown',
|
|
266
|
-
wave:S.waveCounter,
|
|
267
|
-
status:'busy',
|
|
268
|
-
startTime:now,
|
|
269
|
-
endTime:null,
|
|
270
|
-
duration:null,
|
|
271
|
-
ephemeral:a.ephemeral||false
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Agent became idle/online → task completed
|
|
276
|
-
if((a.status==='idle'||a.status==='online')&&prev==='busy'){
|
|
277
|
-
S.currentBusy.delete(a.id);
|
|
278
|
-
for(var i=S.liveTasks.length-1;i>=0;i--){
|
|
279
|
-
if(S.liveTasks[i].agent===a.id&&S.liveTasks[i].status==='busy'){
|
|
280
|
-
S.liveTasks[i].status='completed';
|
|
281
|
-
S.liveTasks[i].endTime=now;
|
|
282
|
-
S.liveTasks[i].duration=Math.round((now-S.liveTasks[i].startTime)/1000);
|
|
283
|
-
break;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
S.prevStates[a.id]=a.status;
|
|
289
|
-
});
|
|
290
|
-
if(S.stateChanges.length>50)S.stateChanges=S.stateChanges.slice(0,50);
|
|
291
|
-
|
|
292
|
-
// Track new swarm tasks
|
|
293
|
-
if (S.liveDelegations.length < S.prevDelegCount) {
|
|
294
|
-
S.prevDelegCount = S.liveDelegations.length;
|
|
295
|
-
}
|
|
296
|
-
if(S.liveDelegations.length>S.prevDelegCount){
|
|
297
|
-
S.liveDelegations.slice(S.prevDelegCount).forEach(function(d){
|
|
298
|
-
S.liveHistory.unshift(Object.assign({},d,{receivedAt:new Date()}));
|
|
299
|
-
});
|
|
300
|
-
S.prevDelegCount=S.liveDelegations.length;
|
|
301
|
-
}
|
|
302
|
-
if(S.liveHistory.length>100)S.liveHistory=S.liveHistory.slice(0,100);
|
|
303
|
-
|
|
304
|
-
// Status bar
|
|
305
|
-
var busy=S.liveAgents.filter(function(a){return a.status==='busy'});
|
|
306
|
-
var el=document.getElementById('liveStatus');
|
|
307
|
-
if(el){
|
|
308
|
-
var t='Connected · '+S.liveAgents.length+' agents';
|
|
309
|
-
if(busy.length>0)t+=' · '+busy.map(function(a){return a.id}).join(', ')+' busy';
|
|
310
|
-
if(S.activeChains>0)t+=' · '+S.activeChains+' chains';
|
|
311
|
-
el.textContent=t;el.style.color=busy.length>0?'var(--yellow)':'var(--green)';
|
|
312
|
-
}
|
|
313
|
-
var te=document.getElementById('livePollTime');
|
|
314
|
-
if(te)te.textContent='Poll #'+S.pollCount+' · '+S.lastPoll.toLocaleTimeString();
|
|
315
|
-
|
|
316
|
-
renderLiveSidebar();renderLiveArea();updateLivePrompt();
|
|
317
|
-
}catch(e){
|
|
318
|
-
if(e.name==='AbortError'){console.warn('Poll timed out');}
|
|
319
|
-
S.liveOk=false;
|
|
320
|
-
var el=document.getElementById('liveStatus');
|
|
321
|
-
if(el){el.textContent='Disconnected — '+(e.name==='AbortError'?'Timeout':e.message);el.style.color='var(--red)'}
|
|
322
|
-
renderLiveSidebar();renderLiveDisconnected();
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
function renderLiveSidebar(){
|
|
327
|
-
var sb=document.getElementById('sidebar');
|
|
328
|
-
var h='<div class="sec"><div class="sec-title"><span class="live-dot'+(S.liveOk?' pulse':'')+'"></span> Live Agents ('+S.liveAgents.length+')</div>';
|
|
329
|
-
S.liveAgents.forEach(function(a){
|
|
330
|
-
var c=AC[a.id]||'#888',e=AE[a.id]||'🤖';
|
|
331
|
-
var sc=a.status==='online'?'online':a.status==='busy'?'busy':'offline';
|
|
332
|
-
h+='<div class="acard"><span class="online-dot '+esc(sc)+'"></span>'+
|
|
333
|
-
'<span class="aname" style="color:'+esc(c)+'">'+esc(e)+' '+esc(a.name||a.id)+'</span>'+
|
|
334
|
-
'<span class="atier">T'+esc(String(a.tier||1))+'</span></div>'+
|
|
335
|
-
'<div style="padding:0 8px 6px 26px;font-size:11px;color:var(--text3)">'+
|
|
336
|
-
esc(a.model||'unknown')+' · '+(a.lastActivity?esc(timeAgo(new Date(a.lastActivity))):'idle')+'</div>';
|
|
337
|
-
});
|
|
338
|
-
h+='</div>';
|
|
339
|
-
|
|
340
|
-
// State changes
|
|
341
|
-
h+='<div class="sec"><div class="sec-title">Activity Log ('+S.stateChanges.length+')</div>';
|
|
342
|
-
if(S.stateChanges.length===0){
|
|
343
|
-
h+='<div style="font-size:12px;color:var(--text3);padding:4px 0">No state changes<br><span style="font-size:11px">Busy detected on DELEGATE:: delegation</span></div>';
|
|
344
|
-
}else{
|
|
345
|
-
S.stateChanges.slice(0,15).forEach(function(c){
|
|
346
|
-
var col=AC[c.agent]||'#888';
|
|
347
|
-
var tc=c.to==='busy'?'var(--yellow)':c.to==='idle'||c.to==='online'?'var(--green)':'var(--text3)';
|
|
348
|
-
var ic=c.to==='busy'?'⚡':c.to==='idle'||c.to==='online'?'✅':'⏸';
|
|
349
|
-
h+='<div class="chg-item">'+
|
|
350
|
-
'<span style="color:var(--text3);font-family:monospace;font-size:10px;min-width:55px">'+esc(fmtTime(c.time))+'</span>'+
|
|
351
|
-
'<span>'+esc(ic)+'</span>'+
|
|
352
|
-
'<span style="color:'+esc(col)+';font-weight:600">'+esc(c.agent)+'</span>'+
|
|
353
|
-
'<span style="color:var(--text3);font-size:11px">'+esc(c.from)+'</span>'+
|
|
354
|
-
'<span style="color:var(--accent);font-size:10px">→</span>'+
|
|
355
|
-
'<span style="color:'+esc(tc)+';font-weight:600;font-size:11px">'+esc(c.to)+'</span></div>';
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
h+='</div>';
|
|
359
|
-
|
|
360
|
-
// Swarm tasks
|
|
361
|
-
if(S.liveHistory.length>0){
|
|
362
|
-
h+='<div class="sec"><div class="sec-title">Swarm Tasks ('+S.liveHistory.length+')</div>';
|
|
363
|
-
S.liveHistory.slice(0,10).forEach(function(d){
|
|
364
|
-
var cc=AC[d.claimedBy]||'#888';
|
|
365
|
-
h+='<div style="padding:4px 0;font-size:12px;border-bottom:1px solid var(--border)">'+
|
|
366
|
-
'<span style="color:'+esc(cc)+';font-weight:600">'+esc(d.claimedBy||'?')+'</span>'+
|
|
367
|
-
' <span class="tstatus '+esc(d.status||'pending')+'" style="font-size:9px">'+esc(d.status||'?')+'</span>'+
|
|
368
|
-
(d.wave?' <span style="color:var(--accent);font-size:10px">W'+esc(String(d.wave))+'</span>':'')+
|
|
369
|
-
'<div style="color:var(--text2);font-size:11px">'+esc(d.description||'-')+'</div></div>';
|
|
370
|
-
});
|
|
371
|
-
h+='</div>';
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// Connection
|
|
375
|
-
h+='<div class="sec"><div class="sec-title">Connection</div>'+
|
|
376
|
-
'<div style="font-size:11px;color:var(--text2);line-height:1.7">'+
|
|
377
|
-
'API: <code style="color:var(--cyan);font-size:10px">/api/multi-agent/*</code><br>'+
|
|
378
|
-
'Poll: 3s interval<br>'+
|
|
379
|
-
'Status: '+(S.liveOk?'<span style="color:var(--green)">OK</span>':'<span style="color:var(--red)">Disconnected</span>')+
|
|
380
|
-
'</div></div>';
|
|
381
|
-
sb.innerHTML=h;
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
function renderLiveArea(){
|
|
385
|
-
var area=document.getElementById('waveArea');
|
|
386
|
-
var h='';
|
|
387
|
-
|
|
388
|
-
// Agent status cards
|
|
389
|
-
h+='<div style="display:flex;gap:8px;margin-bottom:16px;flex-wrap:wrap">';
|
|
390
|
-
S.liveAgents.forEach(function(a){
|
|
391
|
-
var c=AC[a.id]||'#888',e=AE[a.id]||'🤖';
|
|
392
|
-
var bc=a.status==='busy'?'var(--yellow)':a.status==='online'||a.status==='idle'?'var(--green)':'var(--text3)';
|
|
393
|
-
var bg=a.status==='busy'?'rgba(210,153,34,.08)':'transparent';
|
|
394
|
-
h+='<div style="background:var(--surface);border:1px solid var(--border);border-left:3px solid '+esc(bc)+';border-radius:8px;padding:8px 12px;min-width:140px;'+(bg!=='transparent'?'background:'+esc(bg):'')+'">'+
|
|
395
|
-
'<div style="display:flex;align-items:center;gap:6px;margin-bottom:4px">'+
|
|
396
|
-
'<span class="online-dot '+esc(a.status)+'"></span>'+
|
|
397
|
-
'<span style="font-size:13px;font-weight:600;color:'+esc(c)+'">'+esc(e)+' '+esc(a.name||a.id)+'</span>'+
|
|
398
|
-
(a.ephemeral?'<span style="font-size:9px;padding:1px 4px;border-radius:3px;background:var(--surface3);color:var(--text3)">ephemeral</span>':'')+
|
|
399
|
-
'</div>'+
|
|
400
|
-
'<div style="font-size:10px;color:var(--text3)">'+esc(a.model||'-')+' · T'+esc(String(a.tier||1))+'</div>'+
|
|
401
|
-
'</div>';
|
|
402
|
-
});
|
|
403
|
-
h+='</div>';
|
|
404
|
-
|
|
405
|
-
// Wave timeline (built from live tasks)
|
|
406
|
-
if(S.liveTasks.length>0){
|
|
407
|
-
// Group by wave
|
|
408
|
-
var waves={};
|
|
409
|
-
S.liveTasks.forEach(function(t){
|
|
410
|
-
if(!waves[t.wave])waves[t.wave]=[];
|
|
411
|
-
waves[t.wave].push(t);
|
|
412
|
-
});
|
|
413
|
-
var waveNums=Object.keys(waves).sort(function(a,b){return a-b});
|
|
414
|
-
|
|
415
|
-
waveNums.forEach(function(wn,wi){
|
|
416
|
-
if(wi>0)h+='<div class="wconn"><div class="cline"></div></div>';
|
|
417
|
-
var wTasks=waves[wn];
|
|
418
|
-
var allDone=wTasks.every(function(t){return t.status==='completed'});
|
|
419
|
-
var anyBusy=wTasks.some(function(t){return t.status==='busy'});
|
|
420
|
-
var wColor=anyBusy?'var(--yellow)':allDone?'var(--green)':'var(--accent)';
|
|
421
|
-
|
|
422
|
-
h+='<div class="wave-row"><div class="wave-label">'+
|
|
423
|
-
'<div class="wave-num" style="color:'+wColor+'">W'+wn+'</div>'+
|
|
424
|
-
'<div class="wave-name">'+(anyBusy?'Running':allDone?'Done':'Pending')+'</div>'+
|
|
425
|
-
'</div><div class="wave-tasks">';
|
|
426
|
-
|
|
427
|
-
wTasks.forEach(function(t){
|
|
428
|
-
var c=AC[t.agent]||'#888',e=AE[t.agent]||'🤖';
|
|
429
|
-
var elapsed='';
|
|
430
|
-
if(t.duration!==null)elapsed=esc(String(t.duration))+'s';
|
|
431
|
-
else if(t.startTime)elapsed=esc(String(Math.round((Date.now()-t.startTime)/1000)))+'s...';
|
|
432
|
-
|
|
433
|
-
h+='<div class="tcard '+esc(t.status)+'">'+
|
|
434
|
-
'<div class="tagent"><div class="tagent-dot" style="background:'+esc(c)+'"></div>'+
|
|
435
|
-
'<span class="tagent-name" style="color:'+esc(c)+'">'+esc(e)+' '+esc(t.agent)+'</span></div>'+
|
|
436
|
-
'<div style="font-size:11px;color:var(--text3)">'+esc(t.model||'')+'</div>'+
|
|
437
|
-
'<div class="tmeta"><span class="tstatus '+esc(t.status)+'">'+(t.status==='busy'?'running':esc(t.status))+'</span>'+
|
|
438
|
-
(elapsed?'<span class="ttime">'+elapsed+'</span>':'')+'</div>'+
|
|
439
|
-
'</div>';
|
|
440
|
-
});
|
|
441
|
-
h+='</div></div>';
|
|
442
|
-
});
|
|
443
|
-
|
|
444
|
-
// Completion summary
|
|
445
|
-
var done=S.liveTasks.filter(function(t){return t.status==='completed'}).length;
|
|
446
|
-
var total=S.liveTasks.length;
|
|
447
|
-
var busy=S.liveTasks.filter(function(t){return t.status==='busy'}).length;
|
|
448
|
-
if(done===total&&total>0){
|
|
449
|
-
var totalTime=0;
|
|
450
|
-
S.liveTasks.forEach(function(t){if(t.duration)totalTime+=t.duration});
|
|
451
|
-
h+='<div style="text-align:center;padding:16px;color:var(--green);font-size:14px;font-weight:600">'+
|
|
452
|
-
'✅ All '+total+' tasks completed in '+waveNums.length+' waves (total '+totalTime+'s)</div>';
|
|
453
|
-
}
|
|
454
|
-
} else if(S.stateChanges.length>0){
|
|
455
|
-
// Show state changes as simple log if no wave structure yet
|
|
456
|
-
h+='<div style="margin-bottom:12px"><div style="font-size:13px;font-weight:600;color:var(--text2);margin-bottom:8px">📊 Agent Activity</div>';
|
|
457
|
-
S.stateChanges.slice(0,20).forEach(function(c,i){
|
|
458
|
-
var col=AC[c.agent]||'#888';
|
|
459
|
-
var tc=c.to==='busy'?'var(--yellow)':'var(--green)';
|
|
460
|
-
var ic=c.to==='busy'?'⚡':'✅';
|
|
461
|
-
h+='<div class="chg-item" style="opacity:'+Math.max(0.4,1-i*0.04)+'">'+
|
|
462
|
-
'<span style="font-size:10px;color:var(--text3);font-family:monospace;min-width:60px">'+esc(fmtTime(c.time))+'</span>'+
|
|
463
|
-
'<span>'+esc(ic)+'</span>'+
|
|
464
|
-
'<span style="color:'+esc(col)+';font-weight:600;min-width:70px">'+esc(AE[c.agent]||'')+' '+esc(c.agent)+'</span>'+
|
|
465
|
-
'<span style="color:var(--text3);font-size:11px">'+esc(c.from)+'</span>'+
|
|
466
|
-
'<span style="color:var(--accent);font-size:10px">→</span>'+
|
|
467
|
-
'<span style="color:'+esc(tc)+';font-weight:600;font-size:11px">'+esc(c.to)+'</span></div>';
|
|
468
|
-
});
|
|
469
|
-
h+='</div>';
|
|
470
|
-
} else if(S.liveOk) {
|
|
471
|
-
h+='<div style="text-align:center;padding:40px;color:var(--text3)">'+
|
|
472
|
-
'<div style="font-size:32px;margin-bottom:12px">📡</div>'+
|
|
473
|
-
'<div style="font-size:14px">Agents standing by</div>'+
|
|
474
|
-
'<div style="font-size:12px;margin-top:8px;max-width:400px;margin-left:auto;margin-right:auto;line-height:1.6">'+
|
|
475
|
-
'Polling every 3s · Wave timeline auto-generated on agent activity'+
|
|
476
|
-
'</div><div style="font-size:11px;margin-top:12px">Poll #'+S.pollCount+'</div></div>';
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
area.innerHTML=h;
|
|
480
|
-
|
|
481
|
-
// Progress bar based on live tasks
|
|
482
|
-
var ltDone=S.liveTasks.filter(function(t){return t.status==='completed'}).length;
|
|
483
|
-
var ltBusy=S.liveTasks.filter(function(t){return t.status==='busy'}).length;
|
|
484
|
-
var ltTotal=S.liveTasks.length||1;
|
|
485
|
-
var agBusy=S.liveAgents.filter(function(a){return a.status==='busy'}).length;
|
|
486
|
-
document.getElementById('ptrack').innerHTML=
|
|
487
|
-
'<div class="pfill c" style="width:'+esc(String(ltDone/ltTotal*100))+'%"></div>'+
|
|
488
|
-
'<div class="pfill a" style="width:'+esc(String(ltBusy/ltTotal*100))+'%"></div>';
|
|
489
|
-
document.getElementById('pstats').innerHTML=
|
|
490
|
-
'<span>✅ Done: <strong>'+esc(String(ltDone))+'</strong></span>'+
|
|
491
|
-
'<span>⚡ Running: <strong>'+esc(String(ltBusy))+'</strong></span>'+
|
|
492
|
-
'<span>🤖 Agents: <strong>'+esc(String(S.liveAgents.length))+'</strong> ('+esc(String(agBusy))+' busy)</span>'+
|
|
493
|
-
'<span style="margin-left:auto">Wave <strong>'+esc(String(S.waveCounter))+'</strong></span>';
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
function renderLiveDisconnected(){
|
|
497
|
-
document.getElementById('waveArea').innerHTML=
|
|
498
|
-
'<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:var(--text2);gap:12px;padding:40px">'+
|
|
499
|
-
'<div style="font-size:32px">📡</div>'+
|
|
500
|
-
'<div style="font-size:14px">API connection failed</div>'+
|
|
501
|
-
'<div style="font-size:12px">Make sure MAMA OS is running</div>'+
|
|
502
|
-
'<code style="font-size:11px;background:var(--surface2);padding:4px 8px;border-radius:4px">/api/multi-agent/status</code></div>';
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
function updateLivePrompt(){
|
|
506
|
-
var p=[];
|
|
507
|
-
p.push('[LIVE] Multi-Agent Monitor · Wave '+S.waveCounter);
|
|
508
|
-
p.push('Agents: '+S.liveAgents.map(function(a){return(a.ephemeral?'*':'')+a.id+'('+a.status+')'}).join(', '));
|
|
509
|
-
var busy=S.liveAgents.filter(function(a){return a.status==='busy'});
|
|
510
|
-
if(busy.length>0)p.push('Active now: '+busy.map(function(a){return a.id+' ['+a.model+']'}).join(', '));
|
|
511
|
-
var done=S.liveTasks.filter(function(t){return t.status==='completed'});
|
|
512
|
-
var running=S.liveTasks.filter(function(t){return t.status==='busy'});
|
|
513
|
-
if(S.liveTasks.length>0){
|
|
514
|
-
p.push('Tasks: '+done.length+'/'+S.liveTasks.length+' completed'+(running.length>0?', '+running.length+' running':''));
|
|
515
|
-
done.forEach(function(t){p.push(' '+t.agent+' (W'+t.wave+'): '+t.duration+'s')});
|
|
516
|
-
running.forEach(function(t){p.push(' '+t.agent+' (W'+t.wave+'): running '+Math.round((Date.now()-t.startTime)/1000)+'s...')});
|
|
517
|
-
}
|
|
518
|
-
document.getElementById('promptText').textContent=p.join('\n');
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
// ====================== SIM MODE ======================
|
|
522
|
-
function init(){renderPresets();loadPreset('feature-impl')}
|
|
523
|
-
|
|
524
|
-
function renderPresets(){
|
|
525
|
-
var bar=document.getElementById('presetBar');bar.innerHTML='';
|
|
526
|
-
Object.keys(PRESETS).forEach(function(k){
|
|
527
|
-
var p=PRESETS[k],b=document.createElement('button');
|
|
528
|
-
b.className='btn btn-sm'+(k===S.preset?' btn-active':'');
|
|
529
|
-
b.textContent=p.name;b.title=p.desc;
|
|
530
|
-
b.onclick=function(){loadPreset(k)};bar.appendChild(b);
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
function loadPreset(k){
|
|
535
|
-
stopSim();S.preset=k;S.tasks={};S.curWave=0;S.taskOrder=[];S.selTask=null;S.failedTasks=new Set();
|
|
536
|
-
var p=PRESETS[k];
|
|
537
|
-
p.waves.forEach(function(w){
|
|
538
|
-
w.tasks.forEach(function(t){S.tasks[t.id]=Object.assign({},t,{status:'pending',st:null,et:null,wave:w.wave})});
|
|
539
|
-
});
|
|
540
|
-
p.waves.forEach(function(w){S.taskOrder.push(w.tasks.map(function(t){return t.id}))});
|
|
541
|
-
renderPresets();renderSidebar();renderWaves();updateProgress();updatePrompt();hideDetail();
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
function renderSidebar(){
|
|
545
|
-
var sb=document.getElementById('sidebar'),p=PRESETS[S.preset],at={};
|
|
546
|
-
p.agents.forEach(function(a){at[a]={t:0,c:0,f:0,a:0}});
|
|
547
|
-
Object.values(S.tasks).forEach(function(t){
|
|
548
|
-
if(!at[t.agent])at[t.agent]={t:0,c:0,f:0,a:0};
|
|
549
|
-
at[t.agent].t++;
|
|
550
|
-
if(t.status==='completed')at[t.agent].c++;
|
|
551
|
-
if(t.status==='failed')at[t.agent].f++;
|
|
552
|
-
if(t.status==='claimed')at[t.agent].a++;
|
|
553
|
-
});
|
|
554
|
-
var h='<div class="sec"><div class="sec-title">Agents ('+p.agents.length+')</div>';
|
|
555
|
-
p.agents.forEach(function(a){
|
|
556
|
-
var i=at[a]||{t:0,c:0,f:0,a:0};
|
|
557
|
-
var tier=a==='conductor'||a==='pm'?1:(a==='reviewer'||a==='qa'||a==='critic')?3:2;
|
|
558
|
-
var ic=i.a>0?'⚡':i.c===i.t&&i.t>0?'✅':i.f>0?'❌':'⏸';
|
|
559
|
-
h+='<div class="acard"><div class="adot" style="background:'+esc(AC[a]||'#888')+'"></div>'+
|
|
560
|
-
'<span class="aname">'+esc(AE[a]||'🤖')+' '+esc(a)+'</span>'+
|
|
561
|
-
'<span class="atier">T'+esc(String(tier))+'</span>'+
|
|
562
|
-
'<span class="astatus">'+esc(ic)+' '+esc(String(i.c))+'/'+esc(String(i.t))+'</span></div>';
|
|
563
|
-
});
|
|
564
|
-
h+='</div>';
|
|
565
|
-
h+='<div class="sec"><div class="sec-title">Legend</div><div style="font-size:12px;color:var(--text2);line-height:1.8">'+
|
|
566
|
-
'<div><span style="color:var(--text3)">●</span> Pending</div><div><span style="color:var(--yellow)">●</span> Claimed</div>'+
|
|
567
|
-
'<div><span style="color:var(--green)">●</span> Completed</div><div><span style="color:var(--red)">●</span> Failed</div></div></div>';
|
|
568
|
-
h+='<div class="sec"><div class="sec-title">Tiers</div><div style="font-size:11px;color:var(--text2);line-height:1.7">'+
|
|
569
|
-
'<div><strong style="color:var(--accent)">T1</strong> Full Access</div>'+
|
|
570
|
-
'<div><strong style="color:var(--green)">T2</strong> Limited Write</div>'+
|
|
571
|
-
'<div><strong style="color:var(--purple)">T3</strong> Read-Only</div></div></div>';
|
|
572
|
-
sb.innerHTML=h;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
function renderWaves(){
|
|
576
|
-
var area=document.getElementById('waveArea'),p=PRESETS[S.preset],h='';
|
|
577
|
-
p.waves.forEach(function(w,wi){
|
|
578
|
-
if(wi>0)h+='<div class="wconn"><div class="cline"></div></div>';
|
|
579
|
-
var isA=S.curWave===wi,isD=S.curWave>wi;
|
|
580
|
-
h+='<div class="wave-row"><div class="wave-label">'+
|
|
581
|
-
'<div class="wave-num" style="color:'+(isA?'var(--yellow)':isD?'var(--green)':'var(--accent)')+'">W'+w.wave+'</div>'+
|
|
582
|
-
'<div class="wave-name">'+w.name+'</div></div><div class="wave-tasks">';
|
|
583
|
-
w.tasks.forEach(function(t){
|
|
584
|
-
var tk=S.tasks[t.id],c=AC[tk.agent]||'#888';
|
|
585
|
-
var el='';
|
|
586
|
-
if(tk.st&&tk.et)el=((tk.et-tk.st)/1000).toFixed(1)+'s';
|
|
587
|
-
else if(tk.st)el='...';
|
|
588
|
-
h+='<div class="tcard '+esc(tk.status)+'" onclick="selectTask(\''+esc(t.id)+'\')">'+
|
|
589
|
-
'<div class="tagent"><div class="tagent-dot" style="background:'+esc(c)+'"></div>'+
|
|
590
|
-
'<span class="tagent-name" style="color:'+esc(c)+'">'+esc(AE[tk.agent]||'')+' '+esc(tk.agent)+'</span></div>'+
|
|
591
|
-
'<div class="tdesc">'+esc(tk.desc)+'</div>'+
|
|
592
|
-
'<div class="tmeta"><span class="tstatus '+esc(tk.status)+'">'+esc(tk.status)+'</span>'+
|
|
593
|
-
(el?'<span class="ttime">'+esc(el)+'</span>':'')+'</div></div>';
|
|
594
|
-
});
|
|
595
|
-
h+='</div></div>';
|
|
596
|
-
});
|
|
597
|
-
area.innerHTML=h;
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
function updateProgress(){
|
|
601
|
-
var ts=Object.values(S.tasks),n=ts.length;
|
|
602
|
-
var c=ts.filter(function(t){return t.status==='completed'}).length;
|
|
603
|
-
var a=ts.filter(function(t){return t.status==='claimed'}).length;
|
|
604
|
-
var f=ts.filter(function(t){return t.status==='failed'}).length;
|
|
605
|
-
document.getElementById('ptrack').innerHTML=
|
|
606
|
-
'<div class="pfill c" style="width:'+esc(String(c/n*100))+'%"></div>'+
|
|
607
|
-
'<div class="pfill a" style="width:'+esc(String(a/n*100))+'%"></div>'+
|
|
608
|
-
'<div class="pfill f" style="width:'+esc(String(f/n*100))+'%"></div>';
|
|
609
|
-
document.getElementById('pstats').innerHTML=
|
|
610
|
-
'<span>✅ <strong>'+esc(String(c))+'</strong></span><span>⚡ <strong>'+esc(String(a))+'</strong></span>'+
|
|
611
|
-
'<span>❌ <strong>'+esc(String(f))+'</strong></span><span style="margin-left:auto">Wave <strong>'+esc(String(S.curWave+1))+'</strong>/'+esc(String(S.taskOrder.length))+'</span>';
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
function togglePlay(){if(S.playing)stopSim();else startSim()}
|
|
615
|
-
function startSim(){S.playing=true;document.getElementById('playBtn').textContent='⏸ Pause';document.getElementById('playBtn').classList.add('btn-active');runStep()}
|
|
616
|
-
function stopSim(){S.playing=false;if(S.timer){clearTimeout(S.timer);S.timer=null}document.getElementById('playBtn').textContent='▶ Play';document.getElementById('playBtn').classList.remove('btn-active')}
|
|
617
|
-
function resetSim(){loadPreset(S.preset)}
|
|
618
|
-
function getInterval(){return Math.max(200,2000/(S.speed/5))}
|
|
619
|
-
|
|
620
|
-
function runStep(){
|
|
621
|
-
if(!S.playing)return;
|
|
622
|
-
var wave=S.taskOrder[S.curWave];
|
|
623
|
-
if(!wave){stopSim();return}
|
|
624
|
-
var allDone=true,acted=false;
|
|
625
|
-
for(var i=0;i<wave.length;i++){
|
|
626
|
-
var t=S.tasks[wave[i]];
|
|
627
|
-
if(t.status==='pending'){t.status='claimed';t.st=Date.now();acted=true;allDone=false;break}
|
|
628
|
-
else if(t.status==='claimed'){
|
|
629
|
-
if(Math.random()<0.08&&!S.failedTasks.has(t.id)){t.status='failed';t.et=Date.now();S.failedTasks.add(t.id)}
|
|
630
|
-
else{t.status='completed';t.et=Date.now()}
|
|
631
|
-
acted=true;allDone=false;break;
|
|
632
|
-
}else if(t.status!=='completed'&&t.status!=='failed'){allDone=false}
|
|
633
|
-
}
|
|
634
|
-
if(!acted&&allDone){if(S.curWave<S.taskOrder.length-1)S.curWave++;else stopSim()}
|
|
635
|
-
renderWaves();renderSidebar();updateProgress();updatePrompt();
|
|
636
|
-
if(S.playing)S.timer=setTimeout(runStep,getInterval());
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
document.getElementById('speedSlider').addEventListener('input',function(e){
|
|
640
|
-
S.speed=parseInt(e.target.value);
|
|
641
|
-
document.getElementById('speedLabel').textContent=S.speed<=3?'0.5x':S.speed<=5?'1x':S.speed<=7?'2x':'4x';
|
|
642
|
-
});
|
|
643
|
-
|
|
644
|
-
function selectTask(id){
|
|
645
|
-
S.selTask=id;var t=S.tasks[id],p=document.getElementById('dpanel');
|
|
646
|
-
var tier=t.agent==='conductor'||t.agent==='pm'?1:(t.agent==='reviewer'||t.agent==='qa'||t.agent==='critic')?3:2;
|
|
647
|
-
var h='<div class="dtitle">'+esc(AE[t.agent]||'')+' '+esc(t.id.toUpperCase())+'</div>'+
|
|
648
|
-
'<div class="dfield"><div class="dlabel">Description</div><div class="dvalue">'+esc(t.desc)+'</div></div>'+
|
|
649
|
-
'<div class="dfield"><div class="dlabel">Agent</div><div class="dvalue" style="color:'+esc(AC[t.agent]||'#888')+'">'+esc(t.agent)+' (Tier '+esc(String(tier))+')</div></div>'+
|
|
650
|
-
'<div class="dfield"><div class="dlabel">Wave</div><div class="dvalue">Wave '+esc(String(t.wave))+'</div></div>'+
|
|
651
|
-
'<div class="dfield"><div class="dlabel">Status</div><div class="dvalue"><span class="tstatus '+esc(t.status)+'">'+esc(t.status)+'</span></div></div>'+
|
|
652
|
-
'<div class="dfield"><div class="dlabel">Category</div><div class="dvalue">'+esc(t.category||'-')+'</div></div>';
|
|
653
|
-
if(t.files&&t.files.length){h+='<div class="dfield"><div class="dlabel">Files</div><ul class="dfiles">';t.files.forEach(function(f){h+='<li>'+esc(f)+'</li>'});h+='</ul></div>'}
|
|
654
|
-
if(t.dependsOn&&t.dependsOn.length){
|
|
655
|
-
h+='<div class="dfield"><div class="dlabel">Dependencies</div><div class="ddeps">';
|
|
656
|
-
t.dependsOn.forEach(function(d){var dt=S.tasks[d];var c=dt?(dt.status==='completed'?'var(--green)':dt.status==='failed'?'var(--red)':'var(--text3)'):'var(--text3)';h+='<span class="ddep" style="border-left:2px solid '+esc(c)+'">'+esc(d)+'</span>'});
|
|
657
|
-
h+='</div></div>';
|
|
658
|
-
}
|
|
659
|
-
if(t.st){var el=t.et?((t.et-t.st)/1000).toFixed(1)+'s':'running...';h+='<div class="dfield"><div class="dlabel">Duration</div><div class="dvalue" style="font-family:monospace">'+esc(el)+'</div></div>'}
|
|
660
|
-
p.innerHTML=h;p.classList.add('show');
|
|
661
|
-
}
|
|
662
|
-
function hideDetail(){document.getElementById('dpanel').classList.remove('show');S.selTask=null}
|
|
663
|
-
|
|
664
|
-
function updatePrompt(){
|
|
665
|
-
var p=PRESETS[S.preset],ts=Object.values(S.tasks),n=ts.length;
|
|
666
|
-
var c=ts.filter(function(t){return t.status==='completed'}).length;
|
|
667
|
-
var f=ts.filter(function(t){return t.status==='failed'}).length;
|
|
668
|
-
var a=ts.filter(function(t){return t.status==='claimed'}).length;
|
|
669
|
-
var parts=[];
|
|
670
|
-
parts.push('Preset: '+p.name);
|
|
671
|
-
parts.push('Agents: '+p.agents.join(', '));
|
|
672
|
-
parts.push(p.waves.length+' waves, '+n+' tasks');
|
|
673
|
-
if(c>0||f>0||a>0)parts.push('Progress: '+c+'/'+n+' completed'+(f>0?', '+f+' failed':'')+(a>0?', '+a+' running':''));
|
|
674
|
-
var text=c===n&&n>0?'Multi-agent waves completed. '+n+' tasks completed'+(f>0?' ('+f+' failed)':'')+'.':parts.join('\n');
|
|
675
|
-
document.getElementById('promptText').textContent=text;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
async function copyPrompt(){
|
|
679
|
-
var t=document.getElementById('promptText').textContent;
|
|
680
|
-
try{await navigator.clipboard.writeText(t);document.getElementById('copyPromptBtn').textContent='Copied!';setTimeout(function(){document.getElementById('copyPromptBtn').textContent='Copy'},1500)}catch(e){}
|
|
681
|
-
}
|
|
682
|
-
function sendToChat(){
|
|
683
|
-
var t=document.getElementById('promptText').textContent;if(!t)return;
|
|
684
|
-
window.parent.postMessage({type:'playground:sendToChat',message:t},window.location.origin);
|
|
685
|
-
document.getElementById('sendToChatBtn').textContent='Sent!';
|
|
686
|
-
setTimeout(function(){document.getElementById('sendToChatBtn').textContent='Send to Chat'},1500);
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
document.addEventListener('click',function(e){if(!e.target.closest('.tcard')&&!e.target.closest('.dpanel'))hideDetail()});
|
|
690
|
-
|
|
691
|
-
init();
|
|
692
|
-
</script>
|
|
693
|
-
</body>
|
|
694
|
-
</html>
|