@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.
Files changed (218) hide show
  1. package/agent-docs/AGENTS.md +123 -207
  2. package/dist/agents/container-entry.d.ts +1 -3
  3. package/dist/agents/container-entry.d.ts.map +1 -1
  4. package/dist/agents/container-entry.js +208 -154
  5. package/dist/agents/container-entry.js.map +1 -1
  6. package/dist/agents/container-runner.d.ts.map +1 -1
  7. package/dist/agents/container-runner.js +19 -8
  8. package/dist/agents/container-runner.js.map +1 -1
  9. package/dist/agents/context-injection.d.ts +7 -0
  10. package/dist/agents/context-injection.d.ts.map +1 -0
  11. package/dist/agents/context-injection.js +27 -0
  12. package/dist/agents/context-injection.js.map +1 -0
  13. package/dist/agents/execution-engine.d.ts.map +1 -1
  14. package/dist/agents/execution-engine.js +99 -109
  15. package/dist/agents/execution-engine.js.map +1 -1
  16. package/dist/agents/model-fallback.d.ts +18 -0
  17. package/dist/agents/model-fallback.d.ts.map +1 -0
  18. package/dist/agents/model-fallback.js +40 -0
  19. package/dist/agents/model-fallback.js.map +1 -0
  20. package/dist/agents/prompt.d.ts +9 -2
  21. package/dist/agents/prompt.d.ts.map +1 -1
  22. package/dist/agents/prompt.js +21 -49
  23. package/dist/agents/prompt.js.map +1 -1
  24. package/dist/agents/runner.d.ts +2 -0
  25. package/dist/agents/runner.d.ts.map +1 -1
  26. package/dist/agents/runner.js +142 -124
  27. package/dist/agents/runner.js.map +1 -1
  28. package/dist/agents/session-factory.d.ts +13 -0
  29. package/dist/agents/session-factory.d.ts.map +1 -0
  30. package/dist/agents/session-factory.js +27 -0
  31. package/dist/agents/session-factory.js.map +1 -0
  32. package/dist/build-info.json +1 -1
  33. package/dist/cli/commands/agent.d.ts.map +1 -1
  34. package/dist/cli/commands/agent.js +43 -23
  35. package/dist/cli/commands/agent.js.map +1 -1
  36. package/dist/cli/commands/chat.d.ts.map +1 -1
  37. package/dist/cli/commands/chat.js +26 -43
  38. package/dist/cli/commands/chat.js.map +1 -1
  39. package/dist/cli/commands/claude.d.ts +4 -0
  40. package/dist/cli/commands/claude.d.ts.map +1 -0
  41. package/dist/cli/commands/claude.js +8 -0
  42. package/dist/cli/commands/claude.js.map +1 -0
  43. package/dist/cli/commands/doctor.d.ts.map +1 -1
  44. package/dist/cli/commands/doctor.js +24 -6
  45. package/dist/cli/commands/doctor.js.map +1 -1
  46. package/dist/cli/commands/mcp.d.ts +8 -0
  47. package/dist/cli/commands/mcp.d.ts.map +1 -0
  48. package/dist/cli/commands/mcp.js +31 -0
  49. package/dist/cli/commands/mcp.js.map +1 -0
  50. package/dist/cli/commands/new.d.ts.map +1 -1
  51. package/dist/cli/commands/new.js +15 -6
  52. package/dist/cli/commands/new.js.map +1 -1
  53. package/dist/cli/commands/run.js +1 -1
  54. package/dist/cli/commands/run.js.map +1 -1
  55. package/dist/cli/commands/start.js +2 -2
  56. package/dist/cli/commands/start.js.map +1 -1
  57. package/dist/cli/commands/stats.d.ts +9 -0
  58. package/dist/cli/commands/stats.d.ts.map +1 -0
  59. package/dist/cli/commands/stats.js +149 -0
  60. package/dist/cli/commands/stats.js.map +1 -0
  61. package/dist/cli/commands/status.d.ts.map +1 -1
  62. package/dist/cli/commands/status.js +3 -0
  63. package/dist/cli/commands/status.js.map +1 -1
  64. package/dist/cli/main.js +50 -3
  65. package/dist/cli/main.js.map +1 -1
  66. package/dist/gateway/index.d.ts +3 -0
  67. package/dist/gateway/index.d.ts.map +1 -1
  68. package/dist/gateway/index.js +7 -1
  69. package/dist/gateway/index.js.map +1 -1
  70. package/dist/gateway/lock-store.d.ts +10 -0
  71. package/dist/gateway/lock-store.d.ts.map +1 -1
  72. package/dist/gateway/lock-store.js +38 -0
  73. package/dist/gateway/lock-store.js.map +1 -1
  74. package/dist/gateway/routes/dashboard.d.ts +2 -1
  75. package/dist/gateway/routes/dashboard.d.ts.map +1 -1
  76. package/dist/gateway/routes/dashboard.js +26 -6
  77. package/dist/gateway/routes/dashboard.js.map +1 -1
  78. package/dist/gateway/routes/locks.d.ts.map +1 -1
  79. package/dist/gateway/routes/locks.js +39 -0
  80. package/dist/gateway/routes/locks.js.map +1 -1
  81. package/dist/gateway/routes/logs.d.ts.map +1 -1
  82. package/dist/gateway/routes/logs.js +4 -5
  83. package/dist/gateway/routes/logs.js.map +1 -1
  84. package/dist/gateway/routes/stats.d.ts +4 -0
  85. package/dist/gateway/routes/stats.d.ts.map +1 -0
  86. package/dist/gateway/routes/stats.js +25 -0
  87. package/dist/gateway/routes/stats.js.map +1 -0
  88. package/dist/gateway/views/agent-detail-page.d.ts +12 -0
  89. package/dist/gateway/views/agent-detail-page.d.ts.map +1 -0
  90. package/dist/gateway/views/agent-detail-page.js +303 -0
  91. package/dist/gateway/views/agent-detail-page.js.map +1 -0
  92. package/dist/gateway/views/dashboard-page.d.ts.map +1 -1
  93. package/dist/gateway/views/dashboard-page.js +179 -245
  94. package/dist/gateway/views/dashboard-page.js.map +1 -1
  95. package/dist/gateway/views/instance-detail-page.d.ts +24 -0
  96. package/dist/gateway/views/instance-detail-page.d.ts.map +1 -0
  97. package/dist/gateway/views/instance-detail-page.js +277 -0
  98. package/dist/gateway/views/instance-detail-page.js.map +1 -0
  99. package/dist/gateway/views/layout.d.ts +17 -0
  100. package/dist/gateway/views/layout.d.ts.map +1 -0
  101. package/dist/gateway/views/layout.js +153 -0
  102. package/dist/gateway/views/layout.js.map +1 -0
  103. package/dist/gateway/views/login-page.d.ts.map +1 -1
  104. package/dist/gateway/views/login-page.js +24 -37
  105. package/dist/gateway/views/login-page.js.map +1 -1
  106. package/dist/hooks/runner.d.ts +12 -0
  107. package/dist/hooks/runner.d.ts.map +1 -0
  108. package/dist/hooks/runner.js +32 -0
  109. package/dist/hooks/runner.js.map +1 -0
  110. package/dist/mcp/server.d.ts +5 -0
  111. package/dist/mcp/server.d.ts.map +1 -0
  112. package/dist/mcp/server.js +336 -0
  113. package/dist/mcp/server.js.map +1 -0
  114. package/dist/scheduler/call-dispatcher.d.ts +2 -2
  115. package/dist/scheduler/call-dispatcher.js +3 -3
  116. package/dist/scheduler/call-dispatcher.js.map +1 -1
  117. package/dist/scheduler/execution.d.ts +5 -2
  118. package/dist/scheduler/execution.d.ts.map +1 -1
  119. package/dist/scheduler/execution.js +75 -4
  120. package/dist/scheduler/execution.js.map +1 -1
  121. package/dist/scheduler/gateway-setup.d.ts +2 -0
  122. package/dist/scheduler/gateway-setup.d.ts.map +1 -1
  123. package/dist/scheduler/gateway-setup.js +3 -2
  124. package/dist/scheduler/gateway-setup.js.map +1 -1
  125. package/dist/scheduler/image-builder.js +3 -3
  126. package/dist/scheduler/image-builder.js.map +1 -1
  127. package/dist/scheduler/index.d.ts.map +1 -1
  128. package/dist/scheduler/index.js +16 -3
  129. package/dist/scheduler/index.js.map +1 -1
  130. package/dist/scheduler/shutdown.d.ts +2 -0
  131. package/dist/scheduler/shutdown.d.ts.map +1 -1
  132. package/dist/scheduler/shutdown.js +4 -1
  133. package/dist/scheduler/shutdown.js.map +1 -1
  134. package/dist/scheduler/validation.d.ts.map +1 -1
  135. package/dist/scheduler/validation.js +5 -3
  136. package/dist/scheduler/validation.js.map +1 -1
  137. package/dist/scheduler/watcher.d.ts +1 -1
  138. package/dist/scheduler/watcher.js +1 -1
  139. package/dist/scheduler/webhook-setup.d.ts +2 -0
  140. package/dist/scheduler/webhook-setup.d.ts.map +1 -1
  141. package/dist/scheduler/webhook-setup.js +2 -0
  142. package/dist/scheduler/webhook-setup.js.map +1 -1
  143. package/dist/setup/prompts.d.ts.map +1 -1
  144. package/dist/setup/prompts.js +35 -6
  145. package/dist/setup/prompts.js.map +1 -1
  146. package/dist/setup/scaffold.d.ts +6 -0
  147. package/dist/setup/scaffold.d.ts.map +1 -1
  148. package/dist/setup/scaffold.js +185 -7
  149. package/dist/setup/scaffold.js.map +1 -1
  150. package/dist/shared/config.d.ts +16 -5
  151. package/dist/shared/config.d.ts.map +1 -1
  152. package/dist/shared/config.js +75 -18
  153. package/dist/shared/config.js.map +1 -1
  154. package/dist/shared/credential-refs.d.ts.map +1 -1
  155. package/dist/shared/credential-refs.js +8 -0
  156. package/dist/shared/credential-refs.js.map +1 -1
  157. package/dist/shared/environment.d.ts +0 -1
  158. package/dist/shared/environment.d.ts.map +1 -1
  159. package/dist/shared/environment.js +19 -3
  160. package/dist/shared/environment.js.map +1 -1
  161. package/dist/shared/frontmatter.d.ts +11 -0
  162. package/dist/shared/frontmatter.d.ts.map +1 -0
  163. package/dist/shared/frontmatter.js +30 -0
  164. package/dist/shared/frontmatter.js.map +1 -0
  165. package/dist/shared/paths.d.ts +1 -0
  166. package/dist/shared/paths.d.ts.map +1 -1
  167. package/dist/shared/paths.js +3 -0
  168. package/dist/shared/paths.js.map +1 -1
  169. package/dist/stats/index.d.ts +3 -0
  170. package/dist/stats/index.d.ts.map +1 -0
  171. package/dist/stats/index.js +2 -0
  172. package/dist/stats/index.js.map +1 -0
  173. package/dist/stats/store.d.ts +89 -0
  174. package/dist/stats/store.d.ts.map +1 -0
  175. package/dist/stats/store.js +242 -0
  176. package/dist/stats/store.js.map +1 -0
  177. package/dist/tui/status-tracker.d.ts +6 -1
  178. package/dist/tui/status-tracker.d.ts.map +1 -1
  179. package/dist/tui/status-tracker.js +11 -1
  180. package/dist/tui/status-tracker.js.map +1 -1
  181. package/docker/bin/{al-call → al-subagent} +2 -2
  182. package/docker/bin/{al-check → al-subagent-check} +2 -2
  183. package/docker/bin/{al-wait → al-subagent-wait} +2 -2
  184. package/package.json +8 -21
  185. package/LICENSE +0 -21
  186. package/README.md +0 -192
  187. package/dist/gateway/views/logs-page.d.ts +0 -2
  188. package/dist/gateway/views/logs-page.d.ts.map +0 -1
  189. package/dist/gateway/views/logs-page.js +0 -280
  190. package/dist/gateway/views/logs-page.js.map +0 -1
  191. package/dist/preflight/interpolate.d.ts +0 -10
  192. package/dist/preflight/interpolate.d.ts.map +0 -1
  193. package/dist/preflight/interpolate.js +0 -33
  194. package/dist/preflight/interpolate.js.map +0 -1
  195. package/dist/preflight/providers/git-clone.d.ts +0 -3
  196. package/dist/preflight/providers/git-clone.d.ts.map +0 -1
  197. package/dist/preflight/providers/git-clone.js +0 -36
  198. package/dist/preflight/providers/git-clone.js.map +0 -1
  199. package/dist/preflight/providers/http.d.ts +0 -3
  200. package/dist/preflight/providers/http.d.ts.map +0 -1
  201. package/dist/preflight/providers/http.js +0 -36
  202. package/dist/preflight/providers/http.js.map +0 -1
  203. package/dist/preflight/providers/shell.d.ts +0 -3
  204. package/dist/preflight/providers/shell.d.ts.map +0 -1
  205. package/dist/preflight/providers/shell.js +0 -28
  206. package/dist/preflight/providers/shell.js.map +0 -1
  207. package/dist/preflight/registry.d.ts +0 -4
  208. package/dist/preflight/registry.d.ts.map +0 -1
  209. package/dist/preflight/registry.js +0 -20
  210. package/dist/preflight/registry.js.map +0 -1
  211. package/dist/preflight/runner.d.ts +0 -7
  212. package/dist/preflight/runner.d.ts.map +0 -1
  213. package/dist/preflight/runner.js +0 -28
  214. package/dist/preflight/runner.js.map +0 -1
  215. package/dist/preflight/schema.d.ts +0 -21
  216. package/dist/preflight/schema.d.ts.map +0 -1
  217. package/dist/preflight/schema.js +0 -9
  218. package/dist/preflight/schema.js.map +0 -1
@@ -1,36 +1,12 @@
1
- function escapeHtml(str) {
2
- return str
3
- .replace(/&/g, "&")
4
- .replace(/</g, "&lt;")
5
- .replace(/>/g, "&gt;")
6
- .replace(/"/g, "&quot;");
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 "#22c55e";
11
- case "building": return "#eab308";
12
- case "error": return "#ef4444";
13
- case "idle": return "#6b7280";
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 renderAgentRow(agent) {
42
- const color = stateColor(agent.state);
43
- const statusText = agent.statusText || agent.lastError || "\u2014";
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
- return `<tr data-agent="${escapeHtml(agent.name)}">
47
- <td><a href="/dashboard/agents/${escapeHtml(agent.name)}/logs">${escapeHtml(agent.name)}</a></td>
48
- <td><span class="state-dot" style="background:${color}"></span> ${escapeHtml(formatScale(agent))}</td>
49
- <td class="status-text">${escapeHtml(statusText)}</td>
50
- <td>${formatTime(agent.lastRunAt)}</td>
51
- <td>${agent.lastRunDuration != null ? formatDuration(agent.lastRunDuration) : "\u2014"}</td>
52
- <td>${formatTime(agent.nextRunAt)}</td>
53
- <td class="actions">
54
- <button class="btn btn-sm" onclick="triggerAgent('${escapeHtml(agent.name)}')">Run</button>
55
- <button class="btn btn-sm btn-outline" onclick="toggleAgent('${escapeHtml(agent.name)}','${toggleAction}')">${toggleLabel}</button>
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 color = stateColor(agent.state);
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
- return `<div class="agent-card">
65
- <a href="/dashboard/agents/${escapeHtml(agent.name)}/logs" class="card-link">
66
- <div class="card-header">
67
- <span class="card-name">${escapeHtml(agent.name)}</span>
68
- <span><span class="state-dot" style="background:${color}"></span>${escapeHtml(formatScale(agent))}</span>
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
- <div class="card-status">${escapeHtml(statusText)}</div>
71
- <div class="card-meta">
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="card-actions">
78
- <button class="btn btn-sm" onclick="triggerAgent('${escapeHtml(agent.name)}')">Run</button>
79
- <button class="btn btn-sm btn-outline" onclick="toggleAgent('${escapeHtml(agent.name)}','${toggleAction}')">${toggleLabel}</button>
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 mode = schedulerInfo?.mode || "host";
85
- const runtime = schedulerInfo?.runtime || "\u2014";
86
- const uptime = schedulerInfo ? formatDuration(Date.now() - schedulerInfo.startedAt.getTime()) : "\u2014";
87
- const cronCount = schedulerInfo?.cronJobCount || 0;
88
- const webhooks = schedulerInfo?.webhooksActive ? "active" : "inactive";
89
- return `<!DOCTYPE html>
90
- <html lang="en">
91
- <head>
92
- <meta charset="utf-8">
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
- <table class="agent-table">
177
- <thead>
178
- <tr>
179
- <th>Agent</th>
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
- <div class="agent-cards" id="agent-cards">
194
- ${agents.length > 0 ? agents.map(renderAgentCard).join("\n ") : '<div class="empty">No agents registered</div>'}
195
- </div>
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
- <h2>Recent Activity</h2>
198
- <div class="logs" id="recent-logs">
199
- ${recentLogs.length > 0 ? recentLogs.map((l) => `<div class="log-line">${formatLogLine(l)}</div>`).join("\n ") : '<div class="empty">No recent activity</div>'}
200
- </div>
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
- <script>
203
- const stateColors = { running: "#22c55e", building: "#eab308", error: "#ef4444", idle: "#6b7280" };
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 esc(s) { const d = document.createElement("div"); d.textContent = s; return d.innerHTML; }
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 fmtDur(ms) {
208
- if (ms < 1000) return ms + "ms";
209
- const s = Math.floor(ms / 1000);
210
- if (s < 60) return s + "s";
211
- return Math.floor(s / 60) + "m " + (s % 60) + "s";
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 fmtTime(iso) {
215
- if (!iso) return "\\u2014";
216
- return new Date(iso).toLocaleTimeString();
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 fmtScale(a) {
220
- if (a.state === "running" && a.scale > 1) return "running " + a.runningCount + "/" + a.scale;
221
- if (a.scale > 1) return a.state + " (\\u00d7" + a.scale + ")";
222
- return a.state;
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
- const color = stateColors[a.state] || "#6b7280";
227
- const status = a.statusText || a.lastError || "\\u2014";
228
- const toggleLabel = a.enabled ? "Disable" : "Enable";
229
- const toggleAction = a.enabled ? "disable" : "enable";
230
- return '<tr data-agent="' + esc(a.name) + '">' +
231
- '<td><a href="/dashboard/agents/' + esc(a.name) + '/logs">' + esc(a.name) + '</a></td>' +
232
- '<td><span class="state-dot" style="background:' + color + '"></span> ' + esc(fmtScale(a)) + '</td>' +
233
- '<td class="status-text">' + esc(status) + '</td>' +
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="actions"><button class="btn btn-sm" onclick="triggerAgent(\\'' + esc(a.name) + '\\')">Run</button>' +
238
- '<button class="btn btn-sm btn-outline" onclick="toggleAgent(\\'' + esc(a.name) + '\\',\\'' + toggleAction + '\\')">' + toggleLabel + '</button></td>' +
239
- '</tr>';
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
- const color = stateColors[a.state] || "#6b7280";
244
- const status = a.statusText || a.lastError || "\\u2014";
245
- const toggleLabel = a.enabled ? "Disable" : "Enable";
246
- const toggleAction = a.enabled ? "disable" : "enable";
247
- return '<div class="agent-card"><a href="/dashboard/agents/' + esc(a.name) + '/logs" class="card-link">' +
248
- '<div class="card-header"><span class="card-name">' + esc(a.name) + '</span>' +
249
- '<span><span class="state-dot" style="background:' + color + '"></span>' + esc(fmtScale(a)) + '</span></div>' +
250
- '<div class="card-status">' + esc(status) + '</div>' +
251
- '<div class="card-meta"><span>Last: ' + fmtTime(a.lastRunAt) + '</span>' +
252
- '<span>' + (a.lastRunDuration != null ? fmtDur(a.lastRunDuration) : "") + '</span>' +
253
- '<span>Next: ' + fmtTime(a.nextRunAt) + '</span></div></a>' +
254
- '<div class="card-actions"><button class="btn btn-sm" onclick="triggerAgent(\\'' + esc(a.name) + '\\')">Run</button>' +
255
- '<button class="btn btn-sm btn-outline" onclick="toggleAgent(\\'' + esc(a.name) + '\\',\\'' + toggleAction + '\\')">' + toggleLabel + '</button></div></div>';
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
- const t = new Date(l.timestamp).toLocaleTimeString();
260
- return '<div class="log-line"><span class="log-time">' + esc(t) + '</span> <span class="log-agent">[' + esc(l.agent) + ']</span> ' + esc(l.message) + '</div>';
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
- const es = new EventSource("/dashboard/api/status-stream");
211
+ var es = new EventSource("/dashboard/api/status-stream");
264
212
  es.onmessage = function(e) {
265
- const data = JSON.parse(e.data);
266
-
213
+ var data = JSON.parse(e.data);
267
214
  if (data.agents) {
268
- // Update desktop table
269
- const tbody = document.getElementById("agent-table-body");
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="empty">No agents registered</td></tr>';
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="empty">No agents registered</div>';
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
- function doLogout() {
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":"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"}
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"}