@agenticmail/enterprise 0.5.213 → 0.5.214
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-heartbeat-3UMSZXRT.js +510 -0
- package/dist/chunk-3OWONOAJ.js +455 -0
- package/dist/chunk-IP5HZWZM.js +3685 -0
- package/dist/chunk-NJRHVKVY.js +4457 -0
- package/dist/chunk-QRRW3LES.js +1224 -0
- package/dist/cli-agent-L3ESGKPF.js +1719 -0
- package/dist/cli-serve-JH3BKW6F.js +114 -0
- package/dist/cli.js +3 -3
- package/dist/dashboard/pages/task-pipeline.js +54 -46
- package/dist/index.js +3 -3
- package/dist/routes-W7M2THQV.js +13050 -0
- package/dist/runtime-MNKA2HG6.js +45 -0
- package/dist/server-ZDEYMGB5.js +15 -0
- package/dist/setup-RWUGYHIU.js +20 -0
- package/package.json +1 -1
- package/src/dashboard/pages/task-pipeline.js +54 -46
- package/src/engine/task-queue-routes.ts +2 -2
- package/src/engine/task-queue.ts +30 -2
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentRuntime,
|
|
3
|
+
EmailChannel,
|
|
4
|
+
FollowUpScheduler,
|
|
5
|
+
SessionManager,
|
|
6
|
+
SubAgentManager,
|
|
7
|
+
ToolRegistry,
|
|
8
|
+
callLLM,
|
|
9
|
+
createAgentRuntime,
|
|
10
|
+
createNoopHooks,
|
|
11
|
+
createRuntimeHooks,
|
|
12
|
+
estimateMessageTokens,
|
|
13
|
+
estimateTokens,
|
|
14
|
+
executeTool,
|
|
15
|
+
runAgentLoop,
|
|
16
|
+
toolsToDefinitions
|
|
17
|
+
} from "./chunk-NJRHVKVY.js";
|
|
18
|
+
import {
|
|
19
|
+
PROVIDER_REGISTRY,
|
|
20
|
+
listAllProviders,
|
|
21
|
+
resolveApiKeyForProvider,
|
|
22
|
+
resolveProvider
|
|
23
|
+
} from "./chunk-UF3ZJMJO.js";
|
|
24
|
+
import "./chunk-KFQGP6VL.js";
|
|
25
|
+
export {
|
|
26
|
+
AgentRuntime,
|
|
27
|
+
EmailChannel,
|
|
28
|
+
FollowUpScheduler,
|
|
29
|
+
PROVIDER_REGISTRY,
|
|
30
|
+
SessionManager,
|
|
31
|
+
SubAgentManager,
|
|
32
|
+
ToolRegistry,
|
|
33
|
+
callLLM,
|
|
34
|
+
createAgentRuntime,
|
|
35
|
+
createNoopHooks,
|
|
36
|
+
createRuntimeHooks,
|
|
37
|
+
estimateMessageTokens,
|
|
38
|
+
estimateTokens,
|
|
39
|
+
executeTool,
|
|
40
|
+
listAllProviders,
|
|
41
|
+
resolveApiKeyForProvider,
|
|
42
|
+
resolveProvider,
|
|
43
|
+
runAgentLoop,
|
|
44
|
+
toolsToDefinitions
|
|
45
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createServer
|
|
3
|
+
} from "./chunk-IP5HZWZM.js";
|
|
4
|
+
import "./chunk-OF4MUWWS.js";
|
|
5
|
+
import "./chunk-UF3ZJMJO.js";
|
|
6
|
+
import "./chunk-3OC6RH7W.js";
|
|
7
|
+
import "./chunk-2DDKGTD6.js";
|
|
8
|
+
import "./chunk-YVK6F5OD.js";
|
|
9
|
+
import "./chunk-MKRNEM5A.js";
|
|
10
|
+
import "./chunk-DRXMYYKN.js";
|
|
11
|
+
import "./chunk-6WSX7QXF.js";
|
|
12
|
+
import "./chunk-KFQGP6VL.js";
|
|
13
|
+
export {
|
|
14
|
+
createServer
|
|
15
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
promptCompanyInfo,
|
|
3
|
+
promptDatabase,
|
|
4
|
+
promptDeployment,
|
|
5
|
+
promptDomain,
|
|
6
|
+
promptRegistration,
|
|
7
|
+
provision,
|
|
8
|
+
runSetupWizard
|
|
9
|
+
} from "./chunk-QRRW3LES.js";
|
|
10
|
+
import "./chunk-VQQ4SYYQ.js";
|
|
11
|
+
import "./chunk-KFQGP6VL.js";
|
|
12
|
+
export {
|
|
13
|
+
promptCompanyInfo,
|
|
14
|
+
promptDatabase,
|
|
15
|
+
promptDeployment,
|
|
16
|
+
promptDomain,
|
|
17
|
+
promptRegistration,
|
|
18
|
+
provision,
|
|
19
|
+
runSetupWizard
|
|
20
|
+
};
|
package/package.json
CHANGED
|
@@ -14,8 +14,10 @@ var PAD = 40;
|
|
|
14
14
|
var STATUS_COLORS = { created: '#6366f1', assigned: '#f59e0b', in_progress: '#06b6d4', completed: '#22c55e', failed: '#ef4444', cancelled: '#6b7394' };
|
|
15
15
|
var PRIORITY_COLORS = { urgent: '#ef4444', high: '#f59e0b', normal: '#6366f1', low: '#6b7394' };
|
|
16
16
|
var DELEGATION_COLORS = { delegation: '#6366f1', review: '#f59e0b', revision: '#f97316', escalation: '#ef4444', return: '#22c55e' };
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
// Theme-aware: use CSS variables where possible, detect dark/light
|
|
18
|
+
function isDark() { try { return window.matchMedia('(prefers-color-scheme: dark)').matches || document.documentElement.classList.contains('dark') || document.body.getAttribute('data-theme') === 'dark'; } catch(e) { return true; } }
|
|
19
|
+
var BG = 'var(--bg-canvas, var(--bg-primary, #0a0c14))';
|
|
20
|
+
var EDGE_COLOR = 'var(--tp-edge, rgba(128,128,128,0.25))';
|
|
19
21
|
var EDGE_HL = 'rgba(99,102,241,0.7)';
|
|
20
22
|
|
|
21
23
|
// ─── CSS Keyframes (injected once) ──────────────────────
|
|
@@ -24,13 +26,15 @@ function injectCSS() {
|
|
|
24
26
|
if (_injected) return; _injected = true;
|
|
25
27
|
var style = document.createElement('style');
|
|
26
28
|
style.textContent = `
|
|
29
|
+
:root { --tp-bg: #0a0c14; --tp-text: #fff; --tp-text-dim: rgba(255,255,255,0.4); --tp-text-faint: rgba(255,255,255,0.15); --tp-border: rgba(255,255,255,0.08); --tp-card: rgba(255,255,255,0.02); --tp-card-hover: rgba(255,255,255,0.06); --tp-edge: rgba(255,255,255,0.18); --tp-toolbar: rgba(0,0,0,0.3); --tp-metrics: rgba(0,0,0,0.12); }
|
|
30
|
+
[data-theme="light"], .light, :root:not(.dark) { --tp-bg: var(--bg-primary, #f8fafc); --tp-text: var(--text-primary, #1e293b); --tp-text-dim: var(--text-muted, #64748b); --tp-text-faint: rgba(0,0,0,0.06); --tp-border: var(--border, rgba(0,0,0,0.08)); --tp-card: rgba(0,0,0,0.02); --tp-card-hover: rgba(0,0,0,0.05); --tp-edge: rgba(0,0,0,0.2); --tp-toolbar: rgba(0,0,0,0.03); --tp-metrics: rgba(0,0,0,0.02); }
|
|
31
|
+
@media (prefers-color-scheme: light) { :root:not(.dark) { --tp-bg: var(--bg-primary, #f8fafc); --tp-text: var(--text-primary, #1e293b); --tp-text-dim: var(--text-muted, #64748b); --tp-text-faint: rgba(0,0,0,0.06); --tp-border: var(--border, rgba(0,0,0,0.08)); --tp-card: rgba(0,0,0,0.02); --tp-card-hover: rgba(0,0,0,0.05); --tp-edge: rgba(0,0,0,0.2); --tp-toolbar: rgba(0,0,0,0.03); --tp-metrics: rgba(0,0,0,0.02); } }
|
|
27
32
|
@keyframes flowDash { to { stroke-dashoffset: -24; } }
|
|
28
33
|
@keyframes flowPulse { 0%,100% { opacity: 0.4; } 50% { opacity: 1; } }
|
|
29
34
|
@keyframes taskPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(6,182,212,0.3); } 50% { box-shadow: 0 0 8px 2px rgba(6,182,212,0.2); } }
|
|
30
35
|
.tp-flow-active { animation: flowDash 1.2s linear infinite; }
|
|
31
36
|
.tp-node-active { animation: taskPulse 2s ease-in-out infinite; }
|
|
32
37
|
.tp-node:hover { transform: scale(1.03); z-index: 10; }
|
|
33
|
-
.tp-customer-badge { background: linear-gradient(135deg, #6366f1, #a855f7); color: #fff; font-size: 9px; padding: 1px 6px; border-radius: 8px; font-weight: 600; }
|
|
34
38
|
.tp-chain-tag { font-size: 9px; padding: 1px 5px; border-radius: 4px; font-weight: 600; letter-spacing: 0.02em; }
|
|
35
39
|
`;
|
|
36
40
|
document.head.appendChild(style);
|
|
@@ -173,13 +177,13 @@ function formatDuration(ms) {
|
|
|
173
177
|
function tag(color, text) { return h('span', { className: 'tp-chain-tag', style: { background: color + '22', color: color } }, text); }
|
|
174
178
|
|
|
175
179
|
var toolbarBtnStyle = {
|
|
176
|
-
background: '
|
|
177
|
-
borderRadius: 6, color: '
|
|
180
|
+
background: 'var(--tp-border)', border: '1px solid rgba(255,255,255,0.12)',
|
|
181
|
+
borderRadius: 6, color: 'var(--tp-text)', fontSize: 12, fontWeight: 600, padding: '4px 10px', cursor: 'pointer',
|
|
178
182
|
};
|
|
179
183
|
function legendDot(color, label) {
|
|
180
184
|
return h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
|
|
181
185
|
h('div', { style: { width: 8, height: 8, borderRadius: '50%', background: color } }),
|
|
182
|
-
h('span', { style: { color: '
|
|
186
|
+
h('span', { style: { color: 'var(--tp-text-dim)', fontSize: 11 } }, label)
|
|
183
187
|
);
|
|
184
188
|
}
|
|
185
189
|
var _h4 = { marginTop: 16, marginBottom: 8, fontSize: 14 };
|
|
@@ -191,10 +195,10 @@ function CustomerBadge(props) {
|
|
|
191
195
|
var c = props.customer;
|
|
192
196
|
if (!c) return null;
|
|
193
197
|
return h('div', { style: { display: 'flex', alignItems: 'center', gap: 6, padding: '4px 8px', background: 'rgba(99,102,241,0.08)', border: '1px solid rgba(99,102,241,0.2)', borderRadius: 8, fontSize: 11, marginBottom: 4 } },
|
|
194
|
-
h('div', { style: { width: 20, height: 20, borderRadius: '50%', background: 'linear-gradient(135deg, #6366f1, #a855f7)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '
|
|
198
|
+
h('div', { style: { width: 20, height: 20, borderRadius: '50%', background: 'linear-gradient(135deg, #6366f1, #a855f7)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--tp-text)', fontSize: 9, fontWeight: 700, flexShrink: 0 } }, (c.name || '?').charAt(0).toUpperCase()),
|
|
195
199
|
h('div', { style: { overflow: 'hidden' } },
|
|
196
|
-
h('div', { style: { fontWeight: 600, color: '
|
|
197
|
-
h('div', { style: { color: '
|
|
200
|
+
h('div', { style: { fontWeight: 600, color: 'var(--tp-text)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } }, c.name || 'Unknown'),
|
|
201
|
+
h('div', { style: { color: 'var(--tp-text-dim)', fontSize: 9 } },
|
|
198
202
|
c.isNew ? 'New customer' : (c.company || c.email || c.channel || '')
|
|
199
203
|
)
|
|
200
204
|
)
|
|
@@ -227,7 +231,7 @@ function TaskDetail(props) {
|
|
|
227
231
|
|
|
228
232
|
// Customer context
|
|
229
233
|
task.customerContext && h('div', { style: { padding: 12, background: 'rgba(99,102,241,0.06)', border: '1px solid rgba(99,102,241,0.15)', borderRadius: 'var(--radius)', marginBottom: 16 } },
|
|
230
|
-
h('div', { style: { fontSize: 11, fontWeight: 600, color: '
|
|
234
|
+
h('div', { style: { fontSize: 11, fontWeight: 600, color: 'var(--tp-text-dim)', marginBottom: 8 } }, 'CUSTOMER'),
|
|
231
235
|
h('div', { style: { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '6px 16px', fontSize: 13 } },
|
|
232
236
|
task.customerContext.name && h(Fragment, null, h('div', { style: { color: 'var(--text-muted)', fontSize: 11 } }, 'Name'), h('div', null, task.customerContext.name)),
|
|
233
237
|
task.customerContext.email && h(Fragment, null, h('div', { style: { color: 'var(--text-muted)', fontSize: 11 } }, 'Email'), h('div', null, task.customerContext.email)),
|
|
@@ -267,7 +271,7 @@ function TaskDetail(props) {
|
|
|
267
271
|
return h(Fragment, { key: ct.id },
|
|
268
272
|
i > 0 && h('div', { style: { display: 'flex', alignItems: 'center', flexShrink: 0 } },
|
|
269
273
|
h('div', { style: { width: 32, height: 2, background: (DELEGATION_COLORS[ct.delegationType] || '#6366f1') + '66' } }),
|
|
270
|
-
h('div', { style: { fontSize: 8, color: '
|
|
274
|
+
h('div', { style: { fontSize: 8, color: 'var(--tp-text-dim)', position: 'relative', top: -8 } }, ct.delegationType || '')
|
|
271
275
|
),
|
|
272
276
|
h('div', { style: {
|
|
273
277
|
padding: '6px 10px', borderRadius: 8, fontSize: 11, flexShrink: 0,
|
|
@@ -312,32 +316,32 @@ function TaskDetail(props) {
|
|
|
312
316
|
function MetricsBar(props) {
|
|
313
317
|
var s = props.stats;
|
|
314
318
|
function chip(label, value, color) {
|
|
315
|
-
return h('div', { style: { display: 'flex', alignItems: 'center', gap: 4, padding: '3px 8px', background: '
|
|
316
|
-
h('span', { style: { fontSize: 10, color: '
|
|
319
|
+
return h('div', { style: { display: 'flex', alignItems: 'center', gap: 4, padding: '3px 8px', background: 'var(--tp-card)', borderRadius: 6 } },
|
|
320
|
+
h('span', { style: { fontSize: 10, color: 'var(--tp-text-dim)' } }, label),
|
|
317
321
|
h('span', { style: { fontSize: 11, fontWeight: 700, color: color } }, value)
|
|
318
322
|
);
|
|
319
323
|
}
|
|
320
324
|
var hasActivity = s.total > 0;
|
|
321
325
|
|
|
322
|
-
return h('div', { style: { display: 'flex', alignItems: 'center', gap: 6, padding: '6px 16px', borderBottom: '1px solid
|
|
323
|
-
h('span', { style: { fontSize: 9, color: '
|
|
326
|
+
return h('div', { style: { display: 'flex', alignItems: 'center', gap: 6, padding: '6px 16px', borderBottom: '1px solid var(--tp-border)', background: 'var(--tp-metrics)', flexShrink: 0, overflowX: 'auto', fontSize: 11 } },
|
|
327
|
+
h('span', { style: { fontSize: 9, color: 'var(--tp-text-faint)', fontWeight: 600, letterSpacing: '0.06em', marginRight: 2 } }, 'TODAY'),
|
|
324
328
|
chip('Done', s.todayCompleted || 0, '#22c55e'),
|
|
325
329
|
chip('Active', s.inProgress || 0, '#06b6d4'),
|
|
326
330
|
chip('New', s.todayCreated || 0, '#f59e0b'),
|
|
327
331
|
s.todayFailed > 0 && chip('Failed', s.todayFailed, '#ef4444'),
|
|
328
|
-
hasActivity && h('div', { style: { width: 1, height: 14, background: '
|
|
329
|
-
hasActivity && h('span', { style: { fontSize: 9, color: '
|
|
332
|
+
hasActivity && h('div', { style: { width: 1, height: 14, background: 'var(--tp-border)' } }),
|
|
333
|
+
hasActivity && h('span', { style: { fontSize: 9, color: 'var(--tp-text-faint)', fontWeight: 600, letterSpacing: '0.06em' } }, 'ALL'),
|
|
330
334
|
hasActivity && chip('Total', s.total, 'rgba(255,255,255,0.6)'),
|
|
331
335
|
s.avgDurationMs > 0 && chip('Avg', formatDuration(s.avgDurationMs), '#fff'),
|
|
332
336
|
s.totalTokens > 0 && chip('Tokens', s.totalTokens > 999999 ? (s.totalTokens / 1000000).toFixed(1) + 'M' : s.totalTokens > 999 ? (s.totalTokens / 1000).toFixed(1) + 'K' : s.totalTokens, '#a855f7'),
|
|
333
337
|
s.totalCost > 0 && chip('Cost', '$' + s.totalCost.toFixed(2), '#22c55e'),
|
|
334
338
|
s.topAgents && s.topAgents.length > 0 && h(Fragment, null,
|
|
335
|
-
h('div', { style: { width: 1, height: 14, background: '
|
|
339
|
+
h('div', { style: { width: 1, height: 14, background: 'var(--tp-border)' } }),
|
|
336
340
|
s.topAgents.slice(0, 3).map(function(a) {
|
|
337
|
-
return h('div', { key: a.agent, style: { display: 'flex', alignItems: 'center', gap: 3, padding: '2px 6px', background: '
|
|
341
|
+
return h('div', { key: a.agent, style: { display: 'flex', alignItems: 'center', gap: 3, padding: '2px 6px', background: 'var(--tp-card)', borderRadius: 6 } },
|
|
338
342
|
h('div', { style: { width: 12, height: 12, borderRadius: '50%', background: '#6366f133', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 7, fontWeight: 700, color: '#6366f1' } }, (a.name || '?').charAt(0).toUpperCase()),
|
|
339
|
-
h('span', { style: { fontSize: 10, color: '
|
|
340
|
-
h('span', { style: { fontSize: 9, color: '
|
|
343
|
+
h('span', { style: { fontSize: 10, color: 'var(--tp-text)', fontWeight: 600 } }, a.name),
|
|
344
|
+
h('span', { style: { fontSize: 9, color: 'var(--tp-text-dim)' } }, a.completed + '/' + a.active)
|
|
341
345
|
);
|
|
342
346
|
})
|
|
343
347
|
)
|
|
@@ -528,8 +532,8 @@ export function TaskPipelinePage() {
|
|
|
528
532
|
var hoveredNode = hoveredId ? nodes.find(function(n) { return n.id === hoveredId; }) : null;
|
|
529
533
|
|
|
530
534
|
// ─── Toolbar ─────────────────────────────────────────
|
|
531
|
-
var toolbar = h('div', { style: { display: 'flex', alignItems: 'center', gap: 10, padding: '10px 16px', borderBottom: '1px solid
|
|
532
|
-
h('div', { style: { fontWeight: 700, fontSize: 14, color: '
|
|
535
|
+
var toolbar = h('div', { style: { display: 'flex', alignItems: 'center', gap: 10, padding: '10px 16px', borderBottom: '1px solid var(--tp-border)', background: 'var(--tp-toolbar)', flexShrink: 0, flexWrap: 'wrap' } },
|
|
536
|
+
h('div', { style: { fontWeight: 700, fontSize: 14, color: 'var(--tp-text)', display: 'flex', alignItems: 'center', gap: 6 } },
|
|
533
537
|
I.workflow(), 'Task Pipeline',
|
|
534
538
|
h(HelpButton, { label: 'Task Pipeline' },
|
|
535
539
|
h('p', null, 'Visual flow of all agent tasks. Tasks flow left-to-right showing delegation chains, multi-agent handoffs, and circular review loops.'),
|
|
@@ -554,9 +558,9 @@ export function TaskPipelinePage() {
|
|
|
554
558
|
),
|
|
555
559
|
h('div', { style: { display: 'flex', alignItems: 'center', gap: 4 } },
|
|
556
560
|
h('div', { style: { width: 8, height: 8, borderRadius: '50%', background: '#22c55e', animation: 'flowPulse 2s infinite' } }),
|
|
557
|
-
h('span', { style: { color: '
|
|
561
|
+
h('span', { style: { color: 'var(--tp-text-dim)', fontSize: 11 } }, 'Live')
|
|
558
562
|
),
|
|
559
|
-
h('div', { style: { color: '
|
|
563
|
+
h('div', { style: { color: 'var(--tp-text-dim)', fontSize: 11 } },
|
|
560
564
|
(stats.inProgress || 0) + ' active \u00B7 ' + (stats.completed || 0) + ' done \u00B7 ' + (stats.total || 0) + ' total'
|
|
561
565
|
),
|
|
562
566
|
h('div', { style: { flex: 1 } }),
|
|
@@ -570,7 +574,7 @@ export function TaskPipelinePage() {
|
|
|
570
574
|
legendDot(STATUS_COLORS.failed, 'Failed'),
|
|
571
575
|
h('div', { style: { width: 1, height: 14, background: 'rgba(255,255,255,0.12)' } }),
|
|
572
576
|
h('button', { onClick: function() { setZoom(function(z) { return Math.min(3, z + 0.2); }); }, style: toolbarBtnStyle }, '+'),
|
|
573
|
-
h('div', { style: { color: '
|
|
577
|
+
h('div', { style: { color: 'var(--tp-text-dim)', fontSize: 11, minWidth: 36, textAlign: 'center' } }, Math.round(zoom * 100) + '%'),
|
|
574
578
|
h('button', { onClick: function() { setZoom(function(z) { return Math.max(0.15, z - 0.2); }); }, style: toolbarBtnStyle }, '\u2212'),
|
|
575
579
|
h('button', { onClick: fitToView, style: toolbarBtnStyle }, 'Fit'),
|
|
576
580
|
h('button', { onClick: loadData, style: toolbarBtnStyle }, 'Refresh'),
|
|
@@ -578,13 +582,13 @@ export function TaskPipelinePage() {
|
|
|
578
582
|
|
|
579
583
|
if (loading) return h('div', { style: { padding: 40, textAlign: 'center', color: 'var(--text-muted)' } }, 'Loading task pipeline...');
|
|
580
584
|
|
|
581
|
-
if (nodes.length === 0) return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background:
|
|
585
|
+
if (nodes.length === 0) return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--tp-bg)', borderRadius: 'var(--radius-lg)', overflow: 'hidden' } },
|
|
582
586
|
toolbar,
|
|
583
587
|
h(MetricsBar, { stats: stats }),
|
|
584
588
|
h('div', { style: { flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column' } },
|
|
585
589
|
h('div', { style: { width: 48, height: 48, borderRadius: 12, background: 'rgba(99,102,241,0.1)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 16, color: '#6366f1' } }, I.workflow()),
|
|
586
|
-
h('div', { style: { fontSize: 16, fontWeight: 600, marginBottom: 6, color: '
|
|
587
|
-
h('div', { style: { color: '
|
|
590
|
+
h('div', { style: { fontSize: 16, fontWeight: 600, marginBottom: 6, color: 'var(--tp-text)' } }, 'No Tasks in Pipeline'),
|
|
591
|
+
h('div', { style: { color: 'var(--tp-text-dim)', fontSize: 13 } }, 'Tasks will appear here as agents are assigned work.')
|
|
588
592
|
)
|
|
589
593
|
);
|
|
590
594
|
|
|
@@ -600,7 +604,7 @@ export function TaskPipelinePage() {
|
|
|
600
604
|
}
|
|
601
605
|
}
|
|
602
606
|
|
|
603
|
-
return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background:
|
|
607
|
+
return h('div', { style: { height: '100%', display: 'flex', flexDirection: 'column', background: 'var(--tp-bg)', borderRadius: 'var(--radius-lg)', overflow: 'hidden' } },
|
|
604
608
|
toolbar,
|
|
605
609
|
// Metrics bar
|
|
606
610
|
h(MetricsBar, { stats: stats }),
|
|
@@ -615,7 +619,7 @@ export function TaskPipelinePage() {
|
|
|
615
619
|
|
|
616
620
|
// Chain labels (left side)
|
|
617
621
|
chainInfos.map(function(ci, i) {
|
|
618
|
-
return h('div', { key: ci.chainId, style: { position: 'absolute', left: 4, top: ci.y - 2, fontSize: 9, color: '
|
|
622
|
+
return h('div', { key: ci.chainId, style: { position: 'absolute', left: 4, top: ci.y - 2, fontSize: 9, color: 'var(--tp-text-faint)', fontFamily: 'var(--font-mono)', letterSpacing: '0.04em', maxWidth: PAD - 8, overflow: 'hidden' } },
|
|
619
623
|
ci.customer && h(CustomerBadge, { customer: ci.customer })
|
|
620
624
|
);
|
|
621
625
|
}),
|
|
@@ -704,17 +708,17 @@ export function TaskPipelinePage() {
|
|
|
704
708
|
h('div', { style: { width: 18, height: 18, borderRadius: '50%', background: sc + '33', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 8, fontWeight: 700, color: sc, flexShrink: 0, border: '1px solid ' + sc + '44' } },
|
|
705
709
|
(t.assignedToName || t.assignedTo || '?').charAt(0).toUpperCase()
|
|
706
710
|
),
|
|
707
|
-
h('span', { style: { fontSize: 11, fontWeight: 600, color: '
|
|
711
|
+
h('span', { style: { fontSize: 11, fontWeight: 600, color: 'var(--tp-text)', flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' } }, t.title)
|
|
708
712
|
),
|
|
709
713
|
// Status + agent name + time
|
|
710
714
|
h('div', { style: { display: 'flex', alignItems: 'center', gap: 4, flexWrap: 'wrap' } },
|
|
711
715
|
tag(sc, t.status.replace('_', ' ')),
|
|
712
|
-
h('span', { style: { fontSize: 9, color: '
|
|
716
|
+
h('span', { style: { fontSize: 9, color: 'var(--tp-text-dim)' } }, t.assignedToName || t.assignedTo),
|
|
713
717
|
t.delegationType && tag(DELEGATION_COLORS[t.delegationType] || '#6b7394', t.delegationType),
|
|
714
|
-
h('span', { style: { fontSize: 9, color: '
|
|
718
|
+
h('span', { style: { fontSize: 9, color: 'var(--tp-text-dim)', marginLeft: 'auto' } }, timeAgo(t.createdAt))
|
|
715
719
|
),
|
|
716
720
|
// Progress bar
|
|
717
|
-
isActive && t.progress > 0 && h('div', { style: { height: 2, background: '
|
|
721
|
+
isActive && t.progress > 0 && h('div', { style: { height: 2, background: 'var(--tp-border)', borderRadius: 1, overflow: 'hidden', marginTop: 1 } },
|
|
718
722
|
h('div', { style: { height: '100%', width: t.progress + '%', background: sc, borderRadius: 1, transition: 'width 0.3s' } })
|
|
719
723
|
)
|
|
720
724
|
);
|
|
@@ -751,15 +755,19 @@ export function TaskPipelinePage() {
|
|
|
751
755
|
|
|
752
756
|
var totalW = steps.length * STEP_W + (steps.length - 1) * STEP_GAP;
|
|
753
757
|
|
|
754
|
-
|
|
758
|
+
var maxFlowW = Math.max(totalW + 40, 400);
|
|
759
|
+
var containerW = (containerRef.current ? containerRef.current.getBoundingClientRect().width / zoom : 800) - flowX;
|
|
760
|
+
if (maxFlowW > containerW) maxFlowW = Math.max(containerW, 320);
|
|
761
|
+
|
|
762
|
+
return h('div', { style: { position: 'absolute', left: flowX, top: flowY, pointerEvents: 'auto', maxWidth: maxFlowW, zIndex: 20 } },
|
|
755
763
|
// Background card
|
|
756
|
-
h('div', { style: { background: 'rgba(10,12,20,0.
|
|
764
|
+
h('div', { style: { background: 'var(--bg-primary, rgba(10,12,20,0.95))', border: '1px solid rgba(99,102,241,0.2)', borderRadius: 12, padding: '14px 16px 12px', backdropFilter: 'blur(8px)', overflowX: 'auto', overflowY: 'hidden' } },
|
|
757
765
|
// Header
|
|
758
766
|
h('div', { style: { display: 'flex', alignItems: 'center', gap: 8, marginBottom: 12 } },
|
|
759
|
-
h('span', { style: { fontSize: 10, fontWeight: 600, color: '
|
|
767
|
+
h('span', { style: { fontSize: 10, fontWeight: 600, color: 'var(--tp-text-dim)', letterSpacing: '0.06em' } }, 'TASK FLOW'),
|
|
760
768
|
expandedChain[0].chainId && h('span', { style: { fontSize: 9, color: 'rgba(255,255,255,0.2)', fontFamily: 'var(--font-mono)' } }, '#' + expandedChain[0].chainId.slice(0, 8)),
|
|
761
769
|
h('div', { style: { flex: 1 } }),
|
|
762
|
-
h('button', { className: 'tp-node', onClick: function() { setExpandedTaskId(null); }, style: { background: 'none', border: 'none', color: '
|
|
770
|
+
h('button', { className: 'tp-node', onClick: function() { setExpandedTaskId(null); }, style: { background: 'none', border: 'none', color: 'var(--tp-text-dim)', cursor: 'pointer', fontSize: 14, padding: '0 2px' } }, '\u00D7')
|
|
763
771
|
),
|
|
764
772
|
// Flow
|
|
765
773
|
h('div', { style: { position: 'relative', height: STEP_H + 8, minWidth: totalW } },
|
|
@@ -823,7 +831,7 @@ export function TaskPipelinePage() {
|
|
|
823
831
|
// Info
|
|
824
832
|
h('div', { style: { overflow: 'hidden', flex: 1, minWidth: 0 } },
|
|
825
833
|
h('div', { style: { fontSize: 11, fontWeight: 600, color: isTerminal ? sc : '#fff', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } }, step.label),
|
|
826
|
-
!isTerminal && h('div', { style: { fontSize: 9, color: '
|
|
834
|
+
!isTerminal && h('div', { style: { fontSize: 9, color: 'var(--tp-text-dim)', marginTop: 1 } },
|
|
827
835
|
step.type === 'person' || step.isHuman ? 'Human' : step.type === 'system' ? 'System' : 'Agent',
|
|
828
836
|
step.duration ? ' \u00B7 ' + formatDuration(step.duration) : '',
|
|
829
837
|
step.status === 'in_progress' && step.progress > 0 ? ' \u00B7 ' + step.progress + '%' : ''
|
|
@@ -846,13 +854,13 @@ export function TaskPipelinePage() {
|
|
|
846
854
|
padding: '10px 14px', pointerEvents: 'none', zIndex: 1000, minWidth: 180, maxWidth: 280,
|
|
847
855
|
}},
|
|
848
856
|
hoveredNode.task.customerContext && h(CustomerBadge, { customer: hoveredNode.task.customerContext }),
|
|
849
|
-
h('div', { style: { fontSize: 12, fontWeight: 600, color: '
|
|
857
|
+
h('div', { style: { fontSize: 12, fontWeight: 600, color: 'var(--tp-text)', marginBottom: 6 } }, hoveredNode.task.title),
|
|
850
858
|
h('div', { style: { display: 'flex', flexDirection: 'column', gap: 3, fontSize: 11 } },
|
|
851
|
-
h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: '
|
|
852
|
-
h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: '
|
|
853
|
-
hoveredNode.task.chainId && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: '
|
|
854
|
-
hoveredNode.task.delegationType && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: '
|
|
855
|
-
hoveredNode.task.progress > 0 && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: '
|
|
859
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Agent'), h('span', { style: { fontWeight: 600 } }, hoveredNode.task.assignedToName || '-')),
|
|
860
|
+
h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Status'), h('span', { style: { color: STATUS_COLORS[hoveredNode.task.status] } }, hoveredNode.task.status.replace('_', ' '))),
|
|
861
|
+
hoveredNode.task.chainId && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Chain Step'), h('span', null, '#' + ((hoveredNode.task.chainSeq || 0) + 1))),
|
|
862
|
+
hoveredNode.task.delegationType && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Type'), h('span', { style: { color: DELEGATION_COLORS[hoveredNode.task.delegationType] } }, hoveredNode.task.delegationType)),
|
|
863
|
+
hoveredNode.task.progress > 0 && h('div', { style: { display: 'flex', justifyContent: 'space-between' } }, h('span', { style: { color: 'var(--tp-text-dim)' } }, 'Progress'), h('span', { style: { color: STATUS_COLORS.in_progress } }, hoveredNode.task.progress + '%'))
|
|
856
864
|
)
|
|
857
865
|
),
|
|
858
866
|
|
|
@@ -28,9 +28,9 @@ export function createTaskQueueRoutes(taskQueue: TaskQueueManager) {
|
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
// GET /task-pipeline/stats — pipeline statistics
|
|
31
|
-
router.get('/stats', (c) => {
|
|
31
|
+
router.get('/stats', async (c) => {
|
|
32
32
|
const orgId = c.req.query('orgId') || '';
|
|
33
|
-
const stats = taskQueue.getPipelineStats(orgId);
|
|
33
|
+
const stats = await taskQueue.getPipelineStats(orgId);
|
|
34
34
|
return c.json(stats);
|
|
35
35
|
});
|
|
36
36
|
|
package/src/engine/task-queue.ts
CHANGED
|
@@ -385,11 +385,11 @@ export class TaskQueueManager {
|
|
|
385
385
|
return this.getAllTasks(orgId, limit);
|
|
386
386
|
}
|
|
387
387
|
|
|
388
|
-
getPipelineStats(orgId?: string): {
|
|
388
|
+
async getPipelineStats(orgId?: string): Promise<{
|
|
389
389
|
created: number; assigned: number; inProgress: number; completed: number; failed: number; cancelled: number; total: number;
|
|
390
390
|
todayCompleted: number; todayFailed: number; todayCreated: number; avgDurationMs: number; totalCost: number; totalTokens: number;
|
|
391
391
|
topAgents: Array<{ agent: string; name: string; completed: number; active: number }>;
|
|
392
|
-
} {
|
|
392
|
+
}> {
|
|
393
393
|
const stats = {
|
|
394
394
|
created: 0, assigned: 0, inProgress: 0, completed: 0, failed: 0, cancelled: 0, total: 0,
|
|
395
395
|
todayCompleted: 0, todayFailed: 0, todayCreated: 0, avgDurationMs: 0, totalCost: 0, totalTokens: 0,
|
|
@@ -434,6 +434,34 @@ export class TaskQueueManager {
|
|
|
434
434
|
.map(([agent, d]) => ({ agent, ...d }))
|
|
435
435
|
.sort((a, b) => (b.completed + b.active) - (a.completed + a.active))
|
|
436
436
|
.slice(0, 5);
|
|
437
|
+
|
|
438
|
+
// If DB available, also query today's stats from DB to catch anything not in memory
|
|
439
|
+
if (this.db) {
|
|
440
|
+
try {
|
|
441
|
+
const todayISO = todayStart.toISOString();
|
|
442
|
+
const dbToday = await this.db.get(
|
|
443
|
+
`SELECT COUNT(*) FILTER (WHERE status='completed' AND completed_at >= ?) as dc,
|
|
444
|
+
COUNT(*) FILTER (WHERE status='failed' AND completed_at >= ?) as df,
|
|
445
|
+
COUNT(*) FILTER (WHERE created_at >= ?) as dn
|
|
446
|
+
FROM task_pipeline` + (orgId ? ` WHERE org_id = ?` : ''),
|
|
447
|
+
orgId ? [todayISO, todayISO, todayISO, orgId] : [todayISO, todayISO, todayISO]
|
|
448
|
+
).catch(() => null);
|
|
449
|
+
// Postgres FILTER may not work on all DBs, fallback to separate counts
|
|
450
|
+
if (!dbToday || dbToday.dc === undefined) {
|
|
451
|
+
const r1 = await this.db.get(`SELECT COUNT(*) as c FROM task_pipeline WHERE status='completed' AND completed_at >= ?`, [todayISO]).catch(() => null);
|
|
452
|
+
const r2 = await this.db.get(`SELECT COUNT(*) as c FROM task_pipeline WHERE status='failed' AND completed_at >= ?`, [todayISO]).catch(() => null);
|
|
453
|
+
const r3 = await this.db.get(`SELECT COUNT(*) as c FROM task_pipeline WHERE created_at >= ?`, [todayISO]).catch(() => null);
|
|
454
|
+
if (r1?.c > stats.todayCompleted) stats.todayCompleted = r1.c;
|
|
455
|
+
if (r2?.c > stats.todayFailed) stats.todayFailed = r2.c;
|
|
456
|
+
if (r3?.c > stats.todayCreated) stats.todayCreated = r3.c;
|
|
457
|
+
} else {
|
|
458
|
+
if (dbToday.dc > stats.todayCompleted) stats.todayCompleted = dbToday.dc;
|
|
459
|
+
if (dbToday.df > stats.todayFailed) stats.todayFailed = dbToday.df;
|
|
460
|
+
if (dbToday.dn > stats.todayCreated) stats.todayCreated = dbToday.dn;
|
|
461
|
+
}
|
|
462
|
+
} catch { /* ignore — in-memory stats are fine */ }
|
|
463
|
+
}
|
|
464
|
+
|
|
437
465
|
return stats;
|
|
438
466
|
}
|
|
439
467
|
|