@action-llama/action-llama 0.13.7 → 0.14.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.
- package/agent-docs/AGENTS.md +123 -207
- package/dist/agents/container-entry.d.ts +1 -3
- package/dist/agents/container-entry.d.ts.map +1 -1
- package/dist/agents/container-entry.js +208 -154
- package/dist/agents/container-entry.js.map +1 -1
- package/dist/agents/container-runner.d.ts.map +1 -1
- package/dist/agents/container-runner.js +19 -8
- package/dist/agents/container-runner.js.map +1 -1
- package/dist/agents/context-injection.d.ts +7 -0
- package/dist/agents/context-injection.d.ts.map +1 -0
- package/dist/agents/context-injection.js +27 -0
- package/dist/agents/context-injection.js.map +1 -0
- package/dist/agents/execution-engine.d.ts.map +1 -1
- package/dist/agents/execution-engine.js +99 -109
- package/dist/agents/execution-engine.js.map +1 -1
- package/dist/agents/model-fallback.d.ts +18 -0
- package/dist/agents/model-fallback.d.ts.map +1 -0
- package/dist/agents/model-fallback.js +40 -0
- package/dist/agents/model-fallback.js.map +1 -0
- package/dist/agents/prompt.d.ts +9 -2
- package/dist/agents/prompt.d.ts.map +1 -1
- package/dist/agents/prompt.js +21 -49
- package/dist/agents/prompt.js.map +1 -1
- package/dist/agents/runner.d.ts +2 -0
- package/dist/agents/runner.d.ts.map +1 -1
- package/dist/agents/runner.js +142 -124
- package/dist/agents/runner.js.map +1 -1
- package/dist/agents/session-factory.d.ts +13 -0
- package/dist/agents/session-factory.d.ts.map +1 -0
- package/dist/agents/session-factory.js +27 -0
- package/dist/agents/session-factory.js.map +1 -0
- package/dist/build-info.json +1 -1
- package/dist/cli/commands/agent.d.ts.map +1 -1
- package/dist/cli/commands/agent.js +43 -23
- package/dist/cli/commands/agent.js.map +1 -1
- package/dist/cli/commands/chat.d.ts.map +1 -1
- package/dist/cli/commands/chat.js +26 -43
- package/dist/cli/commands/chat.js.map +1 -1
- package/dist/cli/commands/claude.d.ts +4 -0
- package/dist/cli/commands/claude.d.ts.map +1 -0
- package/dist/cli/commands/claude.js +8 -0
- package/dist/cli/commands/claude.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +24 -6
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts +8 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +31 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/new.d.ts.map +1 -1
- package/dist/cli/commands/new.js +15 -6
- package/dist/cli/commands/new.js.map +1 -1
- package/dist/cli/commands/run.js +1 -1
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/start.js +2 -2
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/stats.d.ts +9 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +149 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +3 -0
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/main.js +50 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/gateway/index.d.ts +3 -0
- package/dist/gateway/index.d.ts.map +1 -1
- package/dist/gateway/index.js +7 -1
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/lock-store.d.ts +10 -0
- package/dist/gateway/lock-store.d.ts.map +1 -1
- package/dist/gateway/lock-store.js +38 -0
- package/dist/gateway/lock-store.js.map +1 -1
- package/dist/gateway/routes/dashboard.d.ts +2 -1
- package/dist/gateway/routes/dashboard.d.ts.map +1 -1
- package/dist/gateway/routes/dashboard.js +26 -6
- package/dist/gateway/routes/dashboard.js.map +1 -1
- package/dist/gateway/routes/locks.d.ts.map +1 -1
- package/dist/gateway/routes/locks.js +39 -0
- package/dist/gateway/routes/locks.js.map +1 -1
- package/dist/gateway/routes/logs.d.ts.map +1 -1
- package/dist/gateway/routes/logs.js +4 -5
- package/dist/gateway/routes/logs.js.map +1 -1
- package/dist/gateway/routes/stats.d.ts +4 -0
- package/dist/gateway/routes/stats.d.ts.map +1 -0
- package/dist/gateway/routes/stats.js +25 -0
- package/dist/gateway/routes/stats.js.map +1 -0
- package/dist/gateway/views/agent-detail-page.d.ts +12 -0
- package/dist/gateway/views/agent-detail-page.d.ts.map +1 -0
- package/dist/gateway/views/agent-detail-page.js +303 -0
- package/dist/gateway/views/agent-detail-page.js.map +1 -0
- package/dist/gateway/views/dashboard-page.d.ts.map +1 -1
- package/dist/gateway/views/dashboard-page.js +179 -245
- package/dist/gateway/views/dashboard-page.js.map +1 -1
- package/dist/gateway/views/instance-detail-page.d.ts +24 -0
- package/dist/gateway/views/instance-detail-page.d.ts.map +1 -0
- package/dist/gateway/views/instance-detail-page.js +277 -0
- package/dist/gateway/views/instance-detail-page.js.map +1 -0
- package/dist/gateway/views/layout.d.ts +17 -0
- package/dist/gateway/views/layout.d.ts.map +1 -0
- package/dist/gateway/views/layout.js +153 -0
- package/dist/gateway/views/layout.js.map +1 -0
- package/dist/gateway/views/login-page.d.ts.map +1 -1
- package/dist/gateway/views/login-page.js +24 -37
- package/dist/gateway/views/login-page.js.map +1 -1
- package/dist/hooks/runner.d.ts +12 -0
- package/dist/hooks/runner.d.ts.map +1 -0
- package/dist/hooks/runner.js +32 -0
- package/dist/hooks/runner.js.map +1 -0
- package/dist/mcp/server.d.ts +5 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +336 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/scheduler/call-dispatcher.d.ts +2 -2
- package/dist/scheduler/call-dispatcher.js +3 -3
- package/dist/scheduler/call-dispatcher.js.map +1 -1
- package/dist/scheduler/execution.d.ts +5 -2
- package/dist/scheduler/execution.d.ts.map +1 -1
- package/dist/scheduler/execution.js +75 -4
- package/dist/scheduler/execution.js.map +1 -1
- package/dist/scheduler/gateway-setup.d.ts +2 -0
- package/dist/scheduler/gateway-setup.d.ts.map +1 -1
- package/dist/scheduler/gateway-setup.js +3 -2
- package/dist/scheduler/gateway-setup.js.map +1 -1
- package/dist/scheduler/image-builder.js +3 -3
- package/dist/scheduler/image-builder.js.map +1 -1
- package/dist/scheduler/index.d.ts.map +1 -1
- package/dist/scheduler/index.js +16 -3
- package/dist/scheduler/index.js.map +1 -1
- package/dist/scheduler/shutdown.d.ts +2 -0
- package/dist/scheduler/shutdown.d.ts.map +1 -1
- package/dist/scheduler/shutdown.js +4 -1
- package/dist/scheduler/shutdown.js.map +1 -1
- package/dist/scheduler/validation.d.ts.map +1 -1
- package/dist/scheduler/validation.js +5 -3
- package/dist/scheduler/validation.js.map +1 -1
- package/dist/scheduler/watcher.d.ts +1 -1
- package/dist/scheduler/watcher.js +1 -1
- package/dist/scheduler/webhook-setup.d.ts +2 -0
- package/dist/scheduler/webhook-setup.d.ts.map +1 -1
- package/dist/scheduler/webhook-setup.js +2 -0
- package/dist/scheduler/webhook-setup.js.map +1 -1
- package/dist/setup/prompts.d.ts.map +1 -1
- package/dist/setup/prompts.js +35 -6
- package/dist/setup/prompts.js.map +1 -1
- package/dist/setup/scaffold.d.ts +6 -0
- package/dist/setup/scaffold.d.ts.map +1 -1
- package/dist/setup/scaffold.js +185 -7
- package/dist/setup/scaffold.js.map +1 -1
- package/dist/shared/config.d.ts +16 -5
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/shared/config.js +75 -18
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/credential-refs.d.ts.map +1 -1
- package/dist/shared/credential-refs.js +8 -0
- package/dist/shared/credential-refs.js.map +1 -1
- package/dist/shared/environment.d.ts +0 -1
- package/dist/shared/environment.d.ts.map +1 -1
- package/dist/shared/environment.js +19 -3
- package/dist/shared/environment.js.map +1 -1
- package/dist/shared/frontmatter.d.ts +11 -0
- package/dist/shared/frontmatter.d.ts.map +1 -0
- package/dist/shared/frontmatter.js +30 -0
- package/dist/shared/frontmatter.js.map +1 -0
- package/dist/shared/paths.d.ts +1 -0
- package/dist/shared/paths.d.ts.map +1 -1
- package/dist/shared/paths.js +3 -0
- package/dist/shared/paths.js.map +1 -1
- package/dist/stats/index.d.ts +3 -0
- package/dist/stats/index.d.ts.map +1 -0
- package/dist/stats/index.js +2 -0
- package/dist/stats/index.js.map +1 -0
- package/dist/stats/store.d.ts +89 -0
- package/dist/stats/store.d.ts.map +1 -0
- package/dist/stats/store.js +242 -0
- package/dist/stats/store.js.map +1 -0
- package/dist/tui/status-tracker.d.ts +6 -1
- package/dist/tui/status-tracker.d.ts.map +1 -1
- package/dist/tui/status-tracker.js +11 -1
- package/dist/tui/status-tracker.js.map +1 -1
- package/docker/bin/{al-call → al-subagent} +2 -2
- package/docker/bin/{al-check → al-subagent-check} +2 -2
- package/docker/bin/{al-wait → al-subagent-wait} +2 -2
- package/package.json +8 -21
- package/LICENSE +0 -21
- package/README.md +0 -192
- package/dist/gateway/views/logs-page.d.ts +0 -2
- package/dist/gateway/views/logs-page.d.ts.map +0 -1
- package/dist/gateway/views/logs-page.js +0 -280
- package/dist/gateway/views/logs-page.js.map +0 -1
- package/dist/preflight/interpolate.d.ts +0 -10
- package/dist/preflight/interpolate.d.ts.map +0 -1
- package/dist/preflight/interpolate.js +0 -33
- package/dist/preflight/interpolate.js.map +0 -1
- package/dist/preflight/providers/git-clone.d.ts +0 -3
- package/dist/preflight/providers/git-clone.d.ts.map +0 -1
- package/dist/preflight/providers/git-clone.js +0 -36
- package/dist/preflight/providers/git-clone.js.map +0 -1
- package/dist/preflight/providers/http.d.ts +0 -3
- package/dist/preflight/providers/http.d.ts.map +0 -1
- package/dist/preflight/providers/http.js +0 -36
- package/dist/preflight/providers/http.js.map +0 -1
- package/dist/preflight/providers/shell.d.ts +0 -3
- package/dist/preflight/providers/shell.d.ts.map +0 -1
- package/dist/preflight/providers/shell.js +0 -28
- package/dist/preflight/providers/shell.js.map +0 -1
- package/dist/preflight/registry.d.ts +0 -4
- package/dist/preflight/registry.d.ts.map +0 -1
- package/dist/preflight/registry.js +0 -20
- package/dist/preflight/registry.js.map +0 -1
- package/dist/preflight/runner.d.ts +0 -7
- package/dist/preflight/runner.d.ts.map +0 -1
- package/dist/preflight/runner.js +0 -28
- package/dist/preflight/runner.js.map +0 -1
- package/dist/preflight/schema.d.ts +0 -21
- package/dist/preflight/schema.d.ts.map +0 -1
- package/dist/preflight/schema.js +0 -9
- package/dist/preflight/schema.js.map +0 -1
|
@@ -1,36 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
return str
|
|
3
|
-
.replace(/&/g, "&")
|
|
4
|
-
.replace(/</g, "<")
|
|
5
|
-
.replace(/>/g, ">")
|
|
6
|
-
.replace(/"/g, """);
|
|
7
|
-
}
|
|
1
|
+
import { escapeHtml, formatDuration, formatTime, formatCost, formatTokens, renderLayout } from "./layout.js";
|
|
8
2
|
function stateColor(state) {
|
|
9
3
|
switch (state) {
|
|
10
|
-
case "running": return "
|
|
11
|
-
case "building": return "
|
|
12
|
-
case "error": return "
|
|
13
|
-
case "idle": return "
|
|
4
|
+
case "running": return { dot: "bg-green-500", text: "text-green-600 dark:text-green-400" };
|
|
5
|
+
case "building": return { dot: "bg-yellow-500", text: "text-yellow-600 dark:text-yellow-400" };
|
|
6
|
+
case "error": return { dot: "bg-red-500", text: "text-red-600 dark:text-red-400" };
|
|
7
|
+
case "idle": return { dot: "bg-slate-400", text: "text-slate-500 dark:text-slate-400" };
|
|
14
8
|
}
|
|
15
9
|
}
|
|
16
|
-
function formatDuration(ms) {
|
|
17
|
-
if (ms < 1000)
|
|
18
|
-
return `${ms}ms`;
|
|
19
|
-
const s = Math.floor(ms / 1000);
|
|
20
|
-
if (s < 60)
|
|
21
|
-
return `${s}s`;
|
|
22
|
-
const m = Math.floor(s / 60);
|
|
23
|
-
return `${m}m ${s % 60}s`;
|
|
24
|
-
}
|
|
25
|
-
function formatTime(date) {
|
|
26
|
-
if (!date)
|
|
27
|
-
return "\u2014";
|
|
28
|
-
return date.toLocaleTimeString();
|
|
29
|
-
}
|
|
30
|
-
function formatLogLine(log) {
|
|
31
|
-
const time = log.timestamp.toLocaleTimeString();
|
|
32
|
-
return `<span class="log-time">${escapeHtml(time)}</span> <span class="log-agent">[${escapeHtml(log.agent)}]</span> ${escapeHtml(log.message)}`;
|
|
33
|
-
}
|
|
34
10
|
function formatScale(agent) {
|
|
35
11
|
if (agent.state === "running" && agent.scale > 1)
|
|
36
12
|
return `running ${agent.runningCount}/${agent.scale}`;
|
|
@@ -38,262 +14,229 @@ function formatScale(agent) {
|
|
|
38
14
|
return `${agent.state} (\u00d7${agent.scale})`;
|
|
39
15
|
return agent.state;
|
|
40
16
|
}
|
|
41
|
-
function
|
|
42
|
-
const
|
|
43
|
-
|
|
17
|
+
function renderStatCard(label, value, id) {
|
|
18
|
+
const idAttr = id ? ` id="${id}"` : "";
|
|
19
|
+
return `<div class="bg-slate-50 dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 p-3 sm:p-4">
|
|
20
|
+
<div class="text-xs text-slate-500 dark:text-slate-400 uppercase tracking-wide mb-1">${escapeHtml(label)}</div>
|
|
21
|
+
<div class="text-lg sm:text-xl font-semibold text-slate-900 dark:text-white"${idAttr}>${value}</div>
|
|
22
|
+
</div>`;
|
|
23
|
+
}
|
|
24
|
+
function renderTokenBar(agent, totalSessionTokens) {
|
|
25
|
+
const tokens = agent.cumulativeUsage?.totalTokens ?? 0;
|
|
26
|
+
const pct = totalSessionTokens > 0 ? Math.round((tokens / totalSessionTokens) * 100) : 0;
|
|
27
|
+
return `<div class="flex items-center gap-2">
|
|
28
|
+
<div class="flex-1 h-2 bg-slate-200 dark:bg-slate-700 rounded-full overflow-hidden" style="min-width:60px">
|
|
29
|
+
<div class="h-full bg-blue-500 rounded-full" style="width:${pct}%"></div>
|
|
30
|
+
</div>
|
|
31
|
+
<span class="text-xs text-slate-500 dark:text-slate-400 whitespace-nowrap">${formatTokens(tokens)}</span>
|
|
32
|
+
</div>`;
|
|
33
|
+
}
|
|
34
|
+
function renderAgentRow(agent, totalSessionTokens) {
|
|
35
|
+
const colors = stateColor(agent.state);
|
|
44
36
|
const toggleLabel = agent.enabled ? "Disable" : "Enable";
|
|
45
37
|
const toggleAction = agent.enabled ? "disable" : "enable";
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
<td
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
38
|
+
const descHtml = agent.description
|
|
39
|
+
? `<div class="text-xs text-slate-400 mt-0.5">${escapeHtml(agent.description)}</div>`
|
|
40
|
+
: "";
|
|
41
|
+
return `<tr data-agent="${escapeHtml(agent.name)}" class="hover:bg-slate-50 dark:hover:bg-slate-900/50 transition-colors">
|
|
42
|
+
<td class="px-3 py-2.5">
|
|
43
|
+
<a href="/dashboard/agents/${escapeHtml(agent.name)}" class="text-blue-600 dark:text-blue-400 hover:underline font-medium">${escapeHtml(agent.name)}</a>
|
|
44
|
+
${descHtml}
|
|
45
|
+
</td>
|
|
46
|
+
<td class="px-3 py-2.5"><span class="state-dot ${colors.dot} mr-1.5 inline-block"></span><span class="${colors.text} text-sm">${escapeHtml(formatScale(agent))}</span></td>
|
|
47
|
+
<td class="px-3 py-2.5 text-sm text-slate-600 dark:text-slate-300">${formatTime(agent.lastRunAt)}</td>
|
|
48
|
+
<td class="px-3 py-2.5 text-sm text-slate-600 dark:text-slate-300">${agent.lastRunDuration != null ? formatDuration(agent.lastRunDuration) : "\u2014"}</td>
|
|
49
|
+
<td class="px-3 py-2.5 text-sm text-slate-600 dark:text-slate-300">${formatTime(agent.nextRunAt)}</td>
|
|
50
|
+
<td class="px-3 py-2.5" style="min-width:120px">${renderTokenBar(agent, totalSessionTokens)}</td>
|
|
51
|
+
<td class="px-3 py-2.5 whitespace-nowrap">
|
|
52
|
+
<button class="px-2 py-1 text-xs rounded font-bold bg-green-600 hover:bg-green-700 text-white transition-colors mr-1" onclick="triggerAgent('${escapeHtml(agent.name)}')">Run</button>
|
|
53
|
+
<button class="px-2 py-1 text-xs rounded font-bold bg-red-600 hover:bg-red-700 text-white transition-colors mr-1" onclick="killAgent('${escapeHtml(agent.name)}')">Kill</button>
|
|
54
|
+
<button class="px-2 py-1 text-xs rounded font-bold border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 transition-colors" onclick="toggleAgent('${escapeHtml(agent.name)}','${toggleAction}')">${toggleLabel}</button>
|
|
56
55
|
</td>
|
|
57
56
|
</tr>`;
|
|
58
57
|
}
|
|
59
58
|
function renderAgentCard(agent) {
|
|
60
|
-
const
|
|
61
|
-
const statusText = agent.statusText || agent.lastError || "\u2014";
|
|
59
|
+
const colors = stateColor(agent.state);
|
|
62
60
|
const toggleLabel = agent.enabled ? "Disable" : "Enable";
|
|
63
61
|
const toggleAction = agent.enabled ? "disable" : "enable";
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
const descHtml = agent.description
|
|
63
|
+
? `<div class="text-xs text-slate-400 mb-1">${escapeHtml(agent.description)}</div>`
|
|
64
|
+
: "";
|
|
65
|
+
return `<div class="bg-white dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 p-3 mb-2">
|
|
66
|
+
<a href="/dashboard/agents/${escapeHtml(agent.name)}" class="block">
|
|
67
|
+
<div class="flex justify-between items-center mb-1">
|
|
68
|
+
<span class="text-blue-600 dark:text-blue-400 font-semibold text-sm">${escapeHtml(agent.name)}</span>
|
|
69
|
+
<span class="text-xs ${colors.text}"><span class="state-dot ${colors.dot} mr-1 inline-block"></span>${escapeHtml(formatScale(agent))}</span>
|
|
69
70
|
</div>
|
|
70
|
-
|
|
71
|
-
<div class="
|
|
71
|
+
${descHtml}
|
|
72
|
+
<div class="flex gap-3 text-xs text-slate-400">
|
|
72
73
|
<span>Last: ${formatTime(agent.lastRunAt)}</span>
|
|
73
74
|
<span>${agent.lastRunDuration != null ? formatDuration(agent.lastRunDuration) : ""}</span>
|
|
74
75
|
<span>Next: ${formatTime(agent.nextRunAt)}</span>
|
|
75
76
|
</div>
|
|
76
77
|
</a>
|
|
77
|
-
<div class="
|
|
78
|
-
<button class="
|
|
79
|
-
<button class="
|
|
78
|
+
<div class="flex gap-2 mt-2 pt-2 border-t border-slate-100 dark:border-slate-800">
|
|
79
|
+
<button class="px-2.5 py-1 text-xs rounded font-bold bg-green-600 hover:bg-green-700 text-white transition-colors" onclick="triggerAgent('${escapeHtml(agent.name)}')">Run</button>
|
|
80
|
+
<button class="px-2.5 py-1 text-xs rounded font-bold bg-red-600 hover:bg-red-700 text-white transition-colors" onclick="killAgent('${escapeHtml(agent.name)}')">Kill</button>
|
|
81
|
+
<button class="px-2.5 py-1 text-xs rounded font-bold border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 transition-colors" onclick="toggleAgent('${escapeHtml(agent.name)}','${toggleAction}')">${toggleLabel}</button>
|
|
80
82
|
</div>
|
|
81
83
|
</div>`;
|
|
82
84
|
}
|
|
85
|
+
function formatLogLine(log) {
|
|
86
|
+
const time = log.timestamp.toLocaleTimeString();
|
|
87
|
+
return `<span class="text-slate-400">${escapeHtml(time)}</span> <span class="text-indigo-400">[${escapeHtml(log.agent)}]</span> ${escapeHtml(log.message)}`;
|
|
88
|
+
}
|
|
83
89
|
export function renderDashboardPage(agents, schedulerInfo, recentLogs) {
|
|
84
|
-
const
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
94
|
-
<title>Action Llama Dashboard</title>
|
|
95
|
-
<style>
|
|
96
|
-
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
97
|
-
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; background: #0f172a; color: #e2e8f0; padding: 16px; }
|
|
98
|
-
h1 { font-size: 1.5rem; margin-bottom: 8px; color: #f8fafc; }
|
|
99
|
-
.header { display: flex; align-items: baseline; gap: 12px 20px; margin-bottom: 24px; flex-wrap: wrap; }
|
|
100
|
-
.header-stat { font-size: 0.85rem; color: #94a3b8; white-space: nowrap; }
|
|
101
|
-
.header-stat strong { color: #cbd5e1; }
|
|
102
|
-
|
|
103
|
-
/* Desktop table */
|
|
104
|
-
.agent-table { width: 100%; border-collapse: collapse; margin-bottom: 32px; }
|
|
105
|
-
.agent-table th { text-align: left; padding: 8px 12px; border-bottom: 2px solid #334155; color: #94a3b8; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; }
|
|
106
|
-
.agent-table td { padding: 8px 12px; border-bottom: 1px solid #1e293b; font-size: 0.9rem; }
|
|
107
|
-
.agent-table td a { color: #60a5fa; text-decoration: none; }
|
|
108
|
-
.agent-table td a:hover { text-decoration: underline; }
|
|
109
|
-
.agent-table tr:hover { background: #1e293b; }
|
|
110
|
-
.status-text { max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #94a3b8; }
|
|
111
|
-
|
|
112
|
-
/* Mobile cards (hidden on desktop) */
|
|
113
|
-
.agent-cards { display: none; margin-bottom: 24px; }
|
|
114
|
-
.agent-card { display: block; background: #1e293b; border-radius: 8px; padding: 12px 16px; margin-bottom: 8px; text-decoration: none; color: #e2e8f0; border: 1px solid #334155; }
|
|
115
|
-
.agent-card:active { background: #334155; }
|
|
116
|
-
.card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; }
|
|
117
|
-
.card-name { color: #60a5fa; font-weight: 600; font-size: 0.95rem; }
|
|
118
|
-
.card-status { color: #94a3b8; font-size: 0.8rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 6px; }
|
|
119
|
-
.card-meta { display: flex; gap: 12px; font-size: 0.75rem; color: #64748b; flex-wrap: wrap; }
|
|
120
|
-
|
|
121
|
-
.state-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; vertical-align: middle; }
|
|
122
|
-
|
|
123
|
-
h2 { font-size: 1.1rem; margin-bottom: 12px; color: #f8fafc; }
|
|
124
|
-
.logs { background: #1e293b; border-radius: 8px; padding: 12px; font-family: 'SF Mono', 'Fira Code', monospace; font-size: 0.75rem; line-height: 1.6; max-height: 300px; overflow-y: auto; }
|
|
125
|
-
.log-line { white-space: pre-wrap; word-break: break-all; }
|
|
126
|
-
.log-time { color: #64748b; }
|
|
127
|
-
.log-agent { color: #818cf8; }
|
|
128
|
-
.empty { color: #475569; font-style: italic; }
|
|
129
|
-
|
|
130
|
-
.btn { background: #334155; color: #e2e8f0; border: 1px solid #475569; border-radius: 4px; padding: 4px 10px; font-size: 0.75rem; cursor: pointer; transition: background 0.15s; }
|
|
131
|
-
.btn:hover { background: #475569; }
|
|
132
|
-
.btn-sm { padding: 3px 8px; font-size: 0.7rem; }
|
|
133
|
-
.btn-outline { background: transparent; }
|
|
134
|
-
.btn-outline:hover { background: #1e293b; }
|
|
135
|
-
.btn-primary { background: #3b82f6; border-color: #3b82f6; color: #fff; }
|
|
136
|
-
.btn-primary:hover { background: #2563eb; }
|
|
137
|
-
.actions { white-space: nowrap; }
|
|
138
|
-
.actions button { margin-right: 4px; }
|
|
139
|
-
.card-actions { display: flex; gap: 6px; margin-top: 8px; }
|
|
140
|
-
.card-link { display: block; text-decoration: none; color: #e2e8f0; }
|
|
141
|
-
.header-actions { display: flex; gap: 8px; align-items: center; margin-left: auto; }
|
|
142
|
-
.header-actions a { color: #94a3b8; font-size: 0.85rem; text-decoration: none; }
|
|
143
|
-
.header-actions a:hover { color: #e2e8f0; }
|
|
144
|
-
|
|
145
|
-
@media (max-width: 640px) {
|
|
146
|
-
body { padding: 12px; }
|
|
147
|
-
h1 { font-size: 1.25rem; }
|
|
148
|
-
.header { gap: 6px 14px; margin-bottom: 16px; }
|
|
149
|
-
.header-stat { font-size: 0.75rem; }
|
|
150
|
-
.agent-table { display: none; }
|
|
151
|
-
.agent-cards { display: block; }
|
|
152
|
-
.logs { font-size: 0.7rem; padding: 10px; max-height: 250px; }
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
@media (min-width: 641px) {
|
|
156
|
-
body { padding: 24px; }
|
|
157
|
-
.logs { font-size: 0.8rem; padding: 16px; }
|
|
158
|
-
}
|
|
159
|
-
</style>
|
|
160
|
-
</head>
|
|
161
|
-
<body>
|
|
162
|
-
<div class="header">
|
|
163
|
-
<h1>Action Llama</h1>
|
|
164
|
-
<span class="header-stat">Mode: <strong>${escapeHtml(mode)}</strong></span>
|
|
165
|
-
<span class="header-stat">Runtime: <strong>${escapeHtml(runtime)}</strong></span>
|
|
166
|
-
<span class="header-stat">Agents: <strong>${agents.length}</strong></span>
|
|
167
|
-
<span class="header-stat">Cron: <strong>${cronCount}</strong></span>
|
|
168
|
-
<span class="header-stat">Webhooks: <strong>${escapeHtml(webhooks)}</strong></span>
|
|
169
|
-
<span class="header-stat">Uptime: <strong id="uptime">${escapeHtml(uptime)}</strong></span>
|
|
170
|
-
<span class="header-actions">
|
|
171
|
-
<button id="pause-btn" class="btn btn-sm" onclick="togglePause()">${schedulerInfo?.paused ? "Resume" : "Pause"}</button>
|
|
172
|
-
<a href="#" onclick="doLogout(); return false;">Logout</a>
|
|
173
|
-
</span>
|
|
174
|
-
</div>
|
|
90
|
+
const sessionTokens = agents.reduce((sum, a) => sum + (a.cumulativeUsage?.totalTokens ?? 0), 0);
|
|
91
|
+
const sessionCost = agents.reduce((sum, a) => sum + (a.cumulativeUsage?.cost ?? 0), 0);
|
|
92
|
+
const content = `
|
|
93
|
+
<div class="flex flex-wrap items-center justify-between gap-3 mb-6">
|
|
94
|
+
<h1 class="text-xl sm:text-2xl font-bold text-slate-900 dark:text-white">Dashboard</h1>
|
|
95
|
+
<div class="flex items-center gap-2">
|
|
96
|
+
<button id="pause-btn" class="px-3 py-1.5 text-sm rounded-md font-bold border border-yellow-500 bg-yellow-500 hover:bg-yellow-600 text-white transition-colors" onclick="togglePause()">${schedulerInfo?.paused ? "Resume" : "Pause"}</button>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
175
99
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
<th>State</th>
|
|
181
|
-
<th>Status</th>
|
|
182
|
-
<th>Last Run</th>
|
|
183
|
-
<th>Duration</th>
|
|
184
|
-
<th>Next Run</th>
|
|
185
|
-
<th>Actions</th>
|
|
186
|
-
</tr>
|
|
187
|
-
</thead>
|
|
188
|
-
<tbody id="agent-table-body">
|
|
189
|
-
${agents.length > 0 ? agents.map(renderAgentRow).join("\n ") : '<tr><td colspan="7" class="empty">No agents registered</td></tr>'}
|
|
190
|
-
</tbody>
|
|
191
|
-
</table>
|
|
100
|
+
<div class="grid grid-cols-2 gap-3 mb-6">
|
|
101
|
+
${renderStatCard("Session Tokens", formatTokens(sessionTokens), "stat-tokens")}
|
|
102
|
+
${renderStatCard("Session Cost", formatCost(sessionCost), "stat-cost")}
|
|
103
|
+
</div>
|
|
192
104
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
105
|
+
<!-- Desktop table -->
|
|
106
|
+
<div class="hidden sm:block mb-8">
|
|
107
|
+
<table class="w-full">
|
|
108
|
+
<thead>
|
|
109
|
+
<tr class="border-b-2 border-slate-200 dark:border-slate-700">
|
|
110
|
+
<th class="text-left px-3 py-2 text-xs text-slate-500 dark:text-slate-400 uppercase tracking-wider font-medium">Agent</th>
|
|
111
|
+
<th class="text-left px-3 py-2 text-xs text-slate-500 dark:text-slate-400 uppercase tracking-wider font-medium">State</th>
|
|
112
|
+
<th class="text-left px-3 py-2 text-xs text-slate-500 dark:text-slate-400 uppercase tracking-wider font-medium">Last Run</th>
|
|
113
|
+
<th class="text-left px-3 py-2 text-xs text-slate-500 dark:text-slate-400 uppercase tracking-wider font-medium">Duration</th>
|
|
114
|
+
<th class="text-left px-3 py-2 text-xs text-slate-500 dark:text-slate-400 uppercase tracking-wider font-medium">Next Run</th>
|
|
115
|
+
<th class="text-left px-3 py-2 text-xs text-slate-500 dark:text-slate-400 uppercase tracking-wider font-medium">Tokens Used</th>
|
|
116
|
+
<th class="text-left px-3 py-2 text-xs text-slate-500 dark:text-slate-400 uppercase tracking-wider font-medium">Actions</th>
|
|
117
|
+
</tr>
|
|
118
|
+
</thead>
|
|
119
|
+
<tbody id="agent-table-body" class="divide-y divide-slate-100 dark:divide-slate-800">
|
|
120
|
+
${agents.length > 0 ? agents.map((a) => renderAgentRow(a, sessionTokens)).join("\n") : '<tr><td colspan="7" class="px-3 py-8 text-center text-slate-400 italic">No agents registered</td></tr>'}
|
|
121
|
+
</tbody>
|
|
122
|
+
</table>
|
|
123
|
+
</div>
|
|
196
124
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
125
|
+
<!-- Mobile cards -->
|
|
126
|
+
<div class="sm:hidden mb-6" id="agent-cards">
|
|
127
|
+
${agents.length > 0 ? agents.map(renderAgentCard).join("\n") : '<div class="text-slate-400 italic text-center py-6">No agents registered</div>'}
|
|
128
|
+
</div>
|
|
201
129
|
|
|
202
|
-
|
|
203
|
-
|
|
130
|
+
<h2 class="text-base font-semibold text-slate-900 dark:text-white mb-3">Recent Activity</h2>
|
|
131
|
+
<div class="bg-slate-50 dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 p-3 sm:p-4 font-mono text-xs sm:text-sm leading-relaxed max-h-72 overflow-y-auto scrollbar-thin" id="recent-logs">
|
|
132
|
+
${recentLogs.length > 0 ? recentLogs.map((l) => `<div class="whitespace-pre-wrap break-all">${formatLogLine(l)}</div>`).join("\n") : '<div class="text-slate-400 italic">No recent activity</div>'}
|
|
133
|
+
</div>`;
|
|
134
|
+
const scripts = `<script>
|
|
135
|
+
var stateColors = { running: "bg-green-500", building: "bg-yellow-500", error: "bg-red-500", idle: "bg-slate-400" };
|
|
136
|
+
var stateTextColors = { running: "text-green-600 dark:text-green-400", building: "text-yellow-600 dark:text-yellow-400", error: "text-red-600 dark:text-red-400", idle: "text-slate-500 dark:text-slate-400" };
|
|
204
137
|
|
|
205
|
-
function
|
|
138
|
+
function fmtScale(a) {
|
|
139
|
+
if (a.state === "running" && a.scale > 1) return "running " + a.runningCount + "/" + a.scale;
|
|
140
|
+
if (a.scale > 1) return a.state + " (\\u00d7" + a.scale + ")";
|
|
141
|
+
return a.state;
|
|
142
|
+
}
|
|
206
143
|
|
|
207
|
-
function
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
144
|
+
function sessionTotalTokens(agents) {
|
|
145
|
+
var total = 0;
|
|
146
|
+
for (var i = 0; i < agents.length; i++) {
|
|
147
|
+
if (agents[i].cumulativeUsage) total += agents[i].cumulativeUsage.totalTokens || 0;
|
|
148
|
+
}
|
|
149
|
+
return total;
|
|
212
150
|
}
|
|
213
151
|
|
|
214
|
-
function
|
|
215
|
-
|
|
216
|
-
|
|
152
|
+
function sessionTotalCost(agents) {
|
|
153
|
+
var total = 0;
|
|
154
|
+
for (var i = 0; i < agents.length; i++) {
|
|
155
|
+
if (agents[i].cumulativeUsage) total += agents[i].cumulativeUsage.cost || 0;
|
|
156
|
+
}
|
|
157
|
+
return total;
|
|
217
158
|
}
|
|
218
159
|
|
|
219
|
-
function
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return
|
|
160
|
+
function tokenBar(a, totalTokens) {
|
|
161
|
+
var tokens = (a.cumulativeUsage && a.cumulativeUsage.totalTokens) || 0;
|
|
162
|
+
var pct = totalTokens > 0 ? Math.round((tokens / totalTokens) * 100) : 0;
|
|
163
|
+
return '<div class="flex items-center gap-2">' +
|
|
164
|
+
'<div class="flex-1 h-2 bg-slate-200 dark:bg-slate-700 rounded-full overflow-hidden" style="min-width:60px">' +
|
|
165
|
+
'<div class="h-full bg-blue-500 rounded-full" style="width:' + pct + '%"></div></div>' +
|
|
166
|
+
'<span class="text-xs text-slate-500 dark:text-slate-400 whitespace-nowrap">' + fmtTokens(tokens) + '</span></div>';
|
|
223
167
|
}
|
|
224
168
|
|
|
169
|
+
var _cachedAgents = null;
|
|
170
|
+
|
|
225
171
|
function renderRow(a) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
'<td
|
|
233
|
-
'<td class="
|
|
234
|
-
'<td>' + fmtTime(a.lastRunAt) + '</td>' +
|
|
235
|
-
'<td>' + (a.lastRunDuration != null ? fmtDur(a.lastRunDuration) : "\\u2014") + '</td>' +
|
|
236
|
-
'<td>' + fmtTime(a.nextRunAt) + '</td>' +
|
|
237
|
-
'<td class="
|
|
238
|
-
'<
|
|
239
|
-
'</
|
|
172
|
+
var dotClass = stateColors[a.state] || "bg-slate-400";
|
|
173
|
+
var textClass = stateTextColors[a.state] || "text-slate-400";
|
|
174
|
+
var toggleLabel = a.enabled ? "Disable" : "Enable";
|
|
175
|
+
var toggleAction = a.enabled ? "disable" : "enable";
|
|
176
|
+
var totalTok = _cachedAgents ? sessionTotalTokens(_cachedAgents) : 0;
|
|
177
|
+
return '<tr data-agent="' + esc(a.name) + '" class="hover:bg-slate-50 dark:hover:bg-slate-900/50 transition-colors">' +
|
|
178
|
+
'<td class="px-3 py-2.5"><a href="/dashboard/agents/' + esc(a.name) + '" class="text-blue-600 dark:text-blue-400 hover:underline font-medium">' + esc(a.name) + '</a></td>' +
|
|
179
|
+
'<td class="px-3 py-2.5"><span class="state-dot ' + dotClass + ' mr-1.5 inline-block"></span><span class="' + textClass + ' text-sm">' + esc(fmtScale(a)) + '</span></td>' +
|
|
180
|
+
'<td class="px-3 py-2.5 text-sm text-slate-600 dark:text-slate-300">' + fmtTime(a.lastRunAt) + '</td>' +
|
|
181
|
+
'<td class="px-3 py-2.5 text-sm text-slate-600 dark:text-slate-300">' + (a.lastRunDuration != null ? fmtDur(a.lastRunDuration) : "\\u2014") + '</td>' +
|
|
182
|
+
'<td class="px-3 py-2.5 text-sm text-slate-600 dark:text-slate-300">' + fmtTime(a.nextRunAt) + '</td>' +
|
|
183
|
+
'<td class="px-3 py-2.5" style="min-width:120px">' + tokenBar(a, totalTok) + '</td>' +
|
|
184
|
+
'<td class="px-3 py-2.5 whitespace-nowrap">' +
|
|
185
|
+
'<button class="px-2 py-1 text-xs rounded font-bold bg-green-600 hover:bg-green-700 text-white transition-colors mr-1" onclick="triggerAgent(\\'' + esc(a.name) + '\\')">Run</button>' +
|
|
186
|
+
'<button class="px-2 py-1 text-xs rounded font-bold bg-red-600 hover:bg-red-700 text-white transition-colors mr-1" onclick="killAgent(\\'' + esc(a.name) + '\\')">Kill</button>' +
|
|
187
|
+
'<button class="px-2 py-1 text-xs rounded font-bold border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 transition-colors" onclick="toggleAgent(\\'' + esc(a.name) + '\\',\\'' + toggleAction + '\\')">' + toggleLabel + '</button></td></tr>';
|
|
240
188
|
}
|
|
241
189
|
|
|
242
190
|
function renderCard(a) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
return '<div class="
|
|
248
|
-
'<
|
|
249
|
-
'<
|
|
250
|
-
'<
|
|
251
|
-
'<div class="
|
|
252
|
-
'<
|
|
253
|
-
'<
|
|
254
|
-
'<
|
|
255
|
-
'<button class="
|
|
191
|
+
var dotClass = stateColors[a.state] || "bg-slate-400";
|
|
192
|
+
var textClass = stateTextColors[a.state] || "text-slate-400";
|
|
193
|
+
var toggleLabel = a.enabled ? "Disable" : "Enable";
|
|
194
|
+
var toggleAction = a.enabled ? "disable" : "enable";
|
|
195
|
+
return '<div class="bg-white dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 p-3 mb-2">' +
|
|
196
|
+
'<a href="/dashboard/agents/' + esc(a.name) + '" class="block">' +
|
|
197
|
+
'<div class="flex justify-between items-center mb-1"><span class="text-blue-600 dark:text-blue-400 font-semibold text-sm">' + esc(a.name) + '</span>' +
|
|
198
|
+
'<span class="text-xs ' + textClass + '"><span class="state-dot ' + dotClass + ' mr-1 inline-block"></span>' + esc(fmtScale(a)) + '</span></div>' +
|
|
199
|
+
'<div class="flex gap-3 text-xs text-slate-400"><span>Last: ' + fmtTime(a.lastRunAt) + '</span><span>' + (a.lastRunDuration != null ? fmtDur(a.lastRunDuration) : "") + '</span><span>Next: ' + fmtTime(a.nextRunAt) + '</span></div></a>' +
|
|
200
|
+
'<div class="flex gap-2 mt-2 pt-2 border-t border-slate-100 dark:border-slate-800">' +
|
|
201
|
+
'<button class="px-2.5 py-1 text-xs rounded font-bold bg-green-600 hover:bg-green-700 text-white transition-colors" onclick="triggerAgent(\\'' + esc(a.name) + '\\')">Run</button>' +
|
|
202
|
+
'<button class="px-2.5 py-1 text-xs rounded font-bold bg-red-600 hover:bg-red-700 text-white transition-colors" onclick="killAgent(\\'' + esc(a.name) + '\\')">Kill</button>' +
|
|
203
|
+
'<button class="px-2.5 py-1 text-xs rounded font-bold border border-slate-300 dark:border-slate-600 bg-white dark:bg-slate-800 hover:bg-slate-50 dark:hover:bg-slate-700 text-slate-700 dark:text-slate-200 transition-colors" onclick="toggleAgent(\\'' + esc(a.name) + '\\',\\'' + toggleAction + '\\')">' + toggleLabel + '</button></div></div>';
|
|
256
204
|
}
|
|
257
205
|
|
|
258
206
|
function renderLog(l) {
|
|
259
|
-
|
|
260
|
-
return '<div class="
|
|
207
|
+
var t = new Date(l.timestamp).toLocaleTimeString();
|
|
208
|
+
return '<div class="whitespace-pre-wrap break-all"><span class="text-slate-400">' + esc(t) + '</span> <span class="text-indigo-400">[' + esc(l.agent) + ']</span> ' + esc(l.message) + '</div>';
|
|
261
209
|
}
|
|
262
210
|
|
|
263
|
-
|
|
211
|
+
var es = new EventSource("/dashboard/api/status-stream");
|
|
264
212
|
es.onmessage = function(e) {
|
|
265
|
-
|
|
266
|
-
|
|
213
|
+
var data = JSON.parse(e.data);
|
|
267
214
|
if (data.agents) {
|
|
268
|
-
|
|
269
|
-
|
|
215
|
+
_cachedAgents = data.agents;
|
|
216
|
+
var tbody = document.getElementById("agent-table-body");
|
|
270
217
|
if (data.agents.length > 0) {
|
|
271
218
|
tbody.innerHTML = data.agents.map(renderRow).join("");
|
|
272
219
|
} else {
|
|
273
|
-
tbody.innerHTML = '<tr><td colspan="7" class="
|
|
220
|
+
tbody.innerHTML = '<tr><td colspan="7" class="px-3 py-8 text-center text-slate-400 italic">No agents registered</td></tr>';
|
|
274
221
|
}
|
|
275
|
-
|
|
276
|
-
// Update mobile cards
|
|
277
|
-
const cards = document.getElementById("agent-cards");
|
|
222
|
+
var cards = document.getElementById("agent-cards");
|
|
278
223
|
if (data.agents.length > 0) {
|
|
279
224
|
cards.innerHTML = data.agents.map(renderCard).join("");
|
|
280
225
|
} else {
|
|
281
|
-
cards.innerHTML = '<div class="
|
|
226
|
+
cards.innerHTML = '<div class="text-slate-400 italic text-center py-6">No agents registered</div>';
|
|
282
227
|
}
|
|
228
|
+
// Update session stats
|
|
229
|
+
var tokEl = document.getElementById("stat-tokens");
|
|
230
|
+
var costEl = document.getElementById("stat-cost");
|
|
231
|
+
if (tokEl) tokEl.textContent = fmtTokens(sessionTotalTokens(data.agents));
|
|
232
|
+
if (costEl) costEl.textContent = fmtCost(sessionTotalCost(data.agents));
|
|
283
233
|
}
|
|
284
|
-
|
|
285
|
-
// Update recent logs
|
|
286
|
-
const logsDiv = document.getElementById("recent-logs");
|
|
287
234
|
if (data.recentLogs && data.recentLogs.length > 0) {
|
|
235
|
+
var logsDiv = document.getElementById("recent-logs");
|
|
288
236
|
logsDiv.innerHTML = data.recentLogs.map(renderLog).join("");
|
|
289
237
|
logsDiv.scrollTop = logsDiv.scrollHeight;
|
|
290
238
|
}
|
|
291
|
-
|
|
292
|
-
// Update uptime and pause button
|
|
293
239
|
if (data.schedulerInfo) {
|
|
294
|
-
if (data.schedulerInfo.startedAt) {
|
|
295
|
-
document.getElementById("uptime").textContent = fmtDur(Date.now() - new Date(data.schedulerInfo.startedAt).getTime());
|
|
296
|
-
}
|
|
297
240
|
var btn = document.getElementById("pause-btn");
|
|
298
241
|
if (btn) {
|
|
299
242
|
schedulerPaused = !!data.schedulerInfo.paused;
|
|
@@ -304,29 +247,20 @@ export function renderDashboardPage(agents, schedulerInfo, recentLogs) {
|
|
|
304
247
|
|
|
305
248
|
var schedulerPaused = ${schedulerInfo?.paused ? "true" : "false"};
|
|
306
249
|
|
|
307
|
-
function ctrlPost(path) {
|
|
308
|
-
return fetch(path, { method: "POST", credentials: "same-origin" }).then(function(r) { return r.json(); });
|
|
309
|
-
}
|
|
310
|
-
|
|
311
250
|
function triggerAgent(name) {
|
|
312
251
|
ctrlPost("/control/trigger/" + encodeURIComponent(name));
|
|
313
252
|
}
|
|
314
|
-
|
|
315
253
|
function toggleAgent(name, action) {
|
|
316
254
|
ctrlPost("/control/agents/" + encodeURIComponent(name) + "/" + action);
|
|
317
255
|
}
|
|
318
|
-
|
|
256
|
+
function killAgent(name) {
|
|
257
|
+
if (!confirm("Kill all instances of agent '" + name + "'?")) return;
|
|
258
|
+
ctrlPost("/control/agents/" + encodeURIComponent(name) + "/kill");
|
|
259
|
+
}
|
|
319
260
|
function togglePause() {
|
|
320
261
|
ctrlPost(schedulerPaused ? "/control/resume" : "/control/pause");
|
|
321
262
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
fetch("/logout", { method: "POST", credentials: "same-origin" }).then(function() {
|
|
325
|
-
window.location.href = "/login";
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
</script>
|
|
329
|
-
</body>
|
|
330
|
-
</html>`;
|
|
263
|
+
</script>`;
|
|
264
|
+
return renderLayout({ title: "Dashboard", content, scripts });
|
|
331
265
|
}
|
|
332
266
|
//# sourceMappingURL=dashboard-page.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard-page.js","sourceRoot":"","sources":["../../../src/gateway/views/dashboard-page.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dashboard-page.js","sourceRoot":"","sources":["../../../src/gateway/views/dashboard-page.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface InstanceDetailData {
|
|
2
|
+
agentName: string;
|
|
3
|
+
instanceId: string;
|
|
4
|
+
run: {
|
|
5
|
+
instance_id: string;
|
|
6
|
+
agent_name: string;
|
|
7
|
+
trigger_type: string;
|
|
8
|
+
trigger_source?: string;
|
|
9
|
+
result: string;
|
|
10
|
+
exit_code?: number;
|
|
11
|
+
started_at: number;
|
|
12
|
+
duration_ms: number;
|
|
13
|
+
input_tokens: number;
|
|
14
|
+
output_tokens: number;
|
|
15
|
+
cache_read_tokens: number;
|
|
16
|
+
cache_write_tokens: number;
|
|
17
|
+
total_tokens: number;
|
|
18
|
+
cost_usd: number;
|
|
19
|
+
turn_count: number;
|
|
20
|
+
error_message?: string;
|
|
21
|
+
} | null;
|
|
22
|
+
}
|
|
23
|
+
export declare function renderInstanceDetailPage(data: InstanceDetailData): string;
|
|
24
|
+
//# sourceMappingURL=instance-detail-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance-detail-page.d.ts","sourceRoot":"","sources":["../../../src/gateway/views/instance-detail-page.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE;QACH,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GAAG,IAAI,CAAC;CACV;AAqBD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAoFzE"}
|