@workerdeck/ui 3.4.0 → 3.6.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/build/index.d.mts +55 -4
- package/build/index.mjs +702 -163
- package/build/index.mjs.map +1 -1
- package/build/scoped.css +131 -0
- package/package.json +4 -4
- package/src/components/agent/AgentAvatar.tsx +117 -0
- package/src/components/agent/SessionBrowser.tsx +246 -43
- package/src/components/agent/SessionGroups.tsx +256 -23
- package/src/components/agent/SessionItem.tsx +200 -68
- package/src/index.ts +11 -0
- package/src/lib/team-drop.ts +65 -0
- package/src/styles/theme.css +22 -0
package/build/scoped.css
CHANGED
|
@@ -311,18 +311,27 @@
|
|
|
311
311
|
.wd-root .right-4 {
|
|
312
312
|
right: calc(var(--spacing) * 4);
|
|
313
313
|
}
|
|
314
|
+
.wd-root .-bottom-1 {
|
|
315
|
+
bottom: calc(var(--spacing) * -1);
|
|
316
|
+
}
|
|
314
317
|
.wd-root .bottom-0 {
|
|
315
318
|
bottom: 0px;
|
|
316
319
|
}
|
|
317
320
|
.wd-root .bottom-2 {
|
|
318
321
|
bottom: calc(var(--spacing) * 2);
|
|
319
322
|
}
|
|
323
|
+
.wd-root .bottom-3 {
|
|
324
|
+
bottom: calc(var(--spacing) * 3);
|
|
325
|
+
}
|
|
320
326
|
.wd-root .bottom-4 {
|
|
321
327
|
bottom: calc(var(--spacing) * 4);
|
|
322
328
|
}
|
|
323
329
|
.wd-root .bottom-full {
|
|
324
330
|
bottom: 100%;
|
|
325
331
|
}
|
|
332
|
+
.wd-root .-left-\[7px\] {
|
|
333
|
+
left: calc(7px * -1);
|
|
334
|
+
}
|
|
326
335
|
.wd-root .left-0 {
|
|
327
336
|
left: 0px;
|
|
328
337
|
}
|
|
@@ -431,6 +440,9 @@
|
|
|
431
440
|
.wd-root .-mr-1 {
|
|
432
441
|
margin-right: calc(var(--spacing) * -1);
|
|
433
442
|
}
|
|
443
|
+
.wd-root .-mr-1\.5 {
|
|
444
|
+
margin-right: calc(var(--spacing) * -1.5);
|
|
445
|
+
}
|
|
434
446
|
.wd-root .mr-1 {
|
|
435
447
|
margin-right: var(--spacing);
|
|
436
448
|
}
|
|
@@ -455,6 +467,12 @@
|
|
|
455
467
|
.wd-root .ml-1 {
|
|
456
468
|
margin-left: var(--spacing);
|
|
457
469
|
}
|
|
470
|
+
.wd-root .ml-3 {
|
|
471
|
+
margin-left: calc(var(--spacing) * 3);
|
|
472
|
+
}
|
|
473
|
+
.wd-root .ml-3\.5 {
|
|
474
|
+
margin-left: calc(var(--spacing) * 3.5);
|
|
475
|
+
}
|
|
458
476
|
.wd-root .ml-auto {
|
|
459
477
|
margin-left: auto;
|
|
460
478
|
}
|
|
@@ -501,6 +519,10 @@
|
|
|
501
519
|
width: calc(var(--spacing) * 1.5);
|
|
502
520
|
height: calc(var(--spacing) * 1.5);
|
|
503
521
|
}
|
|
522
|
+
.wd-root .size-1\/2 {
|
|
523
|
+
width: calc(1 / 2 * 100%);
|
|
524
|
+
height: calc(1 / 2 * 100%);
|
|
525
|
+
}
|
|
504
526
|
.wd-root .size-2 {
|
|
505
527
|
width: calc(var(--spacing) * 2);
|
|
506
528
|
height: calc(var(--spacing) * 2);
|
|
@@ -678,6 +700,9 @@
|
|
|
678
700
|
.wd-root .w-36 {
|
|
679
701
|
width: calc(var(--spacing) * 36);
|
|
680
702
|
}
|
|
703
|
+
.wd-root .w-44 {
|
|
704
|
+
width: calc(var(--spacing) * 44);
|
|
705
|
+
}
|
|
681
706
|
.wd-root .w-48 {
|
|
682
707
|
width: calc(var(--spacing) * 48);
|
|
683
708
|
}
|
|
@@ -738,6 +763,9 @@
|
|
|
738
763
|
.wd-root .max-w-full {
|
|
739
764
|
max-width: 100%;
|
|
740
765
|
}
|
|
766
|
+
.wd-root .max-w-max {
|
|
767
|
+
max-width: max-content;
|
|
768
|
+
}
|
|
741
769
|
.wd-root .max-w-md {
|
|
742
770
|
max-width: var(--container-md);
|
|
743
771
|
}
|
|
@@ -798,6 +826,9 @@
|
|
|
798
826
|
.wd-root .grow {
|
|
799
827
|
flex-grow: 1;
|
|
800
828
|
}
|
|
829
|
+
.wd-root .basis-0 {
|
|
830
|
+
flex-basis: 0px;
|
|
831
|
+
}
|
|
801
832
|
.wd-root .border-collapse {
|
|
802
833
|
border-collapse: collapse;
|
|
803
834
|
}
|
|
@@ -872,6 +903,9 @@
|
|
|
872
903
|
.wd-root .appearance-none {
|
|
873
904
|
appearance: none;
|
|
874
905
|
}
|
|
906
|
+
.wd-root .grid-cols-4 {
|
|
907
|
+
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
908
|
+
}
|
|
875
909
|
.wd-root .flex-col {
|
|
876
910
|
flex-direction: column;
|
|
877
911
|
}
|
|
@@ -1003,6 +1037,12 @@
|
|
|
1003
1037
|
.wd-root .rounded {
|
|
1004
1038
|
border-radius: 0.25rem;
|
|
1005
1039
|
}
|
|
1040
|
+
.wd-root .rounded-\[2px\] {
|
|
1041
|
+
border-radius: 2px;
|
|
1042
|
+
}
|
|
1043
|
+
.wd-root .rounded-\[3px\] {
|
|
1044
|
+
border-radius: 3px;
|
|
1045
|
+
}
|
|
1006
1046
|
.wd-root .rounded-\[4px\] {
|
|
1007
1047
|
border-radius: 4px;
|
|
1008
1048
|
}
|
|
@@ -1064,6 +1104,12 @@
|
|
|
1064
1104
|
.wd-root .border-\[var\(--wd-shell-accent\)\] {
|
|
1065
1105
|
border-color: var(--wd-shell-accent);
|
|
1066
1106
|
}
|
|
1107
|
+
.wd-root .border-accent\/50 {
|
|
1108
|
+
border-color: var(--accent);
|
|
1109
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1110
|
+
border-color: color-mix(in oklab, var(--accent) 50%, transparent);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1067
1113
|
.wd-root .border-border {
|
|
1068
1114
|
border-color: var(--border);
|
|
1069
1115
|
}
|
|
@@ -1139,6 +1185,12 @@
|
|
|
1139
1185
|
.wd-root .bg-accent-bg {
|
|
1140
1186
|
background-color: var(--accent-bg);
|
|
1141
1187
|
}
|
|
1188
|
+
.wd-root .bg-accent\/10 {
|
|
1189
|
+
background-color: var(--accent);
|
|
1190
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1191
|
+
background-color: color-mix(in oklab, var(--accent) 10%, transparent);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1142
1194
|
.wd-root .bg-background {
|
|
1143
1195
|
background-color: var(--background);
|
|
1144
1196
|
}
|
|
@@ -1259,6 +1311,9 @@
|
|
|
1259
1311
|
.wd-root .bg-red-100 {
|
|
1260
1312
|
background-color: var(--color-red-100);
|
|
1261
1313
|
}
|
|
1314
|
+
.wd-root .bg-row-attention {
|
|
1315
|
+
background-color: var(--row-attention);
|
|
1316
|
+
}
|
|
1262
1317
|
.wd-root .bg-row-hover\/50 {
|
|
1263
1318
|
background-color: var(--row-hover);
|
|
1264
1319
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -1352,6 +1407,9 @@
|
|
|
1352
1407
|
.wd-root .p-px {
|
|
1353
1408
|
padding: 1px;
|
|
1354
1409
|
}
|
|
1410
|
+
.wd-root .px-0\.5 {
|
|
1411
|
+
padding-inline: calc(var(--spacing) * 0.5);
|
|
1412
|
+
}
|
|
1355
1413
|
.wd-root .px-1 {
|
|
1356
1414
|
padding-inline: var(--spacing);
|
|
1357
1415
|
}
|
|
@@ -1475,6 +1533,9 @@
|
|
|
1475
1533
|
.wd-root .pb-\[var\(--wd-composer-padding\)\] {
|
|
1476
1534
|
padding-bottom: var(--wd-composer-padding);
|
|
1477
1535
|
}
|
|
1536
|
+
.wd-root .pl-1 {
|
|
1537
|
+
padding-left: var(--spacing);
|
|
1538
|
+
}
|
|
1478
1539
|
.wd-root .pl-1\.5 {
|
|
1479
1540
|
padding-left: calc(var(--spacing) * 1.5);
|
|
1480
1541
|
}
|
|
@@ -1571,9 +1632,16 @@
|
|
|
1571
1632
|
.wd-root .text-\[0\.75rem\] {
|
|
1572
1633
|
font-size: 0.75rem;
|
|
1573
1634
|
}
|
|
1635
|
+
.wd-root .text-\[0\.625rem\] {
|
|
1636
|
+
font-size: 0.625rem;
|
|
1637
|
+
}
|
|
1574
1638
|
.wd-root .text-\[9px\] {
|
|
1575
1639
|
font-size: 9px;
|
|
1576
1640
|
}
|
|
1641
|
+
.wd-root .leading-3\.5 {
|
|
1642
|
+
--tw-leading: calc(var(--spacing) * 3.5);
|
|
1643
|
+
line-height: calc(var(--spacing) * 3.5);
|
|
1644
|
+
}
|
|
1577
1645
|
.wd-root .leading-4 {
|
|
1578
1646
|
--tw-leading: calc(var(--spacing) * 4);
|
|
1579
1647
|
line-height: calc(var(--spacing) * 4);
|
|
@@ -1790,6 +1858,10 @@
|
|
|
1790
1858
|
--tw-shadow: var(--shadow-xs);
|
|
1791
1859
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1792
1860
|
}
|
|
1861
|
+
.wd-root .shadow-\[inset_0_-2px_0_0_var\(--color-accent\)\] {
|
|
1862
|
+
--tw-shadow: inset 0 -2px 0 0 var(--tw-shadow-color, var(--color-accent));
|
|
1863
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1864
|
+
}
|
|
1793
1865
|
.wd-root .shadow-\[inset_0_2px_0_0_var\(--color-accent\)\] {
|
|
1794
1866
|
--tw-shadow: inset 0 2px 0 0 var(--tw-shadow-color, var(--color-accent));
|
|
1795
1867
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
@@ -1810,16 +1882,39 @@
|
|
|
1810
1882
|
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
1811
1883
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1812
1884
|
}
|
|
1885
|
+
.wd-root .ring-1 {
|
|
1886
|
+
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
1887
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1888
|
+
}
|
|
1813
1889
|
.wd-root .ring-2 {
|
|
1814
1890
|
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
1815
1891
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
1816
1892
|
}
|
|
1893
|
+
.wd-root .ring-accent {
|
|
1894
|
+
--tw-ring-color: var(--accent);
|
|
1895
|
+
}
|
|
1896
|
+
.wd-root .ring-danger\/60 {
|
|
1897
|
+
--tw-ring-color: var(--danger);
|
|
1898
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1899
|
+
--tw-ring-color: color-mix(in oklab, var(--danger) 60%, transparent);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
.wd-root .ring-fg-3 {
|
|
1903
|
+
--tw-ring-color: var(--fg-3);
|
|
1904
|
+
}
|
|
1817
1905
|
.wd-root .ring-ring\/30 {
|
|
1818
1906
|
--tw-ring-color: var(--ring);
|
|
1819
1907
|
@supports (color: color-mix(in lab, red, red)) {
|
|
1820
1908
|
--tw-ring-color: color-mix(in oklab, var(--ring) 30%, transparent);
|
|
1821
1909
|
}
|
|
1822
1910
|
}
|
|
1911
|
+
.wd-root .ring-offset-1 {
|
|
1912
|
+
--tw-ring-offset-width: 1px;
|
|
1913
|
+
--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1914
|
+
}
|
|
1915
|
+
.wd-root .ring-offset-surface {
|
|
1916
|
+
--tw-ring-offset-color: var(--surface);
|
|
1917
|
+
}
|
|
1823
1918
|
.wd-root .outline {
|
|
1824
1919
|
outline-style: var(--tw-outline-style);
|
|
1825
1920
|
outline-width: 1px;
|
|
@@ -1828,6 +1923,10 @@
|
|
|
1828
1923
|
--tw-blur: blur(8px);
|
|
1829
1924
|
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
|
1830
1925
|
}
|
|
1926
|
+
.wd-root .grayscale {
|
|
1927
|
+
--tw-grayscale: grayscale(100%);
|
|
1928
|
+
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
|
|
1929
|
+
}
|
|
1831
1930
|
.wd-root .backdrop-blur-\[1px\] {
|
|
1832
1931
|
--tw-backdrop-blur: blur(1px);
|
|
1833
1932
|
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
|
@@ -1906,6 +2005,12 @@
|
|
|
1906
2005
|
.wd-root .\[counter-reset\:line\] {
|
|
1907
2006
|
counter-reset: line;
|
|
1908
2007
|
}
|
|
2008
|
+
.wd-root .\[image-rendering\:pixelated\] {
|
|
2009
|
+
image-rendering: pixelated;
|
|
2010
|
+
}
|
|
2011
|
+
.wd-root .ring-inset {
|
|
2012
|
+
--tw-ring-inset: inset;
|
|
2013
|
+
}
|
|
1909
2014
|
@media (hover: hover) {
|
|
1910
2015
|
.wd-root .group-hover\:block:is(:where(.group):hover *) {
|
|
1911
2016
|
display: block;
|
|
@@ -2074,6 +2179,13 @@
|
|
|
2074
2179
|
.wd-root .hover\:opacity-100:hover {
|
|
2075
2180
|
opacity: 100%;
|
|
2076
2181
|
}
|
|
2182
|
+
.wd-root .hover\:ring-1:hover {
|
|
2183
|
+
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
2184
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
2185
|
+
}
|
|
2186
|
+
.wd-root .hover\:ring-border:hover {
|
|
2187
|
+
--tw-ring-color: var(--border);
|
|
2188
|
+
}
|
|
2077
2189
|
}
|
|
2078
2190
|
.wd-root .focus-visible\:border-ring:focus-visible {
|
|
2079
2191
|
border-color: var(--ring);
|
|
@@ -3141,6 +3253,7 @@
|
|
|
3141
3253
|
--row-active: rgb(0 0 0 / 0.08);
|
|
3142
3254
|
--row-selected: #cfe4f7;
|
|
3143
3255
|
--row-selected-weak: #e4e6f1;
|
|
3256
|
+
--row-attention: #fbdcb8;
|
|
3144
3257
|
--badge: #c4c4c4;
|
|
3145
3258
|
--badge-fg: #333333;
|
|
3146
3259
|
--border: #ebebeb;
|
|
@@ -3194,6 +3307,7 @@
|
|
|
3194
3307
|
--row-active: rgb(255 255 255 / 0.1);
|
|
3195
3308
|
--row-selected: #04395e;
|
|
3196
3309
|
--row-selected-weak: #37373d;
|
|
3310
|
+
--row-attention: #5c3906;
|
|
3197
3311
|
--badge: #616161;
|
|
3198
3312
|
--badge-fg: #cccccc;
|
|
3199
3313
|
--border: #1f1f1f;
|
|
@@ -3424,6 +3538,23 @@
|
|
|
3424
3538
|
opacity: 0;
|
|
3425
3539
|
animation: wd-hold-appear 150ms ease-out 600ms forwards;
|
|
3426
3540
|
}
|
|
3541
|
+
@keyframes wd-avatar-strip {
|
|
3542
|
+
to {
|
|
3543
|
+
background-position-x: var(--wd-strip-end);
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
.wd-root .wd-avatar-strip {
|
|
3547
|
+
image-rendering: pixelated;
|
|
3548
|
+
background-repeat: no-repeat;
|
|
3549
|
+
animation-name: wd-avatar-strip;
|
|
3550
|
+
animation-timing-function: steps(var(--wd-strip-steps));
|
|
3551
|
+
animation-iteration-count: infinite;
|
|
3552
|
+
}
|
|
3553
|
+
@media (prefers-reduced-motion: reduce) {
|
|
3554
|
+
.wd-root .wd-avatar-strip {
|
|
3555
|
+
animation: none;
|
|
3556
|
+
}
|
|
3557
|
+
}
|
|
3427
3558
|
@keyframes prompt-area-chip-ripple {
|
|
3428
3559
|
0% {
|
|
3429
3560
|
transform: scale(0);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@workerdeck/ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Styled agent-control component library for WorkerDeck: session panel, transcript with streaming, tool-call cards, permission prompts, session list, composer. Tailwind v4 + Base UI + cva. Pairs with the headless @workerdeck/react layer.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"streamdown": "^2.6.0",
|
|
40
40
|
"tailwind-merge": "^3.7.0",
|
|
41
41
|
"use-stick-to-bottom": "^1.1.6",
|
|
42
|
-
"@workerdeck/client": "3.
|
|
43
|
-
"@workerdeck/react": "3.
|
|
44
|
-
"@workerdeck/protocol": "3.
|
|
42
|
+
"@workerdeck/client": "3.6.1",
|
|
43
|
+
"@workerdeck/react": "3.6.1",
|
|
44
|
+
"@workerdeck/protocol": "3.6.1"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"monaco-editor": "^0.56.0",
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { CSSProperties } from 'react'
|
|
2
|
+
import type { AgentRef, SessionRow, SessionState } from '@workerdeck/protocol'
|
|
3
|
+
import { EngineIcon, vendorMarkClass } from './EngineIcon.tsx'
|
|
4
|
+
import { SessionStatusIcon } from './SessionStatusIcon.tsx'
|
|
5
|
+
import { cn } from '../../lib/utils.ts'
|
|
6
|
+
|
|
7
|
+
export type AgentAvatarImage = { still: string; busy?: { src: string; durations: number[] } }
|
|
8
|
+
|
|
9
|
+
// Keyed by `AgentRef.avatar`, the gateway path: the host fetches with its own credentials and hands over data URLs.
|
|
10
|
+
export type AgentAvatars = Record<string, AgentAvatarImage>
|
|
11
|
+
|
|
12
|
+
export function avatarOf(avatars: AgentAvatars | undefined, agent: AgentRef | undefined): AgentAvatarImage | undefined {
|
|
13
|
+
return agent?.avatar === undefined ? undefined : avatars?.[agent.avatar]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface AgentAvatarProps {
|
|
17
|
+
row: SessionRow
|
|
18
|
+
image?: AgentAvatarImage
|
|
19
|
+
size?: number
|
|
20
|
+
// The state the corner badge draws; a folded lead passes its team's most urgent one.
|
|
21
|
+
state?: SessionState
|
|
22
|
+
badge?: boolean
|
|
23
|
+
className?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function AgentAvatar({ row, image, size = 32, state, badge = true, className }: AgentAvatarProps) {
|
|
27
|
+
const { info } = row
|
|
28
|
+
const shown = state ?? row.state
|
|
29
|
+
const busy = shown === 'working' && image?.busy && image.busy.durations.length > 1 ? image.busy : undefined
|
|
30
|
+
const asleep = info.engineAsleep === true
|
|
31
|
+
const engine = info.engine ?? 'claude'
|
|
32
|
+
const badgeSize = size >= 28 ? 14 : 11
|
|
33
|
+
return (
|
|
34
|
+
<span
|
|
35
|
+
data-slot="agent-avatar"
|
|
36
|
+
className={cn('relative inline-flex shrink-0', className)}
|
|
37
|
+
style={{ width: size, height: size }}
|
|
38
|
+
title={info.agent?.name}
|
|
39
|
+
>
|
|
40
|
+
{busy ? (
|
|
41
|
+
<span
|
|
42
|
+
aria-hidden
|
|
43
|
+
className="wd-avatar-strip size-full rounded-[4px]"
|
|
44
|
+
style={
|
|
45
|
+
{
|
|
46
|
+
backgroundImage: `url(${busy.src})`,
|
|
47
|
+
backgroundSize: `${busy.durations.length * size}px ${size}px`,
|
|
48
|
+
'--wd-strip-end': `-${busy.durations.length * size}px`,
|
|
49
|
+
'--wd-strip-steps': busy.durations.length,
|
|
50
|
+
animationDuration: `${busy.durations.reduce((sum, ms) => sum + ms, 0)}ms`,
|
|
51
|
+
} as CSSProperties
|
|
52
|
+
}
|
|
53
|
+
/>
|
|
54
|
+
) : image ? (
|
|
55
|
+
<img
|
|
56
|
+
src={image.still}
|
|
57
|
+
alt=""
|
|
58
|
+
draggable={false}
|
|
59
|
+
className={cn('size-full rounded-[4px] [image-rendering:pixelated]', asleep && 'opacity-60 grayscale')}
|
|
60
|
+
/>
|
|
61
|
+
) : (
|
|
62
|
+
<span className="flex size-full items-center justify-center rounded-[4px] border border-dashed border-border">
|
|
63
|
+
<EngineIcon engine={engine} model={info.model} className={cn('size-1/2', vendorMarkClass(engine, info.model))} />
|
|
64
|
+
</span>
|
|
65
|
+
)}
|
|
66
|
+
{badge && (shown !== 'idle' || asleep) ? (
|
|
67
|
+
<span
|
|
68
|
+
className="absolute -right-1 -bottom-1 flex items-center justify-center rounded-full bg-bg"
|
|
69
|
+
style={{ width: badgeSize, height: badgeSize }}
|
|
70
|
+
>
|
|
71
|
+
<SessionStatusIcon row={{ ...row, state: shown }} className="size-full p-px" />
|
|
72
|
+
</span>
|
|
73
|
+
) : null}
|
|
74
|
+
</span>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function LeadChip({ className }: { className?: string }) {
|
|
79
|
+
return (
|
|
80
|
+
<span
|
|
81
|
+
className={cn(
|
|
82
|
+
'shrink-0 rounded-[3px] border border-accent/50 px-1 text-[0.625rem] leading-3.5 font-medium tracking-wide text-accent',
|
|
83
|
+
className,
|
|
84
|
+
)}
|
|
85
|
+
>
|
|
86
|
+
LEAD
|
|
87
|
+
</span>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface AgentHeadingProps {
|
|
92
|
+
row: SessionRow
|
|
93
|
+
image?: AgentAvatarImage
|
|
94
|
+
// Overrides `AgentRef.conversation`, which a gateway sends from the second conversation on.
|
|
95
|
+
conversation?: number
|
|
96
|
+
className?: string
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// A session panel's title for an agent: avatar, name, its place in a team. Plain sessions keep the host's own title.
|
|
100
|
+
export function AgentHeading({ row, image, conversation, className }: AgentHeadingProps) {
|
|
101
|
+
const agent = row.info.agent
|
|
102
|
+
if (!agent) {
|
|
103
|
+
return null
|
|
104
|
+
}
|
|
105
|
+
const n = conversation ?? agent.conversation ?? 1
|
|
106
|
+
const detail = [agent.lead !== undefined && agent.team ? `${agent.team} team` : undefined, `conversation ${n}`]
|
|
107
|
+
.filter(Boolean)
|
|
108
|
+
.join(' · ')
|
|
109
|
+
return (
|
|
110
|
+
<span data-slot="agent-heading" className={cn('flex min-w-0 items-center gap-2', className)}>
|
|
111
|
+
<AgentAvatar row={row} image={image} size={24} />
|
|
112
|
+
<span className="truncate text-body-sm font-medium text-fg-1">{agent.name}</span>
|
|
113
|
+
{agent.leads ? <LeadChip /> : null}
|
|
114
|
+
{detail ? <span className="shrink-0 text-label text-fg-4">{detail}</span> : null}
|
|
115
|
+
</span>
|
|
116
|
+
)
|
|
117
|
+
}
|