@chrysb/alphaclaw 0.6.2-beta.6 → 0.7.0-beta.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/lib/public/css/agents.css +37 -13
- package/lib/public/css/cron.css +124 -18
- package/lib/public/css/shell.css +61 -2
- package/lib/public/css/theme.css +2 -1
- package/lib/public/js/app.js +41 -33
- package/lib/public/js/components/agents-tab/agent-detail-panel.js +61 -49
- package/lib/public/js/components/agents-tab/agent-overview/index.js +9 -0
- package/lib/public/js/components/agents-tab/agent-overview/tools-card.js +54 -0
- package/lib/public/js/components/cron-tab/cron-calendar.js +164 -151
- package/lib/public/js/components/cron-tab/cron-helpers.js +48 -0
- package/lib/public/js/components/cron-tab/cron-insights-panel.js +8 -39
- package/lib/public/js/components/cron-tab/cron-run-history-panel.js +8 -9
- package/lib/public/js/components/cron-tab/cron-runs-trend-card.js +4 -22
- package/lib/public/js/components/envars.js +187 -46
- package/lib/public/js/components/icons.js +11 -0
- package/lib/public/js/components/models-tab/index.js +137 -133
- package/lib/public/js/components/models-tab/provider-auth-card.js +8 -1
- package/lib/public/js/components/models-tab/use-models.js +35 -8
- package/lib/public/js/components/pane-shell.js +27 -0
- package/lib/public/js/components/routes/envars-route.js +1 -3
- package/lib/public/js/components/routes/models-route.js +1 -3
- package/lib/public/js/lib/app-navigation.js +1 -1
- package/lib/server/cost-utils.js +2 -2
- package/package.json +1 -1
|
@@ -1,34 +1,63 @@
|
|
|
1
1
|
/* ── Agents detail layout ────────────────────── */
|
|
2
2
|
|
|
3
3
|
.app-content-pane.agents-pane {
|
|
4
|
-
|
|
4
|
+
overflow: hidden;
|
|
5
|
+
padding-left: 0;
|
|
6
|
+
padding-right: 0;
|
|
7
|
+
padding-bottom: 0;
|
|
5
8
|
}
|
|
6
9
|
|
|
7
10
|
/* ── Detail panel ────────────────────────────── */
|
|
8
11
|
|
|
9
12
|
.agents-detail-panel {
|
|
10
13
|
height: 100%;
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
min-height: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.agents-detail-header-area {
|
|
20
|
+
padding: 8px 32px 16px;
|
|
13
21
|
}
|
|
14
22
|
|
|
15
|
-
.agents-detail-inner {
|
|
23
|
+
.agents-detail-header-area-inner {
|
|
16
24
|
max-width: 42rem;
|
|
17
25
|
width: 100%;
|
|
18
26
|
margin: 0 auto;
|
|
19
|
-
display: flex;
|
|
20
|
-
flex-direction: column;
|
|
21
|
-
min-height: 100%;
|
|
22
27
|
}
|
|
23
28
|
|
|
24
29
|
.agents-detail-header {
|
|
25
|
-
padding-top: 16px;
|
|
26
30
|
display: flex;
|
|
27
31
|
align-items: flex-start;
|
|
28
32
|
justify-content: space-between;
|
|
29
33
|
gap: 12px;
|
|
30
34
|
}
|
|
31
35
|
|
|
36
|
+
.agents-detail-body {
|
|
37
|
+
flex: 1;
|
|
38
|
+
min-height: 0;
|
|
39
|
+
overflow-y: auto;
|
|
40
|
+
overflow-x: hidden;
|
|
41
|
+
padding: 0 32px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.agents-detail-content {
|
|
45
|
+
max-width: 42rem;
|
|
46
|
+
width: 100%;
|
|
47
|
+
margin: 0 auto;
|
|
48
|
+
padding: 0 0 24px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@media (max-width: 768px) {
|
|
52
|
+
.agents-detail-header-area {
|
|
53
|
+
padding: 16px 14px 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.agents-detail-body {
|
|
57
|
+
padding: 0 14px;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
32
61
|
.agents-detail-header-title {
|
|
33
62
|
font-size: 16px;
|
|
34
63
|
font-weight: 600;
|
|
@@ -72,11 +101,6 @@
|
|
|
72
101
|
border-bottom-color: var(--accent);
|
|
73
102
|
}
|
|
74
103
|
|
|
75
|
-
.agents-detail-content {
|
|
76
|
-
flex: 1;
|
|
77
|
-
padding: 16px 0;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
104
|
/* ── Empty state ─────────────────────────────── */
|
|
81
105
|
|
|
82
106
|
.agents-empty-state {
|
package/lib/public/css/cron.css
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
.app-content-pane.cron-pane {
|
|
2
|
-
padding:
|
|
2
|
+
padding: 24px 32px 12px;
|
|
3
|
+
overflow: hidden;
|
|
3
4
|
}
|
|
4
5
|
|
|
5
6
|
.cron-tab-shell {
|
|
@@ -10,8 +11,7 @@
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
.cron-tab-header {
|
|
13
|
-
padding:
|
|
14
|
-
border-bottom: 1px solid var(--border);
|
|
14
|
+
padding: 0 0 16px;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
.cron-tab-header-content {
|
|
@@ -33,13 +33,28 @@
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
.cron-tab-main-content {
|
|
36
|
-
width:
|
|
36
|
+
width: 100%;
|
|
37
|
+
max-width: 672px;
|
|
37
38
|
margin-left: auto;
|
|
38
39
|
margin-right: auto;
|
|
39
40
|
padding: 0 0 24px;
|
|
40
41
|
min-height: 100%;
|
|
41
42
|
}
|
|
42
43
|
|
|
44
|
+
.cron-tab-main-content .cron-detail-content {
|
|
45
|
+
padding-top: 8px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@media (max-width: 768px) {
|
|
49
|
+
.app-content-pane.cron-pane {
|
|
50
|
+
padding: 0 14px 12px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.cron-tab-header {
|
|
54
|
+
padding: 0 0 12px;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
43
58
|
.cron-tab-selector-shell {
|
|
44
59
|
position: relative;
|
|
45
60
|
width: min(100%, 320px);
|
|
@@ -329,7 +344,6 @@
|
|
|
329
344
|
.cron-calendar-legend-pill {
|
|
330
345
|
font-size: 10px;
|
|
331
346
|
line-height: 1;
|
|
332
|
-
border: 1px solid transparent;
|
|
333
347
|
border-radius: 999px;
|
|
334
348
|
padding: 4px 7px;
|
|
335
349
|
}
|
|
@@ -338,13 +352,13 @@
|
|
|
338
352
|
border: 1px solid var(--border);
|
|
339
353
|
border-radius: 10px;
|
|
340
354
|
overflow: auto;
|
|
341
|
-
background:
|
|
355
|
+
background: var(--bg-surface);
|
|
342
356
|
}
|
|
343
357
|
|
|
344
358
|
.cron-calendar-grid-header,
|
|
345
359
|
.cron-calendar-grid-row {
|
|
346
360
|
display: grid;
|
|
347
|
-
grid-template-columns:
|
|
361
|
+
grid-template-columns: 72px repeat(7, minmax(80px, 1fr));
|
|
348
362
|
}
|
|
349
363
|
|
|
350
364
|
.cron-calendar-day-header {
|
|
@@ -370,6 +384,79 @@
|
|
|
370
384
|
border-bottom: 1px solid var(--border);
|
|
371
385
|
border-right: 1px solid var(--border);
|
|
372
386
|
background: rgba(0, 0, 0, 0.15);
|
|
387
|
+
position: sticky;
|
|
388
|
+
left: 0;
|
|
389
|
+
z-index: 2;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
.cron-calendar-grid-header .cron-calendar-hour-cell {
|
|
393
|
+
top: 0;
|
|
394
|
+
z-index: 3;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
.cron-calendar-grid-corner {
|
|
398
|
+
display: flex;
|
|
399
|
+
align-items: center;
|
|
400
|
+
justify-content: center;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.cron-calendar-expand-btn {
|
|
404
|
+
width: 22px;
|
|
405
|
+
height: 22px;
|
|
406
|
+
border-radius: 6px;
|
|
407
|
+
border: 1px solid var(--border);
|
|
408
|
+
background: rgba(255, 255, 255, 0.03);
|
|
409
|
+
color: var(--text-dim);
|
|
410
|
+
display: inline-flex;
|
|
411
|
+
align-items: center;
|
|
412
|
+
justify-content: center;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.cron-calendar-expand-btn:hover {
|
|
416
|
+
color: var(--text);
|
|
417
|
+
border-color: rgba(148, 163, 184, 0.5);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.cron-calendar-grid-wrap {
|
|
421
|
+
position: relative;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.cron-calendar-lightbox-panel {
|
|
425
|
+
width: min(96vw, 1200px);
|
|
426
|
+
max-height: 88vh;
|
|
427
|
+
display: flex;
|
|
428
|
+
flex-direction: column;
|
|
429
|
+
gap: 10px;
|
|
430
|
+
padding: 16px;
|
|
431
|
+
border: 1px solid var(--border);
|
|
432
|
+
border-radius: 12px;
|
|
433
|
+
background: var(--bg-sidebar);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.cron-calendar-lightbox-close {
|
|
437
|
+
width: 26px;
|
|
438
|
+
height: 26px;
|
|
439
|
+
border-radius: 8px;
|
|
440
|
+
border: 1px solid var(--border);
|
|
441
|
+
background: rgba(255, 255, 255, 0.03);
|
|
442
|
+
color: var(--text-dim);
|
|
443
|
+
display: inline-flex;
|
|
444
|
+
align-items: center;
|
|
445
|
+
justify-content: center;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.cron-calendar-lightbox-close:hover {
|
|
449
|
+
color: var(--text);
|
|
450
|
+
border-color: rgba(148, 163, 184, 0.5);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
.cron-calendar-lightbox-body {
|
|
454
|
+
min-height: 0;
|
|
455
|
+
overflow: auto;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.cron-calendar-grid-row .cron-calendar-hour-cell {
|
|
459
|
+
box-shadow: 1px 0 0 var(--border);
|
|
373
460
|
}
|
|
374
461
|
|
|
375
462
|
.cron-calendar-grid-cell {
|
|
@@ -462,31 +549,50 @@
|
|
|
462
549
|
box-shadow: inset 0 0 0 1px rgba(250, 204, 21, 0.45);
|
|
463
550
|
}
|
|
464
551
|
|
|
465
|
-
.cron-calendar-compact-
|
|
552
|
+
.cron-calendar-compact-list {
|
|
466
553
|
display: flex;
|
|
467
|
-
flex-
|
|
554
|
+
flex-direction: column;
|
|
468
555
|
gap: 6px;
|
|
469
|
-
align-items: center;
|
|
470
556
|
}
|
|
471
557
|
|
|
472
|
-
.cron-calendar-compact-
|
|
558
|
+
.cron-calendar-compact-row {
|
|
559
|
+
width: 100%;
|
|
560
|
+
display: flex;
|
|
561
|
+
align-items: center;
|
|
562
|
+
justify-content: space-between;
|
|
563
|
+
gap: 10px;
|
|
564
|
+
border: 1px solid rgba(148, 163, 184, 0.32);
|
|
565
|
+
border-radius: 8px;
|
|
566
|
+
padding: 7px 9px;
|
|
567
|
+
text-align: left;
|
|
473
568
|
font-size: 11px;
|
|
474
569
|
line-height: 1.2;
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
.cron-calendar-compact-main {
|
|
573
|
+
min-width: 0;
|
|
478
574
|
display: inline-flex;
|
|
479
575
|
align-items: center;
|
|
480
|
-
gap:
|
|
481
|
-
max-width: 260px;
|
|
482
|
-
cursor: pointer;
|
|
576
|
+
gap: 8px;
|
|
483
577
|
}
|
|
484
578
|
|
|
485
579
|
.cron-calendar-compact-time {
|
|
486
580
|
font-size: 10px;
|
|
487
581
|
font-family: var(--font-mono, monospace);
|
|
488
|
-
opacity: 0.
|
|
582
|
+
opacity: 0.72;
|
|
583
|
+
white-space: nowrap;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
.cron-calendar-compact-name {
|
|
587
|
+
color: var(--text);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.cron-calendar-compact-estimate {
|
|
591
|
+
font-size: 10px;
|
|
592
|
+
color: var(--text);
|
|
593
|
+
font-weight: 500;
|
|
489
594
|
white-space: nowrap;
|
|
595
|
+
text-align: right;
|
|
490
596
|
}
|
|
491
597
|
|
|
492
598
|
.cron-runs-trend-bars {
|
package/lib/public/css/shell.css
CHANGED
|
@@ -63,6 +63,62 @@
|
|
|
63
63
|
padding: 0;
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
/* ── Fixed-header pane shell ────────────────────── */
|
|
67
|
+
|
|
68
|
+
.app-content-pane.ac-fixed-header-pane {
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
padding-left: 0;
|
|
71
|
+
padding-right: 0;
|
|
72
|
+
padding-bottom: 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.ac-pane-shell {
|
|
76
|
+
height: 100%;
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-direction: column;
|
|
79
|
+
min-height: 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.ac-pane-header {
|
|
83
|
+
padding: 16px 32px 16px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.ac-pane-header-content {
|
|
87
|
+
width: 100%;
|
|
88
|
+
max-width: 672px;
|
|
89
|
+
margin-left: auto;
|
|
90
|
+
margin-right: auto;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.ac-pane-body {
|
|
94
|
+
flex: 1;
|
|
95
|
+
min-height: 0;
|
|
96
|
+
overflow-y: auto;
|
|
97
|
+
overflow-x: hidden;
|
|
98
|
+
padding: 0 32px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.ac-pane-body-content {
|
|
102
|
+
width: 100%;
|
|
103
|
+
max-width: 672px;
|
|
104
|
+
margin-left: auto;
|
|
105
|
+
margin-right: auto;
|
|
106
|
+
padding-bottom: 24px;
|
|
107
|
+
display: flex;
|
|
108
|
+
flex-direction: column;
|
|
109
|
+
gap: 16px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
@media (max-width: 768px) {
|
|
113
|
+
.ac-pane-header {
|
|
114
|
+
padding: 16px 14px 12px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.ac-pane-body {
|
|
118
|
+
padding: 0 14px;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
66
122
|
/* ── Sidebar ───────────────────────────────────── */
|
|
67
123
|
|
|
68
124
|
.app-sidebar {
|
|
@@ -336,6 +392,7 @@
|
|
|
336
392
|
}
|
|
337
393
|
.app-content-pane {
|
|
338
394
|
padding: 0 14px 12px;
|
|
395
|
+
top: 52px;
|
|
339
396
|
}
|
|
340
397
|
|
|
341
398
|
.sidebar-resizer {
|
|
@@ -346,7 +403,9 @@
|
|
|
346
403
|
display: flex;
|
|
347
404
|
align-items: center;
|
|
348
405
|
justify-content: center;
|
|
349
|
-
position:
|
|
406
|
+
position: absolute;
|
|
407
|
+
left: 0;
|
|
408
|
+
right: 0;
|
|
350
409
|
top: 0;
|
|
351
410
|
z-index: 15;
|
|
352
411
|
background: var(--panel-bg-contrast);
|
|
@@ -355,7 +414,7 @@
|
|
|
355
414
|
border-radius: 0;
|
|
356
415
|
min-height: 52px;
|
|
357
416
|
padding: 8px 14px;
|
|
358
|
-
margin: 0
|
|
417
|
+
margin: 0;
|
|
359
418
|
}
|
|
360
419
|
|
|
361
420
|
.mobile-topbar.is-scrolled {
|
package/lib/public/css/theme.css
CHANGED
package/lib/public/js/app.js
CHANGED
|
@@ -77,6 +77,8 @@ const App = () => {
|
|
|
77
77
|
|
|
78
78
|
const isAgentsRoute = location.startsWith("/agents");
|
|
79
79
|
const isCronRoute = location.startsWith("/cron");
|
|
80
|
+
const isEnvarsRoute = location.startsWith("/envars");
|
|
81
|
+
const isModelsRoute = location.startsWith("/models");
|
|
80
82
|
const selectedAgentId = (() => {
|
|
81
83
|
const match = location.match(/^\/agents\/([^/]+)/);
|
|
82
84
|
return match ? decodeURIComponent(match[1]) : "";
|
|
@@ -211,6 +213,31 @@ const App = () => {
|
|
|
211
213
|
/>
|
|
212
214
|
|
|
213
215
|
<div class="app-content">
|
|
216
|
+
<div
|
|
217
|
+
class=${`mobile-topbar ${shellState.mobileTopbarScrolled ? "is-scrolled" : ""}`}
|
|
218
|
+
>
|
|
219
|
+
<button
|
|
220
|
+
class="mobile-topbar-menu"
|
|
221
|
+
onclick=${() =>
|
|
222
|
+
shellActions.setMobileSidebarOpen((open) => !open)}
|
|
223
|
+
aria-label="Open menu"
|
|
224
|
+
aria-expanded=${shellState.mobileSidebarOpen ? "true" : "false"}
|
|
225
|
+
>
|
|
226
|
+
<svg
|
|
227
|
+
width="18"
|
|
228
|
+
height="18"
|
|
229
|
+
viewBox="0 0 16 16"
|
|
230
|
+
fill="currentColor"
|
|
231
|
+
>
|
|
232
|
+
<path
|
|
233
|
+
d="M2 3.75a.75.75 0 01.75-.75h10.5a.75.75 0 010 1.5H2.75A.75.75 0 012 3.75zm0 4.25a.75.75 0 01.75-.75h10.5a.75.75 0 010 1.5H2.75A.75.75 0 012 8zm0 4.25a.75.75 0 01.75-.75h10.5a.75.75 0 010 1.5H2.75a.75.75 0 01-.75-.75z"
|
|
234
|
+
/>
|
|
235
|
+
</svg>
|
|
236
|
+
</button>
|
|
237
|
+
<span class="mobile-topbar-title">
|
|
238
|
+
<span style="color: var(--accent)">alpha</span>claw
|
|
239
|
+
</span>
|
|
240
|
+
</div>
|
|
214
241
|
<div
|
|
215
242
|
class="app-content-pane browse-pane"
|
|
216
243
|
style=${{ display: browseState.isBrowseRoute ? "block" : "none" }}
|
|
@@ -265,38 +292,25 @@ const App = () => {
|
|
|
265
292
|
onSetLocation=${setLocation}
|
|
266
293
|
/>
|
|
267
294
|
</div>
|
|
295
|
+
<div
|
|
296
|
+
class="app-content-pane ac-fixed-header-pane"
|
|
297
|
+
style=${{ display: isEnvarsRoute ? "block" : "none" }}
|
|
298
|
+
>
|
|
299
|
+
<${EnvarsRoute} onRestartRequired=${controllerActions.setRestartRequired} />
|
|
300
|
+
</div>
|
|
301
|
+
<div
|
|
302
|
+
class="app-content-pane ac-fixed-header-pane"
|
|
303
|
+
style=${{ display: isModelsRoute ? "block" : "none" }}
|
|
304
|
+
>
|
|
305
|
+
<${ModelsRoute} onRestartRequired=${controllerActions.setRestartRequired} />
|
|
306
|
+
</div>
|
|
268
307
|
<div
|
|
269
308
|
class="app-content-pane"
|
|
270
309
|
onscroll=${shellActions.handlePaneScroll}
|
|
271
|
-
style=${{ display: browseState.isBrowseRoute || isAgentsRoute || isCronRoute ? "none" : "block" }}
|
|
310
|
+
style=${{ display: browseState.isBrowseRoute || isAgentsRoute || isCronRoute || isEnvarsRoute || isModelsRoute ? "none" : "block" }}
|
|
272
311
|
>
|
|
273
|
-
<div
|
|
274
|
-
class=${`mobile-topbar ${shellState.mobileTopbarScrolled ? "is-scrolled" : ""}`}
|
|
275
|
-
>
|
|
276
|
-
<button
|
|
277
|
-
class="mobile-topbar-menu"
|
|
278
|
-
onclick=${() =>
|
|
279
|
-
shellActions.setMobileSidebarOpen((open) => !open)}
|
|
280
|
-
aria-label="Open menu"
|
|
281
|
-
aria-expanded=${shellState.mobileSidebarOpen ? "true" : "false"}
|
|
282
|
-
>
|
|
283
|
-
<svg
|
|
284
|
-
width="18"
|
|
285
|
-
height="18"
|
|
286
|
-
viewBox="0 0 16 16"
|
|
287
|
-
fill="currentColor"
|
|
288
|
-
>
|
|
289
|
-
<path
|
|
290
|
-
d="M2 3.75a.75.75 0 01.75-.75h10.5a.75.75 0 010 1.5H2.75A.75.75 0 012 3.75zm0 4.25a.75.75 0 01.75-.75h10.5a.75.75 0 010 1.5H2.75A.75.75 0 012 8zm0 4.25a.75.75 0 01.75-.75h10.5a.75.75 0 010 1.5H2.75a.75.75 0 01-.75-.75z"
|
|
291
|
-
/>
|
|
292
|
-
</svg>
|
|
293
|
-
</button>
|
|
294
|
-
<span class="mobile-topbar-title">
|
|
295
|
-
<span style="color: var(--accent)">alpha</span>claw
|
|
296
|
-
</span>
|
|
297
|
-
</div>
|
|
298
312
|
<div class="max-w-2xl w-full mx-auto">
|
|
299
|
-
${!browseState.isBrowseRoute && !isAgentsRoute && !isCronRoute
|
|
313
|
+
${!browseState.isBrowseRoute && !isAgentsRoute && !isCronRoute && !isEnvarsRoute && !isModelsRoute
|
|
300
314
|
? html`
|
|
301
315
|
<${Switch}>
|
|
302
316
|
<${Route} path="/general">
|
|
@@ -336,9 +350,6 @@ const App = () => {
|
|
|
336
350
|
<${Route} path="/telegram">
|
|
337
351
|
<${RouteRedirect} to="/telegram/default" />
|
|
338
352
|
</${Route}>
|
|
339
|
-
<${Route} path="/models">
|
|
340
|
-
<${ModelsRoute} onRestartRequired=${controllerActions.setRestartRequired} />
|
|
341
|
-
</${Route}>
|
|
342
353
|
<${Route} path="/providers">
|
|
343
354
|
<${RouteRedirect} to="/models" />
|
|
344
355
|
</${Route}>
|
|
@@ -368,9 +379,6 @@ const App = () => {
|
|
|
368
379
|
<${Route} path="/usage">
|
|
369
380
|
<${UsageRoute} onSetLocation=${setLocation} />
|
|
370
381
|
</${Route}>
|
|
371
|
-
<${Route} path="/envars">
|
|
372
|
-
<${EnvarsRoute} onRestartRequired=${controllerActions.setRestartRequired} />
|
|
373
|
-
</${Route}>
|
|
374
382
|
<${Route} path="/webhooks/:hookName">
|
|
375
383
|
${(params) => html`
|
|
376
384
|
<${WebhooksRoute}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { h } from "https://esm.sh/preact";
|
|
2
|
-
import { useState, useCallback } from "https://esm.sh/preact/hooks";
|
|
2
|
+
import { useState, useCallback, useMemo } from "https://esm.sh/preact/hooks";
|
|
3
3
|
import htm from "https://esm.sh/htm";
|
|
4
4
|
import { ActionButton } from "../action-button.js";
|
|
5
5
|
import { Badge } from "../badge.js";
|
|
@@ -64,6 +64,12 @@ export const AgentDetailPanel = ({
|
|
|
64
64
|
|
|
65
65
|
const isSaving = saving || savingTools;
|
|
66
66
|
|
|
67
|
+
const toolsSummary = useMemo(() => ({
|
|
68
|
+
profile: tools.profile,
|
|
69
|
+
enabledCount: (tools.toolStates || []).filter((t) => t.enabled).length,
|
|
70
|
+
totalCount: (tools.toolStates || []).length,
|
|
71
|
+
}), [tools.profile, tools.toolStates]);
|
|
72
|
+
|
|
67
73
|
if (!agent) {
|
|
68
74
|
return html`
|
|
69
75
|
<div class="agents-detail-panel">
|
|
@@ -76,57 +82,61 @@ export const AgentDetailPanel = ({
|
|
|
76
82
|
|
|
77
83
|
return html`
|
|
78
84
|
<div class="agents-detail-panel">
|
|
79
|
-
<div class="agents-detail-
|
|
80
|
-
<div class="agents-detail-header">
|
|
81
|
-
<div class="
|
|
82
|
-
<div class="
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
<
|
|
85
|
+
<div class="agents-detail-header-area">
|
|
86
|
+
<div class="agents-detail-header-area-inner">
|
|
87
|
+
<div class="agents-detail-header">
|
|
88
|
+
<div class="min-w-0">
|
|
89
|
+
<div class="flex items-center gap-2 min-w-0">
|
|
90
|
+
<span class="agents-detail-header-title">
|
|
91
|
+
${agent.name || agent.id}
|
|
92
|
+
</span>
|
|
93
|
+
<button
|
|
94
|
+
type="button"
|
|
95
|
+
class="text-gray-500 hover:text-gray-300 transition-colors p-0.5 -ml-0.5"
|
|
96
|
+
onclick=${() => onEdit(agent)}
|
|
97
|
+
title="Edit agent name"
|
|
98
|
+
>
|
|
99
|
+
<${PencilIcon} />
|
|
100
|
+
</button>
|
|
101
|
+
${agent.default
|
|
102
|
+
? html`<${Badge} tone="cyan">Default</${Badge}>`
|
|
103
|
+
: null}
|
|
104
|
+
</div>
|
|
105
|
+
<div class="mt-1 flex flex-wrap items-center gap-x-1.5 gap-y-1 min-w-0 text-xs text-gray-500">
|
|
106
|
+
<span class="font-mono">${agent.id}</span>
|
|
107
|
+
</div>
|
|
100
108
|
</div>
|
|
109
|
+
<${PopActions} visible=${tools.dirty}>
|
|
110
|
+
<${ActionButton}
|
|
111
|
+
onClick=${tools.reset}
|
|
112
|
+
disabled=${isSaving}
|
|
113
|
+
tone="secondary"
|
|
114
|
+
size="sm"
|
|
115
|
+
idleLabel="Cancel"
|
|
116
|
+
className="text-xs"
|
|
117
|
+
/>
|
|
118
|
+
<${ActionButton}
|
|
119
|
+
onClick=${handleSaveTools}
|
|
120
|
+
disabled=${isSaving}
|
|
121
|
+
loading=${isSaving}
|
|
122
|
+
loadingMode="inline"
|
|
123
|
+
tone="primary"
|
|
124
|
+
size="sm"
|
|
125
|
+
idleLabel="Save changes"
|
|
126
|
+
loadingLabel="Saving…"
|
|
127
|
+
className="text-xs"
|
|
128
|
+
/>
|
|
129
|
+
</${PopActions}>
|
|
101
130
|
</div>
|
|
102
|
-
<${
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
idleLabel="Cancel"
|
|
109
|
-
className="text-xs"
|
|
110
|
-
/>
|
|
111
|
-
<${ActionButton}
|
|
112
|
-
onClick=${handleSaveTools}
|
|
113
|
-
disabled=${isSaving}
|
|
114
|
-
loading=${isSaving}
|
|
115
|
-
loadingMode="inline"
|
|
116
|
-
tone="primary"
|
|
117
|
-
size="sm"
|
|
118
|
-
idleLabel="Save changes"
|
|
119
|
-
loadingLabel="Saving…"
|
|
120
|
-
className="text-xs"
|
|
121
|
-
/>
|
|
122
|
-
</${PopActions}>
|
|
131
|
+
<${PillTabs}
|
|
132
|
+
tabs=${kDetailTabs}
|
|
133
|
+
activeTab=${activeTab}
|
|
134
|
+
onSelectTab=${onSelectTab}
|
|
135
|
+
className="flex items-center gap-2 pt-6"
|
|
136
|
+
/>
|
|
123
137
|
</div>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
activeTab=${activeTab}
|
|
127
|
-
onSelectTab=${onSelectTab}
|
|
128
|
-
className="flex items-center gap-2 pt-6"
|
|
129
|
-
/>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="agents-detail-body">
|
|
130
140
|
<div class="agents-detail-content">
|
|
131
141
|
${activeTab === "overview"
|
|
132
142
|
? html`
|
|
@@ -134,10 +144,12 @@ export const AgentDetailPanel = ({
|
|
|
134
144
|
agent=${agent}
|
|
135
145
|
agents=${agents}
|
|
136
146
|
saving=${saving}
|
|
147
|
+
toolsSummary=${toolsSummary}
|
|
137
148
|
onUpdateAgent=${onUpdateAgent}
|
|
138
149
|
onSetLocation=${onSetLocation}
|
|
139
150
|
onOpenWorkspace=${onOpenWorkspace}
|
|
140
151
|
onSwitchToModels=${() => onSetLocation("/models")}
|
|
152
|
+
onSwitchToTools=${() => onSelectTab("tools")}
|
|
141
153
|
onSetDefault=${onSetDefault}
|
|
142
154
|
onDelete=${onDelete}
|
|
143
155
|
/>
|
|
@@ -3,6 +3,7 @@ import htm from "https://esm.sh/htm";
|
|
|
3
3
|
import { ChannelOperationsPanel } from "../../channel-operations-panel.js";
|
|
4
4
|
import { ManageCard } from "./manage-card.js";
|
|
5
5
|
import { AgentModelCard } from "./model-card.js";
|
|
6
|
+
import { AgentToolsCard } from "./tools-card.js";
|
|
6
7
|
import { WorkspaceCard } from "./workspace-card.js";
|
|
7
8
|
|
|
8
9
|
const html = htm.bind(h);
|
|
@@ -11,10 +12,12 @@ export const AgentOverview = ({
|
|
|
11
12
|
agent = {},
|
|
12
13
|
agents = [],
|
|
13
14
|
saving = false,
|
|
15
|
+
toolsSummary = {},
|
|
14
16
|
onUpdateAgent = async () => {},
|
|
15
17
|
onSetLocation = () => {},
|
|
16
18
|
onOpenWorkspace = () => {},
|
|
17
19
|
onSwitchToModels = () => {},
|
|
20
|
+
onSwitchToTools = () => {},
|
|
18
21
|
onSetDefault = () => {},
|
|
19
22
|
onDelete = () => {},
|
|
20
23
|
}) => {
|
|
@@ -33,6 +36,12 @@ export const AgentOverview = ({
|
|
|
33
36
|
onUpdateAgent=${onUpdateAgent}
|
|
34
37
|
onSwitchToModels=${onSwitchToModels}
|
|
35
38
|
/>
|
|
39
|
+
<${AgentToolsCard}
|
|
40
|
+
profile=${toolsSummary.profile || "full"}
|
|
41
|
+
enabledCount=${toolsSummary.enabledCount || 0}
|
|
42
|
+
totalCount=${toolsSummary.totalCount || 0}
|
|
43
|
+
onSwitchToTools=${onSwitchToTools}
|
|
44
|
+
/>
|
|
36
45
|
<${ChannelOperationsPanel}
|
|
37
46
|
agent=${agent}
|
|
38
47
|
agents=${agents}
|