@poncho-ai/cli 0.13.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +6 -6
- package/CHANGELOG.md +42 -0
- package/dist/{chunk-CUCEDHME.js → chunk-AIEVSNGF.js} +1994 -467
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/{run-interactive-ink-VZBOYJYS.js → run-interactive-ink-7ULE5JJI.js} +151 -118
- package/package.json +4 -4
- package/src/api-docs.ts +674 -0
- package/src/index.ts +632 -229
- package/src/init-onboarding.ts +14 -1
- package/src/run-interactive-ink.ts +171 -147
- package/src/web-ui.ts +760 -244
package/src/web-ui.ts
CHANGED
|
@@ -429,7 +429,8 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
429
429
|
<head>
|
|
430
430
|
<meta charset="utf-8">
|
|
431
431
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover">
|
|
432
|
-
<meta name="theme-color" content="#000000">
|
|
432
|
+
<meta name="theme-color" content="#000000" media="(prefers-color-scheme: dark)">
|
|
433
|
+
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
|
|
433
434
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
434
435
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
435
436
|
<meta name="apple-mobile-web-app-title" content="${agentName}">
|
|
@@ -439,12 +440,172 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
439
440
|
<title>${agentName}</title>
|
|
440
441
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inconsolata:400,700">
|
|
441
442
|
<style>
|
|
443
|
+
:root {
|
|
444
|
+
color-scheme: light dark;
|
|
445
|
+
|
|
446
|
+
--bg: #000;
|
|
447
|
+
--bg-alt: #0a0a0a;
|
|
448
|
+
--bg-elevated: #111;
|
|
449
|
+
|
|
450
|
+
--fg: #ededed;
|
|
451
|
+
--fg-strong: #fff;
|
|
452
|
+
--fg-2: #888;
|
|
453
|
+
--fg-3: #999;
|
|
454
|
+
--fg-4: #777;
|
|
455
|
+
--fg-5: #666;
|
|
456
|
+
--fg-6: #555;
|
|
457
|
+
--fg-7: #444;
|
|
458
|
+
--fg-8: #333;
|
|
459
|
+
|
|
460
|
+
--fg-tool: #8a8a8a;
|
|
461
|
+
--fg-tool-code: #bcbcbc;
|
|
462
|
+
--fg-tool-item: #d6d6d6;
|
|
463
|
+
--fg-approval-label: #b0b0b0;
|
|
464
|
+
--fg-approval-input: #cfcfcf;
|
|
465
|
+
--fg-approval-btn: #f0f0f0;
|
|
466
|
+
|
|
467
|
+
--accent: #ededed;
|
|
468
|
+
--accent-fg: #000;
|
|
469
|
+
--accent-hover: #fff;
|
|
470
|
+
|
|
471
|
+
--stop-bg: #4a4a4a;
|
|
472
|
+
--stop-fg: #fff;
|
|
473
|
+
--stop-hover: #565656;
|
|
474
|
+
|
|
475
|
+
--border-1: rgba(255,255,255,0.06);
|
|
476
|
+
--border-2: rgba(255,255,255,0.08);
|
|
477
|
+
--border-3: rgba(255,255,255,0.1);
|
|
478
|
+
--border-4: rgba(255,255,255,0.12);
|
|
479
|
+
--border-5: rgba(255,255,255,0.18);
|
|
480
|
+
--border-focus: rgba(255,255,255,0.2);
|
|
481
|
+
--border-hover: rgba(255,255,255,0.25);
|
|
482
|
+
--border-drag: rgba(255,255,255,0.4);
|
|
483
|
+
|
|
484
|
+
--surface-1: rgba(255,255,255,0.02);
|
|
485
|
+
--surface-2: rgba(255,255,255,0.03);
|
|
486
|
+
--surface-3: rgba(255,255,255,0.04);
|
|
487
|
+
--surface-4: rgba(255,255,255,0.06);
|
|
488
|
+
--surface-5: rgba(255,255,255,0.08);
|
|
489
|
+
--surface-6: rgba(255,255,255,0.1);
|
|
490
|
+
--surface-7: rgba(255,255,255,0.12);
|
|
491
|
+
--surface-8: rgba(255,255,255,0.14);
|
|
492
|
+
|
|
493
|
+
--chip-bg: rgba(0,0,0,0.6);
|
|
494
|
+
--chip-bg-hover: rgba(0,0,0,0.75);
|
|
495
|
+
--backdrop: rgba(0,0,0,0.6);
|
|
496
|
+
--lightbox-bg: rgba(0,0,0,0.85);
|
|
497
|
+
--inset-1: rgba(0,0,0,0.16);
|
|
498
|
+
--inset-2: rgba(0,0,0,0.25);
|
|
499
|
+
|
|
500
|
+
--file-badge-bg: rgba(0,0,0,0.2);
|
|
501
|
+
--file-badge-fg: rgba(255,255,255,0.8);
|
|
502
|
+
|
|
503
|
+
--error: #ff4444;
|
|
504
|
+
--error-soft: #ff6b6b;
|
|
505
|
+
--error-alt: #ff6666;
|
|
506
|
+
--error-bg: rgba(255,68,68,0.08);
|
|
507
|
+
--error-border: rgba(255,68,68,0.25);
|
|
508
|
+
|
|
509
|
+
--tool-done: #6a9955;
|
|
510
|
+
--tool-error: #f48771;
|
|
511
|
+
|
|
512
|
+
--warning: #e8a735;
|
|
513
|
+
|
|
514
|
+
--approve: #78e7a6;
|
|
515
|
+
--approve-border: rgba(58,208,122,0.45);
|
|
516
|
+
--deny: #f59b9b;
|
|
517
|
+
--deny-border: rgba(224,95,95,0.45);
|
|
518
|
+
|
|
519
|
+
--scrollbar: rgba(255,255,255,0.1);
|
|
520
|
+
--scrollbar-hover: rgba(255,255,255,0.16);
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
@media (prefers-color-scheme: light) {
|
|
524
|
+
:root {
|
|
525
|
+
--bg: #ffffff;
|
|
526
|
+
--bg-alt: #f5f5f5;
|
|
527
|
+
--bg-elevated: #e8e8e8;
|
|
528
|
+
|
|
529
|
+
--fg: #1a1a1a;
|
|
530
|
+
--fg-strong: #000;
|
|
531
|
+
--fg-2: #666;
|
|
532
|
+
--fg-3: #555;
|
|
533
|
+
--fg-4: #777;
|
|
534
|
+
--fg-5: #888;
|
|
535
|
+
--fg-6: #888;
|
|
536
|
+
--fg-7: #aaa;
|
|
537
|
+
--fg-8: #bbb;
|
|
538
|
+
|
|
539
|
+
--fg-tool: #666;
|
|
540
|
+
--fg-tool-code: #444;
|
|
541
|
+
--fg-tool-item: #333;
|
|
542
|
+
--fg-approval-label: #666;
|
|
543
|
+
--fg-approval-input: #444;
|
|
544
|
+
--fg-approval-btn: #1a1a1a;
|
|
545
|
+
|
|
546
|
+
--accent: #1a1a1a;
|
|
547
|
+
--accent-fg: #fff;
|
|
548
|
+
--accent-hover: #000;
|
|
549
|
+
|
|
550
|
+
--stop-bg: #d4d4d4;
|
|
551
|
+
--stop-fg: #333;
|
|
552
|
+
--stop-hover: #c4c4c4;
|
|
553
|
+
|
|
554
|
+
--border-1: rgba(0,0,0,0.06);
|
|
555
|
+
--border-2: rgba(0,0,0,0.08);
|
|
556
|
+
--border-3: rgba(0,0,0,0.1);
|
|
557
|
+
--border-4: rgba(0,0,0,0.1);
|
|
558
|
+
--border-5: rgba(0,0,0,0.15);
|
|
559
|
+
--border-focus: rgba(0,0,0,0.2);
|
|
560
|
+
--border-hover: rgba(0,0,0,0.2);
|
|
561
|
+
--border-drag: rgba(0,0,0,0.3);
|
|
562
|
+
|
|
563
|
+
--surface-1: rgba(0,0,0,0.02);
|
|
564
|
+
--surface-2: rgba(0,0,0,0.03);
|
|
565
|
+
--surface-3: rgba(0,0,0,0.03);
|
|
566
|
+
--surface-4: rgba(0,0,0,0.04);
|
|
567
|
+
--surface-5: rgba(0,0,0,0.05);
|
|
568
|
+
--surface-6: rgba(0,0,0,0.07);
|
|
569
|
+
--surface-7: rgba(0,0,0,0.08);
|
|
570
|
+
--surface-8: rgba(0,0,0,0.1);
|
|
571
|
+
|
|
572
|
+
--chip-bg: rgba(255,255,255,0.8);
|
|
573
|
+
--chip-bg-hover: rgba(255,255,255,0.9);
|
|
574
|
+
--backdrop: rgba(0,0,0,0.3);
|
|
575
|
+
--lightbox-bg: rgba(0,0,0,0.75);
|
|
576
|
+
--inset-1: rgba(0,0,0,0.04);
|
|
577
|
+
--inset-2: rgba(0,0,0,0.06);
|
|
578
|
+
|
|
579
|
+
--file-badge-bg: rgba(0,0,0,0.05);
|
|
580
|
+
--file-badge-fg: rgba(0,0,0,0.7);
|
|
581
|
+
|
|
582
|
+
--error: #dc2626;
|
|
583
|
+
--error-soft: #ef4444;
|
|
584
|
+
--error-alt: #ef4444;
|
|
585
|
+
--error-bg: rgba(220,38,38,0.06);
|
|
586
|
+
--error-border: rgba(220,38,38,0.2);
|
|
587
|
+
|
|
588
|
+
--tool-done: #16a34a;
|
|
589
|
+
--tool-error: #dc2626;
|
|
590
|
+
|
|
591
|
+
--warning: #ca8a04;
|
|
592
|
+
|
|
593
|
+
--approve: #16a34a;
|
|
594
|
+
--approve-border: rgba(22,163,74,0.35);
|
|
595
|
+
--deny: #dc2626;
|
|
596
|
+
--deny-border: rgba(220,38,38,0.3);
|
|
597
|
+
|
|
598
|
+
--scrollbar: rgba(0,0,0,0.12);
|
|
599
|
+
--scrollbar-hover: rgba(0,0,0,0.2);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
442
603
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
443
604
|
html, body { height: 100vh; overflow: hidden; overscroll-behavior: none; touch-action: pan-y; }
|
|
444
605
|
body {
|
|
445
606
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Helvetica Neue", sans-serif;
|
|
446
|
-
background:
|
|
447
|
-
color:
|
|
607
|
+
background: var(--bg);
|
|
608
|
+
color: var(--fg);
|
|
448
609
|
font-size: 14px;
|
|
449
610
|
line-height: 1.5;
|
|
450
611
|
-webkit-font-smoothing: antialiased;
|
|
@@ -452,7 +613,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
452
613
|
}
|
|
453
614
|
button, input, textarea { font: inherit; color: inherit; }
|
|
454
615
|
.hidden { display: none !important; }
|
|
455
|
-
a { color:
|
|
616
|
+
a { color: var(--fg); }
|
|
456
617
|
|
|
457
618
|
/* Auth */
|
|
458
619
|
.auth {
|
|
@@ -460,39 +621,39 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
460
621
|
display: grid;
|
|
461
622
|
place-items: center;
|
|
462
623
|
padding: 20px;
|
|
463
|
-
background:
|
|
624
|
+
background: var(--bg);
|
|
464
625
|
}
|
|
465
626
|
.auth-card {
|
|
466
627
|
width: min(400px, 90vw);
|
|
467
628
|
}
|
|
468
629
|
.auth-shell {
|
|
469
|
-
background:
|
|
470
|
-
border: 1px solid
|
|
630
|
+
background: var(--bg-alt);
|
|
631
|
+
border: 1px solid var(--border-3);
|
|
471
632
|
border-radius: 9999px;
|
|
472
633
|
display: flex;
|
|
473
634
|
align-items: center;
|
|
474
635
|
padding: 4px 6px 4px 18px;
|
|
475
636
|
transition: border-color 0.15s;
|
|
476
637
|
}
|
|
477
|
-
.auth-shell:focus-within { border-color:
|
|
638
|
+
.auth-shell:focus-within { border-color: var(--border-focus); }
|
|
478
639
|
.auth-input {
|
|
479
640
|
flex: 1;
|
|
480
641
|
background: transparent;
|
|
481
642
|
border: 0;
|
|
482
643
|
outline: none;
|
|
483
|
-
color:
|
|
644
|
+
color: var(--fg);
|
|
484
645
|
padding: 10px 0 8px;
|
|
485
646
|
font-size: 14px;
|
|
486
647
|
margin-top: -2px;
|
|
487
648
|
}
|
|
488
|
-
.auth-input::placeholder { color:
|
|
649
|
+
.auth-input::placeholder { color: var(--fg-7); }
|
|
489
650
|
.auth-submit {
|
|
490
651
|
width: 32px;
|
|
491
652
|
height: 32px;
|
|
492
|
-
background:
|
|
653
|
+
background: var(--accent);
|
|
493
654
|
border: 0;
|
|
494
655
|
border-radius: 50%;
|
|
495
|
-
color:
|
|
656
|
+
color: var(--accent-fg);
|
|
496
657
|
cursor: pointer;
|
|
497
658
|
display: grid;
|
|
498
659
|
place-items: center;
|
|
@@ -500,19 +661,19 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
500
661
|
margin-bottom: 2px;
|
|
501
662
|
transition: background 0.15s;
|
|
502
663
|
}
|
|
503
|
-
.auth-submit:hover { background:
|
|
504
|
-
.error { color:
|
|
664
|
+
.auth-submit:hover { background: var(--accent-hover); }
|
|
665
|
+
.error { color: var(--error); font-size: 13px; min-height: 16px; }
|
|
505
666
|
.message-error {
|
|
506
|
-
background:
|
|
507
|
-
border: 1px solid
|
|
667
|
+
background: var(--error-bg);
|
|
668
|
+
border: 1px solid var(--error-border);
|
|
508
669
|
border-radius: 10px;
|
|
509
|
-
color:
|
|
670
|
+
color: var(--error-soft);
|
|
510
671
|
padding: 12px 16px;
|
|
511
672
|
font-size: 13px;
|
|
512
673
|
line-height: 1.5;
|
|
513
674
|
max-width: 600px;
|
|
514
675
|
}
|
|
515
|
-
.message-error strong { color:
|
|
676
|
+
.message-error strong { color: var(--error); }
|
|
516
677
|
|
|
517
678
|
/* Layout - use fixed positioning with explicit dimensions */
|
|
518
679
|
.shell {
|
|
@@ -544,8 +705,8 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
544
705
|
}
|
|
545
706
|
.sidebar {
|
|
546
707
|
width: 260px;
|
|
547
|
-
background:
|
|
548
|
-
border-right: 1px solid
|
|
708
|
+
background: var(--bg);
|
|
709
|
+
border-right: 1px solid var(--border-1);
|
|
549
710
|
display: flex;
|
|
550
711
|
flex-direction: column;
|
|
551
712
|
padding: 12px 8px;
|
|
@@ -553,7 +714,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
553
714
|
.new-chat-btn {
|
|
554
715
|
background: transparent;
|
|
555
716
|
border: 0;
|
|
556
|
-
color:
|
|
717
|
+
color: var(--fg-2);
|
|
557
718
|
border-radius: 12px;
|
|
558
719
|
height: 36px;
|
|
559
720
|
padding: 0 10px;
|
|
@@ -564,7 +725,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
564
725
|
cursor: pointer;
|
|
565
726
|
transition: background 0.15s, color 0.15s;
|
|
566
727
|
}
|
|
567
|
-
.new-chat-btn:hover { color:
|
|
728
|
+
.new-chat-btn:hover { color: var(--fg); }
|
|
568
729
|
.new-chat-btn svg { width: 16px; height: 16px; }
|
|
569
730
|
.conversation-list {
|
|
570
731
|
flex: 1;
|
|
@@ -574,6 +735,20 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
574
735
|
flex-direction: column;
|
|
575
736
|
gap: 2px;
|
|
576
737
|
}
|
|
738
|
+
.sidebar-section-label {
|
|
739
|
+
font-size: 11px;
|
|
740
|
+
font-weight: 600;
|
|
741
|
+
color: var(--fg-7);
|
|
742
|
+
text-transform: uppercase;
|
|
743
|
+
letter-spacing: 0.04em;
|
|
744
|
+
padding: 10px 10px 4px;
|
|
745
|
+
}
|
|
746
|
+
.sidebar-section-label:first-child { padding-top: 4px; }
|
|
747
|
+
.sidebar-section-divider {
|
|
748
|
+
height: 1px;
|
|
749
|
+
background: var(--border);
|
|
750
|
+
margin: 6px 10px;
|
|
751
|
+
}
|
|
577
752
|
.conversation-item {
|
|
578
753
|
height: 36px;
|
|
579
754
|
min-height: 36px;
|
|
@@ -584,16 +759,26 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
584
759
|
cursor: pointer;
|
|
585
760
|
font-size: 13px;
|
|
586
761
|
line-height: 36px;
|
|
587
|
-
color:
|
|
762
|
+
color: var(--fg-6);
|
|
588
763
|
white-space: nowrap;
|
|
589
764
|
overflow: hidden;
|
|
590
765
|
text-overflow: ellipsis;
|
|
591
766
|
position: relative;
|
|
592
767
|
transition: color 0.15s;
|
|
593
768
|
}
|
|
594
|
-
.conversation-item
|
|
769
|
+
.conversation-item .approval-dot {
|
|
770
|
+
display: inline-block;
|
|
771
|
+
width: 6px;
|
|
772
|
+
height: 6px;
|
|
773
|
+
border-radius: 50%;
|
|
774
|
+
background: var(--warning, #e8a735);
|
|
775
|
+
margin-right: 6px;
|
|
776
|
+
flex-shrink: 0;
|
|
777
|
+
vertical-align: middle;
|
|
778
|
+
}
|
|
779
|
+
.conversation-item:hover { color: var(--fg-3); }
|
|
595
780
|
.conversation-item.active {
|
|
596
|
-
color:
|
|
781
|
+
color: var(--fg);
|
|
597
782
|
}
|
|
598
783
|
.conversation-item .delete-btn {
|
|
599
784
|
position: absolute;
|
|
@@ -601,9 +786,9 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
601
786
|
top: 0;
|
|
602
787
|
bottom: 0;
|
|
603
788
|
opacity: 0;
|
|
604
|
-
background:
|
|
789
|
+
background: var(--bg);
|
|
605
790
|
border: 0;
|
|
606
|
-
color:
|
|
791
|
+
color: var(--fg-7);
|
|
607
792
|
padding: 0 8px;
|
|
608
793
|
border-radius: 0 4px 4px 0;
|
|
609
794
|
cursor: pointer;
|
|
@@ -614,7 +799,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
614
799
|
transition: opacity 0.15s, color 0.15s;
|
|
615
800
|
}
|
|
616
801
|
.conversation-item:hover .delete-btn { opacity: 1; }
|
|
617
|
-
.conversation-item.active .delete-btn { background:
|
|
802
|
+
.conversation-item.active .delete-btn { background: var(--bg); }
|
|
618
803
|
.conversation-item .delete-btn::before {
|
|
619
804
|
content: "";
|
|
620
805
|
position: absolute;
|
|
@@ -622,23 +807,23 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
622
807
|
top: 0;
|
|
623
808
|
bottom: 0;
|
|
624
809
|
width: 24px;
|
|
625
|
-
background: linear-gradient(to right, transparent,
|
|
810
|
+
background: linear-gradient(to right, transparent, var(--bg));
|
|
626
811
|
pointer-events: none;
|
|
627
812
|
}
|
|
628
813
|
.conversation-item.active .delete-btn::before {
|
|
629
|
-
background: linear-gradient(to right, transparent,
|
|
814
|
+
background: linear-gradient(to right, transparent, var(--bg));
|
|
630
815
|
}
|
|
631
|
-
.conversation-item .delete-btn:hover { color:
|
|
816
|
+
.conversation-item .delete-btn:hover { color: var(--fg-2); }
|
|
632
817
|
.conversation-item .delete-btn.confirming {
|
|
633
818
|
opacity: 1;
|
|
634
819
|
width: auto;
|
|
635
820
|
padding: 0 8px;
|
|
636
821
|
font-size: 11px;
|
|
637
|
-
color:
|
|
822
|
+
color: var(--error);
|
|
638
823
|
border-radius: 3px;
|
|
639
824
|
}
|
|
640
825
|
.conversation-item .delete-btn.confirming:hover {
|
|
641
|
-
color:
|
|
826
|
+
color: var(--error-alt);
|
|
642
827
|
}
|
|
643
828
|
.sidebar-footer {
|
|
644
829
|
margin-top: auto;
|
|
@@ -647,7 +832,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
647
832
|
.logout-btn {
|
|
648
833
|
background: transparent;
|
|
649
834
|
border: 0;
|
|
650
|
-
color:
|
|
835
|
+
color: var(--fg-6);
|
|
651
836
|
width: 100%;
|
|
652
837
|
padding: 8px 10px;
|
|
653
838
|
text-align: left;
|
|
@@ -656,10 +841,10 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
656
841
|
font-size: 13px;
|
|
657
842
|
transition: color 0.15s, background 0.15s;
|
|
658
843
|
}
|
|
659
|
-
.logout-btn:hover { color:
|
|
844
|
+
.logout-btn:hover { color: var(--fg-2); }
|
|
660
845
|
|
|
661
846
|
/* Main */
|
|
662
|
-
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; max-width: 100%; background:
|
|
847
|
+
.main { flex: 1; display: flex; flex-direction: column; min-width: 0; max-width: 100%; background: var(--bg); overflow: hidden; }
|
|
663
848
|
.topbar {
|
|
664
849
|
height: calc(52px + env(safe-area-inset-top, 0px));
|
|
665
850
|
padding-top: env(safe-area-inset-top, 0px);
|
|
@@ -668,8 +853,8 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
668
853
|
justify-content: center;
|
|
669
854
|
font-size: 13px;
|
|
670
855
|
font-weight: 500;
|
|
671
|
-
color:
|
|
672
|
-
border-bottom: 1px solid
|
|
856
|
+
color: var(--fg-2);
|
|
857
|
+
border-bottom: 1px solid var(--border-1);
|
|
673
858
|
position: relative;
|
|
674
859
|
flex-shrink: 0;
|
|
675
860
|
}
|
|
@@ -688,7 +873,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
688
873
|
bottom: 4px; /* Position from bottom of topbar content area */
|
|
689
874
|
background: transparent;
|
|
690
875
|
border: 0;
|
|
691
|
-
color:
|
|
876
|
+
color: var(--fg-5);
|
|
692
877
|
width: 44px;
|
|
693
878
|
height: 44px;
|
|
694
879
|
border-radius: 6px;
|
|
@@ -698,7 +883,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
698
883
|
z-index: 10;
|
|
699
884
|
-webkit-tap-highlight-color: transparent;
|
|
700
885
|
}
|
|
701
|
-
.sidebar-toggle:hover { color:
|
|
886
|
+
.sidebar-toggle:hover { color: var(--fg); }
|
|
702
887
|
.topbar-new-chat {
|
|
703
888
|
display: none;
|
|
704
889
|
position: absolute;
|
|
@@ -706,7 +891,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
706
891
|
bottom: 4px;
|
|
707
892
|
background: transparent;
|
|
708
893
|
border: 0;
|
|
709
|
-
color:
|
|
894
|
+
color: var(--fg-5);
|
|
710
895
|
width: 44px;
|
|
711
896
|
height: 44px;
|
|
712
897
|
border-radius: 6px;
|
|
@@ -715,7 +900,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
715
900
|
z-index: 10;
|
|
716
901
|
-webkit-tap-highlight-color: transparent;
|
|
717
902
|
}
|
|
718
|
-
.topbar-new-chat:hover { color:
|
|
903
|
+
.topbar-new-chat:hover { color: var(--fg); }
|
|
719
904
|
.topbar-new-chat svg { width: 16px; height: 16px; }
|
|
720
905
|
|
|
721
906
|
/* Messages */
|
|
@@ -727,8 +912,8 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
727
912
|
.assistant-avatar {
|
|
728
913
|
width: 24px;
|
|
729
914
|
height: 24px;
|
|
730
|
-
background:
|
|
731
|
-
color:
|
|
915
|
+
background: var(--accent);
|
|
916
|
+
color: var(--accent-fg);
|
|
732
917
|
border-radius: 6px;
|
|
733
918
|
display: grid;
|
|
734
919
|
place-items: center;
|
|
@@ -739,7 +924,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
739
924
|
}
|
|
740
925
|
.assistant-content {
|
|
741
926
|
line-height: 1.65;
|
|
742
|
-
color:
|
|
927
|
+
color: var(--fg);
|
|
743
928
|
font-size: 14px;
|
|
744
929
|
min-width: 0;
|
|
745
930
|
max-width: 100%;
|
|
@@ -751,32 +936,32 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
751
936
|
.assistant-content p:last-child { margin-bottom: 0; }
|
|
752
937
|
.assistant-content ul, .assistant-content ol { margin: 8px 0; padding-left: 20px; }
|
|
753
938
|
.assistant-content li { margin: 4px 0; }
|
|
754
|
-
.assistant-content strong { font-weight: 600; color:
|
|
939
|
+
.assistant-content strong { font-weight: 600; color: var(--fg-strong); }
|
|
755
940
|
.assistant-content h2 {
|
|
756
941
|
font-size: 16px;
|
|
757
942
|
font-weight: 600;
|
|
758
943
|
letter-spacing: -0.02em;
|
|
759
944
|
margin: 20px 0 8px;
|
|
760
|
-
color:
|
|
945
|
+
color: var(--fg-strong);
|
|
761
946
|
}
|
|
762
947
|
.assistant-content h3 {
|
|
763
948
|
font-size: 14px;
|
|
764
949
|
font-weight: 600;
|
|
765
950
|
letter-spacing: -0.01em;
|
|
766
951
|
margin: 16px 0 6px;
|
|
767
|
-
color:
|
|
952
|
+
color: var(--fg-strong);
|
|
768
953
|
}
|
|
769
954
|
.assistant-content code {
|
|
770
|
-
background:
|
|
771
|
-
border: 1px solid
|
|
955
|
+
background: var(--surface-4);
|
|
956
|
+
border: 1px solid var(--border-1);
|
|
772
957
|
padding: 2px 5px;
|
|
773
958
|
border-radius: 4px;
|
|
774
959
|
font-family: ui-monospace, "SF Mono", "Fira Code", monospace;
|
|
775
960
|
font-size: 0.88em;
|
|
776
961
|
}
|
|
777
962
|
.assistant-content pre {
|
|
778
|
-
background:
|
|
779
|
-
border: 1px solid
|
|
963
|
+
background: var(--bg-alt);
|
|
964
|
+
border: 1px solid var(--border-1);
|
|
780
965
|
padding: 14px 16px;
|
|
781
966
|
border-radius: 8px;
|
|
782
967
|
overflow-x: auto;
|
|
@@ -793,33 +978,33 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
793
978
|
margin: 8px 0;
|
|
794
979
|
font-size: 12px;
|
|
795
980
|
line-height: 1.45;
|
|
796
|
-
color:
|
|
981
|
+
color: var(--fg-tool);
|
|
797
982
|
}
|
|
798
983
|
.tool-activity-inline code {
|
|
799
984
|
font-family: ui-monospace, "SF Mono", "Fira Code", monospace;
|
|
800
|
-
background:
|
|
801
|
-
border: 1px solid
|
|
985
|
+
background: var(--surface-3);
|
|
986
|
+
border: 1px solid var(--border-2);
|
|
802
987
|
padding: 4px 8px;
|
|
803
988
|
border-radius: 6px;
|
|
804
|
-
color:
|
|
989
|
+
color: var(--fg-tool-code);
|
|
805
990
|
font-size: 11px;
|
|
806
991
|
}
|
|
807
992
|
.tool-status {
|
|
808
|
-
color:
|
|
993
|
+
color: var(--fg-tool);
|
|
809
994
|
font-style: italic;
|
|
810
995
|
}
|
|
811
996
|
.tool-done {
|
|
812
|
-
color:
|
|
997
|
+
color: var(--tool-done);
|
|
813
998
|
}
|
|
814
999
|
.tool-error {
|
|
815
|
-
color:
|
|
1000
|
+
color: var(--tool-error);
|
|
816
1001
|
}
|
|
817
|
-
.assistant-content table {
|
|
1002
|
+
.assistant-content table:not(.approval-request-table) {
|
|
818
1003
|
border-collapse: collapse;
|
|
819
1004
|
width: 100%;
|
|
820
1005
|
margin: 14px 0;
|
|
821
1006
|
font-size: 13px;
|
|
822
|
-
border: 1px solid
|
|
1007
|
+
border: 1px solid var(--border-2);
|
|
823
1008
|
border-radius: 8px;
|
|
824
1009
|
overflow: hidden;
|
|
825
1010
|
display: block;
|
|
@@ -827,42 +1012,46 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
827
1012
|
overflow-x: auto;
|
|
828
1013
|
white-space: nowrap;
|
|
829
1014
|
}
|
|
830
|
-
.assistant-content th {
|
|
831
|
-
background:
|
|
1015
|
+
.assistant-content table:not(.approval-request-table) th {
|
|
1016
|
+
background: var(--surface-4);
|
|
832
1017
|
padding: 10px 12px;
|
|
833
1018
|
text-align: left;
|
|
834
1019
|
font-weight: 600;
|
|
835
|
-
border-bottom: 1px solid
|
|
836
|
-
color:
|
|
1020
|
+
border-bottom: 1px solid var(--border-4);
|
|
1021
|
+
color: var(--fg-strong);
|
|
837
1022
|
min-width: 100px;
|
|
838
1023
|
}
|
|
839
|
-
.assistant-content td {
|
|
1024
|
+
.assistant-content table:not(.approval-request-table) td {
|
|
840
1025
|
padding: 10px 12px;
|
|
841
|
-
border-bottom: 1px solid
|
|
1026
|
+
border-bottom: 1px solid var(--border-1);
|
|
842
1027
|
width: 100%;
|
|
843
1028
|
min-width: 100px;
|
|
844
1029
|
}
|
|
845
|
-
.assistant-content tr:last-child td {
|
|
1030
|
+
.assistant-content table:not(.approval-request-table) tr:last-child td {
|
|
846
1031
|
border-bottom: none;
|
|
847
1032
|
}
|
|
848
|
-
.assistant-content tbody tr:hover {
|
|
849
|
-
background:
|
|
1033
|
+
.assistant-content table:not(.approval-request-table) tbody tr:hover {
|
|
1034
|
+
background: var(--surface-1);
|
|
850
1035
|
}
|
|
851
1036
|
.assistant-content hr {
|
|
852
1037
|
border: 0;
|
|
853
|
-
border-top: 1px solid
|
|
1038
|
+
border-top: 1px solid var(--border-3);
|
|
854
1039
|
margin: 20px 0;
|
|
855
1040
|
}
|
|
856
1041
|
.tool-activity {
|
|
857
1042
|
margin-top: 12px;
|
|
858
1043
|
margin-bottom: 12px;
|
|
859
|
-
border: 1px solid
|
|
860
|
-
background:
|
|
1044
|
+
border: 1px solid var(--border-2);
|
|
1045
|
+
background: var(--surface-2);
|
|
861
1046
|
border-radius: 10px;
|
|
862
1047
|
font-size: 12px;
|
|
863
1048
|
line-height: 1.45;
|
|
864
|
-
color:
|
|
1049
|
+
color: var(--fg-tool-code);
|
|
865
1050
|
width: 300px;
|
|
1051
|
+
transition: width 0.2s ease;
|
|
1052
|
+
}
|
|
1053
|
+
.tool-activity.has-approvals {
|
|
1054
|
+
width: 100%;
|
|
866
1055
|
}
|
|
867
1056
|
.assistant-content > .tool-activity:first-child {
|
|
868
1057
|
margin-top: 0;
|
|
@@ -886,12 +1075,12 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
886
1075
|
font-size: 11px;
|
|
887
1076
|
text-transform: uppercase;
|
|
888
1077
|
letter-spacing: 0.06em;
|
|
889
|
-
color:
|
|
1078
|
+
color: var(--fg-tool);
|
|
890
1079
|
font-weight: 600;
|
|
891
1080
|
}
|
|
892
1081
|
.tool-activity-caret {
|
|
893
1082
|
margin-left: auto;
|
|
894
|
-
color:
|
|
1083
|
+
color: var(--fg-tool);
|
|
895
1084
|
display: inline-flex;
|
|
896
1085
|
align-items: center;
|
|
897
1086
|
justify-content: center;
|
|
@@ -913,49 +1102,69 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
913
1102
|
}
|
|
914
1103
|
.tool-activity-item {
|
|
915
1104
|
font-family: ui-monospace, "SF Mono", "Fira Code", monospace;
|
|
916
|
-
background:
|
|
1105
|
+
background: var(--surface-3);
|
|
917
1106
|
border-radius: 6px;
|
|
918
1107
|
padding: 4px 7px;
|
|
919
|
-
color:
|
|
1108
|
+
color: var(--fg-tool-item);
|
|
920
1109
|
}
|
|
921
1110
|
.approval-requests {
|
|
922
|
-
border-top: 1px solid
|
|
1111
|
+
border-top: 1px solid var(--border-2);
|
|
923
1112
|
padding: 10px 12px 12px;
|
|
924
1113
|
display: grid;
|
|
925
|
-
gap:
|
|
926
|
-
background: rgba(0,0,0,0.16);
|
|
1114
|
+
gap: 10px;
|
|
927
1115
|
}
|
|
928
1116
|
.approval-requests-label {
|
|
929
|
-
font-size:
|
|
1117
|
+
font-size: 12px;
|
|
930
1118
|
text-transform: uppercase;
|
|
931
1119
|
letter-spacing: 0.06em;
|
|
932
|
-
color:
|
|
1120
|
+
color: var(--fg-approval-label);
|
|
933
1121
|
font-weight: 600;
|
|
934
1122
|
}
|
|
1123
|
+
.approval-requests-label code {
|
|
1124
|
+
font-family: ui-monospace, "SF Mono", "Fira Code", monospace;
|
|
1125
|
+
text-transform: none;
|
|
1126
|
+
letter-spacing: 0;
|
|
1127
|
+
color: var(--fg-strong);
|
|
1128
|
+
}
|
|
935
1129
|
.approval-request-item {
|
|
936
|
-
border: 1px solid rgba(255,255,255,0.1);
|
|
937
|
-
background: rgba(255,255,255,0.03);
|
|
938
|
-
border-radius: 8px;
|
|
939
|
-
padding: 8px;
|
|
940
1130
|
display: grid;
|
|
941
|
-
gap:
|
|
1131
|
+
gap: 8px;
|
|
942
1132
|
}
|
|
943
|
-
.approval-request-
|
|
944
|
-
|
|
945
|
-
|
|
1133
|
+
.approval-request-table {
|
|
1134
|
+
width: 100%;
|
|
1135
|
+
border-collapse: collapse;
|
|
1136
|
+
border: none;
|
|
1137
|
+
font-size: 14px;
|
|
1138
|
+
line-height: 1.5;
|
|
1139
|
+
}
|
|
1140
|
+
.approval-request-table tr,
|
|
1141
|
+
.approval-request-table td {
|
|
1142
|
+
border: none;
|
|
1143
|
+
background: none;
|
|
1144
|
+
}
|
|
1145
|
+
.approval-request-table td {
|
|
1146
|
+
padding: 4px 0;
|
|
1147
|
+
vertical-align: top;
|
|
1148
|
+
}
|
|
1149
|
+
.approval-request-table .ak {
|
|
946
1150
|
font-weight: 600;
|
|
947
|
-
|
|
1151
|
+
color: var(--fg-approval-label);
|
|
1152
|
+
white-space: nowrap;
|
|
1153
|
+
width: 1%;
|
|
1154
|
+
padding-right: 20px;
|
|
948
1155
|
}
|
|
949
|
-
.approval-request-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
color: #cfcfcf;
|
|
953
|
-
background: rgba(0,0,0,0.25);
|
|
954
|
-
border-radius: 6px;
|
|
955
|
-
padding: 6px;
|
|
1156
|
+
.approval-request-table .av,
|
|
1157
|
+
.approval-request-table .av-complex {
|
|
1158
|
+
color: var(--fg);
|
|
956
1159
|
overflow-wrap: anywhere;
|
|
957
|
-
|
|
1160
|
+
white-space: pre-wrap;
|
|
1161
|
+
max-height: 200px;
|
|
958
1162
|
overflow-y: auto;
|
|
1163
|
+
display: block;
|
|
1164
|
+
}
|
|
1165
|
+
.approval-request-table .av-complex {
|
|
1166
|
+
font-family: ui-monospace, "SF Mono", "Fira Code", monospace;
|
|
1167
|
+
font-size: 12px;
|
|
959
1168
|
}
|
|
960
1169
|
.approval-request-actions {
|
|
961
1170
|
display: flex;
|
|
@@ -963,32 +1172,32 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
963
1172
|
}
|
|
964
1173
|
.approval-action-btn {
|
|
965
1174
|
border-radius: 6px;
|
|
966
|
-
border: 1px solid
|
|
967
|
-
background:
|
|
968
|
-
color:
|
|
1175
|
+
border: 1px solid var(--border-5);
|
|
1176
|
+
background: var(--surface-4);
|
|
1177
|
+
color: var(--fg-approval-btn);
|
|
969
1178
|
font-size: 11px;
|
|
970
1179
|
font-weight: 600;
|
|
971
1180
|
padding: 4px 8px;
|
|
972
1181
|
cursor: pointer;
|
|
973
1182
|
}
|
|
974
1183
|
.approval-action-btn:hover {
|
|
975
|
-
background:
|
|
1184
|
+
background: var(--surface-7);
|
|
976
1185
|
}
|
|
977
1186
|
.approval-action-btn.approve {
|
|
978
|
-
border-color:
|
|
979
|
-
color:
|
|
1187
|
+
border-color: var(--approve-border);
|
|
1188
|
+
color: var(--approve);
|
|
980
1189
|
}
|
|
981
1190
|
.approval-action-btn.deny {
|
|
982
|
-
border-color:
|
|
983
|
-
color:
|
|
1191
|
+
border-color: var(--deny-border);
|
|
1192
|
+
color: var(--deny);
|
|
984
1193
|
}
|
|
985
1194
|
.approval-action-btn[disabled] {
|
|
986
1195
|
opacity: 0.55;
|
|
987
1196
|
cursor: not-allowed;
|
|
988
1197
|
}
|
|
989
1198
|
.user-bubble {
|
|
990
|
-
background:
|
|
991
|
-
border: 1px solid
|
|
1199
|
+
background: var(--bg-elevated);
|
|
1200
|
+
border: 1px solid var(--border-2);
|
|
992
1201
|
padding: 10px 16px;
|
|
993
1202
|
border-radius: 18px;
|
|
994
1203
|
max-width: 70%;
|
|
@@ -996,6 +1205,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
996
1205
|
line-height: 1.5;
|
|
997
1206
|
overflow-wrap: break-word;
|
|
998
1207
|
word-break: break-word;
|
|
1208
|
+
white-space: pre-wrap;
|
|
999
1209
|
}
|
|
1000
1210
|
.empty-state {
|
|
1001
1211
|
display: flex;
|
|
@@ -1004,7 +1214,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1004
1214
|
justify-content: center;
|
|
1005
1215
|
height: 100%;
|
|
1006
1216
|
gap: 16px;
|
|
1007
|
-
color:
|
|
1217
|
+
color: var(--fg-6);
|
|
1008
1218
|
}
|
|
1009
1219
|
.empty-state .assistant-avatar {
|
|
1010
1220
|
width: 36px;
|
|
@@ -1014,7 +1224,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1014
1224
|
}
|
|
1015
1225
|
.empty-state-text {
|
|
1016
1226
|
font-size: 14px;
|
|
1017
|
-
color:
|
|
1227
|
+
color: var(--fg-6);
|
|
1018
1228
|
}
|
|
1019
1229
|
.thinking-indicator {
|
|
1020
1230
|
display: inline-block;
|
|
@@ -1022,7 +1232,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1022
1232
|
font-size: 20px;
|
|
1023
1233
|
line-height: 1;
|
|
1024
1234
|
vertical-align: middle;
|
|
1025
|
-
color:
|
|
1235
|
+
color: var(--fg);
|
|
1026
1236
|
opacity: 0.5;
|
|
1027
1237
|
}
|
|
1028
1238
|
.thinking-status {
|
|
@@ -1030,13 +1240,13 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1030
1240
|
align-items: center;
|
|
1031
1241
|
gap: 8px;
|
|
1032
1242
|
margin-top: 2px;
|
|
1033
|
-
color:
|
|
1243
|
+
color: var(--fg-tool);
|
|
1034
1244
|
font-size: 14px;
|
|
1035
1245
|
line-height: 1.65;
|
|
1036
1246
|
font-weight: 400;
|
|
1037
1247
|
}
|
|
1038
1248
|
.thinking-status-label {
|
|
1039
|
-
color:
|
|
1249
|
+
color: var(--fg-tool);
|
|
1040
1250
|
font-size: 14px;
|
|
1041
1251
|
line-height: 1.65;
|
|
1042
1252
|
font-weight: 400;
|
|
@@ -1067,26 +1277,26 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1067
1277
|
right: 0;
|
|
1068
1278
|
bottom: 100%;
|
|
1069
1279
|
height: 48px;
|
|
1070
|
-
background: linear-gradient(to top,
|
|
1280
|
+
background: linear-gradient(to top, var(--bg) 0%, transparent 100%);
|
|
1071
1281
|
pointer-events: none;
|
|
1072
1282
|
}
|
|
1073
1283
|
.composer-inner { max-width: 680px; margin: 0 auto; }
|
|
1074
1284
|
.composer-shell {
|
|
1075
|
-
background:
|
|
1076
|
-
border: 1px solid
|
|
1285
|
+
background: var(--bg-alt);
|
|
1286
|
+
border: 1px solid var(--border-3);
|
|
1077
1287
|
border-radius: 24px;
|
|
1078
1288
|
display: flex;
|
|
1079
1289
|
align-items: end;
|
|
1080
1290
|
padding: 4px 6px 4px 6px;
|
|
1081
1291
|
transition: border-color 0.15s;
|
|
1082
1292
|
}
|
|
1083
|
-
.composer-shell:focus-within { border-color:
|
|
1293
|
+
.composer-shell:focus-within { border-color: var(--border-focus); }
|
|
1084
1294
|
.composer-input {
|
|
1085
1295
|
flex: 1;
|
|
1086
1296
|
background: transparent;
|
|
1087
1297
|
border: 0;
|
|
1088
1298
|
outline: none;
|
|
1089
|
-
color:
|
|
1299
|
+
color: var(--fg);
|
|
1090
1300
|
min-height: 40px;
|
|
1091
1301
|
max-height: 200px;
|
|
1092
1302
|
resize: none;
|
|
@@ -1095,14 +1305,14 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1095
1305
|
line-height: 1.5;
|
|
1096
1306
|
margin-top: -4px;
|
|
1097
1307
|
}
|
|
1098
|
-
.composer-input::placeholder { color:
|
|
1308
|
+
.composer-input::placeholder { color: var(--fg-7); }
|
|
1099
1309
|
.send-btn {
|
|
1100
1310
|
width: 32px;
|
|
1101
1311
|
height: 32px;
|
|
1102
|
-
background:
|
|
1312
|
+
background: var(--accent);
|
|
1103
1313
|
border: 0;
|
|
1104
1314
|
border-radius: 50%;
|
|
1105
|
-
color:
|
|
1315
|
+
color: var(--accent-fg);
|
|
1106
1316
|
cursor: pointer;
|
|
1107
1317
|
display: grid;
|
|
1108
1318
|
place-items: center;
|
|
@@ -1110,21 +1320,79 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1110
1320
|
margin-bottom: 2px;
|
|
1111
1321
|
transition: background 0.15s, opacity 0.15s;
|
|
1112
1322
|
}
|
|
1113
|
-
.send-btn:hover { background:
|
|
1323
|
+
.send-btn:hover { background: var(--accent-hover); }
|
|
1114
1324
|
.send-btn.stop-mode {
|
|
1115
|
-
background:
|
|
1116
|
-
color:
|
|
1325
|
+
background: var(--stop-bg);
|
|
1326
|
+
color: var(--stop-fg);
|
|
1117
1327
|
}
|
|
1118
|
-
.send-btn.stop-mode:hover { background:
|
|
1328
|
+
.send-btn.stop-mode:hover { background: var(--stop-hover); }
|
|
1119
1329
|
.send-btn:disabled { opacity: 0.2; cursor: default; }
|
|
1120
|
-
.send-btn:disabled:hover { background:
|
|
1330
|
+
.send-btn:disabled:hover { background: var(--accent); }
|
|
1331
|
+
.send-btn-wrapper {
|
|
1332
|
+
position: relative;
|
|
1333
|
+
width: 36px;
|
|
1334
|
+
height: 36px;
|
|
1335
|
+
display: grid;
|
|
1336
|
+
place-items: center;
|
|
1337
|
+
flex-shrink: 0;
|
|
1338
|
+
margin-bottom: 0;
|
|
1339
|
+
}
|
|
1340
|
+
.send-btn-wrapper .send-btn {
|
|
1341
|
+
margin-bottom: 0;
|
|
1342
|
+
}
|
|
1343
|
+
.context-ring {
|
|
1344
|
+
position: absolute;
|
|
1345
|
+
inset: 0;
|
|
1346
|
+
width: 36px;
|
|
1347
|
+
height: 36px;
|
|
1348
|
+
pointer-events: none;
|
|
1349
|
+
transform: rotate(-90deg);
|
|
1350
|
+
}
|
|
1351
|
+
.context-ring-fill {
|
|
1352
|
+
fill: none;
|
|
1353
|
+
stroke: var(--bg-alt);
|
|
1354
|
+
stroke-width: 3;
|
|
1355
|
+
stroke-linecap: butt;
|
|
1356
|
+
transition: stroke-dashoffset 0.4s ease, stroke 0.3s ease;
|
|
1357
|
+
}
|
|
1358
|
+
.send-btn-wrapper.stop-mode .context-ring-fill {
|
|
1359
|
+
stroke: var(--fg-3);
|
|
1360
|
+
}
|
|
1361
|
+
.context-ring-fill.warning {
|
|
1362
|
+
stroke: #e5a33d;
|
|
1363
|
+
}
|
|
1364
|
+
.context-ring-fill.critical {
|
|
1365
|
+
stroke: #e55d4a;
|
|
1366
|
+
}
|
|
1367
|
+
.context-tooltip {
|
|
1368
|
+
position: absolute;
|
|
1369
|
+
bottom: calc(100% + 8px);
|
|
1370
|
+
right: 0;
|
|
1371
|
+
background: var(--bg-elevated);
|
|
1372
|
+
border: 1px solid var(--border-3);
|
|
1373
|
+
border-radius: 8px;
|
|
1374
|
+
padding: 6px 10px;
|
|
1375
|
+
font-size: 12px;
|
|
1376
|
+
color: var(--fg-2);
|
|
1377
|
+
white-space: nowrap;
|
|
1378
|
+
pointer-events: none;
|
|
1379
|
+
opacity: 0;
|
|
1380
|
+
transform: translateY(4px);
|
|
1381
|
+
transition: opacity 0.15s, transform 0.15s;
|
|
1382
|
+
z-index: 10;
|
|
1383
|
+
}
|
|
1384
|
+
.send-btn-wrapper:hover .context-tooltip,
|
|
1385
|
+
.send-btn-wrapper:focus-within .context-tooltip {
|
|
1386
|
+
opacity: 1;
|
|
1387
|
+
transform: translateY(0);
|
|
1388
|
+
}
|
|
1121
1389
|
.attach-btn {
|
|
1122
1390
|
width: 32px;
|
|
1123
1391
|
height: 32px;
|
|
1124
|
-
background:
|
|
1392
|
+
background: var(--surface-5);
|
|
1125
1393
|
border: 0;
|
|
1126
1394
|
border-radius: 50%;
|
|
1127
|
-
color:
|
|
1395
|
+
color: var(--fg-3);
|
|
1128
1396
|
cursor: pointer;
|
|
1129
1397
|
display: grid;
|
|
1130
1398
|
place-items: center;
|
|
@@ -1133,7 +1401,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1133
1401
|
margin-right: 8px;
|
|
1134
1402
|
transition: color 0.15s, background 0.15s;
|
|
1135
1403
|
}
|
|
1136
|
-
.attach-btn:hover { color:
|
|
1404
|
+
.attach-btn:hover { color: var(--fg); background: var(--surface-8); }
|
|
1137
1405
|
.attachment-preview {
|
|
1138
1406
|
display: flex;
|
|
1139
1407
|
gap: 8px;
|
|
@@ -1144,12 +1412,12 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1144
1412
|
display: inline-flex;
|
|
1145
1413
|
align-items: center;
|
|
1146
1414
|
gap: 6px;
|
|
1147
|
-
background:
|
|
1148
|
-
border: 1px solid
|
|
1415
|
+
background: var(--chip-bg);
|
|
1416
|
+
border: 1px solid var(--border-4);
|
|
1149
1417
|
border-radius: 9999px;
|
|
1150
1418
|
padding: 4px 10px 4px 6px;
|
|
1151
1419
|
font-size: 11px;
|
|
1152
|
-
color:
|
|
1420
|
+
color: var(--fg-4);
|
|
1153
1421
|
max-width: 200px;
|
|
1154
1422
|
cursor: pointer;
|
|
1155
1423
|
backdrop-filter: blur(6px);
|
|
@@ -1157,9 +1425,9 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1157
1425
|
transition: color 0.15s, border-color 0.15s, background 0.15s;
|
|
1158
1426
|
}
|
|
1159
1427
|
.attachment-chip:hover {
|
|
1160
|
-
color:
|
|
1161
|
-
border-color:
|
|
1162
|
-
background:
|
|
1428
|
+
color: var(--fg);
|
|
1429
|
+
border-color: var(--border-hover);
|
|
1430
|
+
background: var(--chip-bg-hover);
|
|
1163
1431
|
}
|
|
1164
1432
|
.attachment-chip img {
|
|
1165
1433
|
width: 20px;
|
|
@@ -1173,7 +1441,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1173
1441
|
width: 20px;
|
|
1174
1442
|
height: 20px;
|
|
1175
1443
|
border-radius: 50%;
|
|
1176
|
-
background:
|
|
1444
|
+
background: var(--surface-6);
|
|
1177
1445
|
display: grid;
|
|
1178
1446
|
place-items: center;
|
|
1179
1447
|
font-size: 11px;
|
|
@@ -1181,13 +1449,13 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1181
1449
|
}
|
|
1182
1450
|
.attachment-chip .remove-attachment {
|
|
1183
1451
|
cursor: pointer;
|
|
1184
|
-
color:
|
|
1452
|
+
color: var(--fg-6);
|
|
1185
1453
|
font-size: 14px;
|
|
1186
1454
|
margin-left: 2px;
|
|
1187
1455
|
line-height: 1;
|
|
1188
1456
|
transition: color 0.15s;
|
|
1189
1457
|
}
|
|
1190
|
-
.attachment-chip .remove-attachment:hover { color:
|
|
1458
|
+
.attachment-chip .remove-attachment:hover { color: var(--fg-strong); }
|
|
1191
1459
|
.attachment-chip .filename { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100px; }
|
|
1192
1460
|
.user-bubble .user-file-attachments {
|
|
1193
1461
|
display: flex;
|
|
@@ -1217,7 +1485,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1217
1485
|
transition: background 0.25s ease, backdrop-filter 0.25s ease;
|
|
1218
1486
|
}
|
|
1219
1487
|
.lightbox.active {
|
|
1220
|
-
background:
|
|
1488
|
+
background: var(--lightbox-bg);
|
|
1221
1489
|
backdrop-filter: blur(8px);
|
|
1222
1490
|
}
|
|
1223
1491
|
.lightbox img {
|
|
@@ -1237,16 +1505,16 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1237
1505
|
display: inline-flex;
|
|
1238
1506
|
align-items: center;
|
|
1239
1507
|
gap: 4px;
|
|
1240
|
-
background:
|
|
1508
|
+
background: var(--file-badge-bg);
|
|
1241
1509
|
border-radius: 6px;
|
|
1242
1510
|
padding: 4px 8px;
|
|
1243
1511
|
font-size: 12px;
|
|
1244
|
-
color:
|
|
1512
|
+
color: var(--file-badge-fg);
|
|
1245
1513
|
}
|
|
1246
1514
|
.drag-overlay {
|
|
1247
1515
|
position: fixed;
|
|
1248
1516
|
inset: 0;
|
|
1249
|
-
background:
|
|
1517
|
+
background: var(--backdrop);
|
|
1250
1518
|
z-index: 9999;
|
|
1251
1519
|
display: none;
|
|
1252
1520
|
align-items: center;
|
|
@@ -1255,15 +1523,15 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1255
1523
|
}
|
|
1256
1524
|
.drag-overlay.active { display: flex; }
|
|
1257
1525
|
.drag-overlay-inner {
|
|
1258
|
-
border: 2px dashed
|
|
1526
|
+
border: 2px dashed var(--border-drag);
|
|
1259
1527
|
border-radius: 16px;
|
|
1260
1528
|
padding: 40px 60px;
|
|
1261
|
-
color:
|
|
1529
|
+
color: var(--fg-strong);
|
|
1262
1530
|
font-size: 16px;
|
|
1263
1531
|
}
|
|
1264
1532
|
.disclaimer {
|
|
1265
1533
|
text-align: center;
|
|
1266
|
-
color:
|
|
1534
|
+
color: var(--fg-8);
|
|
1267
1535
|
font-size: 12px;
|
|
1268
1536
|
margin-top: 10px;
|
|
1269
1537
|
}
|
|
@@ -1278,10 +1546,10 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1278
1546
|
align-items: center;
|
|
1279
1547
|
gap: 6px;
|
|
1280
1548
|
font-size: 11px;
|
|
1281
|
-
color:
|
|
1549
|
+
color: var(--fg-4);
|
|
1282
1550
|
text-decoration: none;
|
|
1283
|
-
background:
|
|
1284
|
-
border: 1px solid
|
|
1551
|
+
background: var(--chip-bg);
|
|
1552
|
+
border: 1px solid var(--border-4);
|
|
1285
1553
|
border-radius: 9999px;
|
|
1286
1554
|
padding: 4px 10px 4px 6px;
|
|
1287
1555
|
backdrop-filter: blur(6px);
|
|
@@ -1289,9 +1557,9 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1289
1557
|
transition: color 0.15s, border-color 0.15s, background 0.15s;
|
|
1290
1558
|
}
|
|
1291
1559
|
.poncho-badge:hover {
|
|
1292
|
-
color:
|
|
1293
|
-
border-color:
|
|
1294
|
-
background:
|
|
1560
|
+
color: var(--fg);
|
|
1561
|
+
border-color: var(--border-hover);
|
|
1562
|
+
background: var(--chip-bg-hover);
|
|
1295
1563
|
}
|
|
1296
1564
|
.poncho-badge-avatar {
|
|
1297
1565
|
width: 16px;
|
|
@@ -1305,8 +1573,8 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1305
1573
|
/* Scrollbar */
|
|
1306
1574
|
::-webkit-scrollbar { width: 6px; }
|
|
1307
1575
|
::-webkit-scrollbar-track { background: transparent; }
|
|
1308
|
-
::-webkit-scrollbar-thumb { background:
|
|
1309
|
-
::-webkit-scrollbar-thumb:hover { background:
|
|
1576
|
+
::-webkit-scrollbar-thumb { background: var(--scrollbar); border-radius: 3px; }
|
|
1577
|
+
::-webkit-scrollbar-thumb:hover { background: var(--scrollbar-hover); }
|
|
1310
1578
|
|
|
1311
1579
|
/* Mobile */
|
|
1312
1580
|
@media (max-width: 768px) {
|
|
@@ -1336,7 +1604,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1336
1604
|
.sidebar-backdrop {
|
|
1337
1605
|
position: fixed;
|
|
1338
1606
|
inset: 0;
|
|
1339
|
-
background:
|
|
1607
|
+
background: var(--backdrop);
|
|
1340
1608
|
z-index: 50;
|
|
1341
1609
|
backdrop-filter: blur(2px);
|
|
1342
1610
|
-webkit-backdrop-filter: blur(2px);
|
|
@@ -1411,9 +1679,15 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1411
1679
|
</button>
|
|
1412
1680
|
<input id="file-input" type="file" multiple accept="image/*,video/*,application/pdf,.txt,.csv,.json,.html" style="display:none" />
|
|
1413
1681
|
<textarea id="prompt" class="composer-input" placeholder="Send a message..." rows="1"></textarea>
|
|
1414
|
-
<
|
|
1415
|
-
<svg
|
|
1416
|
-
|
|
1682
|
+
<div class="send-btn-wrapper" id="send-btn-wrapper">
|
|
1683
|
+
<svg class="context-ring" viewBox="0 0 36 36">
|
|
1684
|
+
<circle class="context-ring-fill" id="context-ring-fill" cx="18" cy="18" r="14.5" />
|
|
1685
|
+
</svg>
|
|
1686
|
+
<button id="send" class="send-btn" type="submit">
|
|
1687
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 12V4M4 7l4-4 4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
1688
|
+
</button>
|
|
1689
|
+
<div class="context-tooltip" id="context-tooltip"></div>
|
|
1690
|
+
</div>
|
|
1417
1691
|
</div>
|
|
1418
1692
|
</div>
|
|
1419
1693
|
</form>
|
|
@@ -1445,6 +1719,8 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1445
1719
|
confirmDeleteId: null,
|
|
1446
1720
|
approvalRequestsInFlight: {},
|
|
1447
1721
|
pendingFiles: [],
|
|
1722
|
+
contextTokens: 0,
|
|
1723
|
+
contextWindow: 0,
|
|
1448
1724
|
};
|
|
1449
1725
|
|
|
1450
1726
|
const agentInitial = document.body.dataset.agentInitial || "A";
|
|
@@ -1472,12 +1748,41 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1472
1748
|
attachmentPreview: $("attachment-preview"),
|
|
1473
1749
|
dragOverlay: $("drag-overlay"),
|
|
1474
1750
|
lightbox: $("lightbox"),
|
|
1751
|
+
contextRingFill: $("context-ring-fill"),
|
|
1752
|
+
contextTooltip: $("context-tooltip"),
|
|
1753
|
+
sendBtnWrapper: $("send-btn-wrapper"),
|
|
1475
1754
|
};
|
|
1476
1755
|
const sendIconMarkup =
|
|
1477
1756
|
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 12V4M4 7l4-4 4 4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
|
1478
1757
|
const stopIconMarkup =
|
|
1479
1758
|
'<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="4" y="4" width="8" height="8" rx="2" fill="currentColor"/></svg>';
|
|
1480
1759
|
|
|
1760
|
+
const CONTEXT_RING_CIRCUMFERENCE = 2 * Math.PI * 14.5;
|
|
1761
|
+
const formatTokenCount = (n) => {
|
|
1762
|
+
if (n >= 1_000_000) return (n / 1_000_000).toFixed(1).replace(/\\.0$/, "") + "M";
|
|
1763
|
+
if (n >= 1_000) return (n / 1_000).toFixed(1).replace(/\\.0$/, "") + "k";
|
|
1764
|
+
return String(n);
|
|
1765
|
+
};
|
|
1766
|
+
const updateContextRing = () => {
|
|
1767
|
+
const ring = elements.contextRingFill;
|
|
1768
|
+
const tooltip = elements.contextTooltip;
|
|
1769
|
+
if (!ring || !tooltip) return;
|
|
1770
|
+
if (state.contextWindow <= 0) {
|
|
1771
|
+
ring.style.strokeDasharray = String(CONTEXT_RING_CIRCUMFERENCE);
|
|
1772
|
+
ring.style.strokeDashoffset = String(CONTEXT_RING_CIRCUMFERENCE);
|
|
1773
|
+
tooltip.textContent = "";
|
|
1774
|
+
return;
|
|
1775
|
+
}
|
|
1776
|
+
const ratio = Math.min(state.contextTokens / state.contextWindow, 1);
|
|
1777
|
+
const offset = CONTEXT_RING_CIRCUMFERENCE * (1 - ratio);
|
|
1778
|
+
ring.style.strokeDasharray = String(CONTEXT_RING_CIRCUMFERENCE);
|
|
1779
|
+
ring.style.strokeDashoffset = String(offset);
|
|
1780
|
+
ring.classList.toggle("warning", ratio >= 0.7 && ratio < 0.9);
|
|
1781
|
+
ring.classList.toggle("critical", ratio >= 0.9);
|
|
1782
|
+
const pct = (ratio * 100).toFixed(1).replace(/\\.0$/, "");
|
|
1783
|
+
tooltip.textContent = formatTokenCount(state.contextTokens) + " / " + formatTokenCount(state.contextWindow) + " tokens (" + pct + "%)";
|
|
1784
|
+
};
|
|
1785
|
+
|
|
1481
1786
|
const pushConversationUrl = (conversationId) => {
|
|
1482
1787
|
const target = conversationId ? "/c/" + encodeURIComponent(conversationId) : "/";
|
|
1483
1788
|
if (window.location.pathname !== target) {
|
|
@@ -1574,18 +1879,20 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1574
1879
|
.map((req) => {
|
|
1575
1880
|
const approvalId = typeof req.approvalId === "string" ? req.approvalId : "";
|
|
1576
1881
|
const tool = typeof req.tool === "string" ? req.tool : "tool";
|
|
1577
|
-
const
|
|
1882
|
+
const input = req.input != null ? req.input : {};
|
|
1578
1883
|
const submitting = req.state === "submitting";
|
|
1579
1884
|
const approveLabel = submitting && req.pendingDecision === "approve" ? "Approving..." : "Approve";
|
|
1580
1885
|
const denyLabel = submitting && req.pendingDecision === "deny" ? "Denying..." : "Deny";
|
|
1886
|
+
const errorHtml = req._error
|
|
1887
|
+
? '<div style="color: var(--deny); font-size: 11px; margin-top: 4px;">Submit failed: ' + escapeHtml(req._error) + "</div>"
|
|
1888
|
+
: "";
|
|
1581
1889
|
return (
|
|
1582
1890
|
'<div class="approval-request-item">' +
|
|
1583
|
-
'<div class="approval-
|
|
1891
|
+
'<div class="approval-requests-label">Approval required: <code>' +
|
|
1584
1892
|
escapeHtml(tool) +
|
|
1585
|
-
"</div>" +
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
"</div>" +
|
|
1893
|
+
"</code></div>" +
|
|
1894
|
+
renderInputTable(input) +
|
|
1895
|
+
errorHtml +
|
|
1589
1896
|
'<div class="approval-request-actions">' +
|
|
1590
1897
|
'<button class="approval-action-btn approve" data-approval-id="' +
|
|
1591
1898
|
escapeHtml(approvalId) +
|
|
@@ -1608,7 +1915,6 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1608
1915
|
.join("");
|
|
1609
1916
|
return (
|
|
1610
1917
|
'<div class="approval-requests">' +
|
|
1611
|
-
'<div class="approval-requests-label">Approval required</div>' +
|
|
1612
1918
|
rows +
|
|
1613
1919
|
"</div>"
|
|
1614
1920
|
);
|
|
@@ -1638,22 +1944,46 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1638
1944
|
"</details>"
|
|
1639
1945
|
)
|
|
1640
1946
|
: "";
|
|
1947
|
+
const cls = "tool-activity" + (hasApprovals ? " has-approvals" : "");
|
|
1641
1948
|
return (
|
|
1642
|
-
'<div class="
|
|
1949
|
+
'<div class="' + cls + '">' +
|
|
1643
1950
|
disclosure +
|
|
1644
1951
|
renderApprovalRequests(approvalRequests) +
|
|
1645
1952
|
"</div>"
|
|
1646
1953
|
);
|
|
1647
1954
|
};
|
|
1648
1955
|
|
|
1649
|
-
const
|
|
1650
|
-
|
|
1651
|
-
return
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
return
|
|
1956
|
+
const renderInputTable = (input) => {
|
|
1957
|
+
if (!input || typeof input !== "object") {
|
|
1958
|
+
return '<div class="av-complex">' + escapeHtml(String(input ?? "{}")) + "</div>";
|
|
1959
|
+
}
|
|
1960
|
+
const keys = Object.keys(input);
|
|
1961
|
+
if (keys.length === 0) {
|
|
1962
|
+
return '<div class="av-complex">{}</div>';
|
|
1656
1963
|
}
|
|
1964
|
+
const formatValue = (val) => {
|
|
1965
|
+
if (val === null || val === undefined) return escapeHtml("null");
|
|
1966
|
+
if (typeof val === "boolean" || typeof val === "number") return escapeHtml(String(val));
|
|
1967
|
+
if (typeof val === "string") return escapeHtml(val);
|
|
1968
|
+
try {
|
|
1969
|
+
const replacer = (_, v) => typeof v === "bigint" ? String(v) : v;
|
|
1970
|
+
return escapeHtml(JSON.stringify(val, replacer, 2));
|
|
1971
|
+
} catch {
|
|
1972
|
+
return escapeHtml("[unserializable]");
|
|
1973
|
+
}
|
|
1974
|
+
};
|
|
1975
|
+
const rows = keys.map((key) => {
|
|
1976
|
+
const val = input[key];
|
|
1977
|
+
const isComplex = val !== null && typeof val === "object";
|
|
1978
|
+
const cls = isComplex ? "av-complex" : "av";
|
|
1979
|
+
return (
|
|
1980
|
+
"<tr>" +
|
|
1981
|
+
'<td class="ak">' + escapeHtml(key) + "</td>" +
|
|
1982
|
+
'<td><div class="' + cls + '">' + formatValue(val) + "</div></td>" +
|
|
1983
|
+
"</tr>"
|
|
1984
|
+
);
|
|
1985
|
+
}).join("");
|
|
1986
|
+
return '<table class="approval-request-table">' + rows + "</table>";
|
|
1657
1987
|
};
|
|
1658
1988
|
|
|
1659
1989
|
const updatePendingApproval = (approvalId, updater) => {
|
|
@@ -1692,12 +2022,10 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1692
2022
|
return null;
|
|
1693
2023
|
}
|
|
1694
2024
|
const toolName = item && typeof item.tool === "string" ? item.tool : "tool";
|
|
1695
|
-
const preview = safeJsonPreview(item?.input ?? {});
|
|
1696
|
-
const inputPreview = preview.length > 600 ? preview.slice(0, 600) + "..." : preview;
|
|
1697
2025
|
return {
|
|
1698
2026
|
approvalId,
|
|
1699
2027
|
tool: toolName,
|
|
1700
|
-
|
|
2028
|
+
input: item?.input ?? {},
|
|
1701
2029
|
state: "pending",
|
|
1702
2030
|
};
|
|
1703
2031
|
})
|
|
@@ -1775,50 +2103,87 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1775
2103
|
elements.shell.classList.toggle("sidebar-open", open);
|
|
1776
2104
|
};
|
|
1777
2105
|
|
|
1778
|
-
const
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
const item = document.createElement("div");
|
|
1782
|
-
item.className = "conversation-item" + (c.conversationId === state.activeConversationId ? " active" : "");
|
|
1783
|
-
item.textContent = c.title;
|
|
1784
|
-
|
|
1785
|
-
const isConfirming = state.confirmDeleteId === c.conversationId;
|
|
1786
|
-
const deleteBtn = document.createElement("button");
|
|
1787
|
-
deleteBtn.className = "delete-btn" + (isConfirming ? " confirming" : "");
|
|
1788
|
-
deleteBtn.textContent = isConfirming ? "sure?" : "\\u00d7";
|
|
1789
|
-
deleteBtn.onclick = async (e) => {
|
|
1790
|
-
e.stopPropagation();
|
|
1791
|
-
if (!isConfirming) {
|
|
1792
|
-
state.confirmDeleteId = c.conversationId;
|
|
1793
|
-
renderConversationList();
|
|
1794
|
-
return;
|
|
1795
|
-
}
|
|
1796
|
-
await api("/api/conversations/" + c.conversationId, { method: "DELETE" });
|
|
1797
|
-
if (state.activeConversationId === c.conversationId) {
|
|
1798
|
-
state.activeConversationId = null;
|
|
1799
|
-
state.activeMessages = [];
|
|
1800
|
-
pushConversationUrl(null);
|
|
1801
|
-
elements.chatTitle.textContent = "";
|
|
1802
|
-
renderMessages([]);
|
|
1803
|
-
}
|
|
1804
|
-
state.confirmDeleteId = null;
|
|
1805
|
-
await loadConversations();
|
|
1806
|
-
};
|
|
1807
|
-
item.appendChild(deleteBtn);
|
|
2106
|
+
const buildConversationItem = (c) => {
|
|
2107
|
+
const item = document.createElement("div");
|
|
2108
|
+
item.className = "conversation-item" + (c.conversationId === state.activeConversationId ? " active" : "");
|
|
1808
2109
|
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
2110
|
+
if (c.hasPendingApprovals) {
|
|
2111
|
+
const dot = document.createElement("span");
|
|
2112
|
+
dot.className = "approval-dot";
|
|
2113
|
+
item.appendChild(dot);
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
const titleSpan = document.createElement("span");
|
|
2117
|
+
titleSpan.textContent = c.title;
|
|
2118
|
+
item.appendChild(titleSpan);
|
|
2119
|
+
|
|
2120
|
+
const isConfirming = state.confirmDeleteId === c.conversationId;
|
|
2121
|
+
const deleteBtn = document.createElement("button");
|
|
2122
|
+
deleteBtn.className = "delete-btn" + (isConfirming ? " confirming" : "");
|
|
2123
|
+
deleteBtn.textContent = isConfirming ? "sure?" : "\\u00d7";
|
|
2124
|
+
deleteBtn.onclick = async (e) => {
|
|
2125
|
+
e.stopPropagation();
|
|
2126
|
+
if (!isConfirming) {
|
|
2127
|
+
state.confirmDeleteId = c.conversationId;
|
|
1816
2128
|
renderConversationList();
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
};
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
await api("/api/conversations/" + c.conversationId, { method: "DELETE" });
|
|
2132
|
+
if (state.activeConversationId === c.conversationId) {
|
|
2133
|
+
state.activeConversationId = null;
|
|
2134
|
+
state.activeMessages = [];
|
|
2135
|
+
state.contextTokens = 0;
|
|
2136
|
+
state.contextWindow = 0;
|
|
2137
|
+
updateContextRing();
|
|
2138
|
+
pushConversationUrl(null);
|
|
2139
|
+
elements.chatTitle.textContent = "";
|
|
2140
|
+
renderMessages([]);
|
|
2141
|
+
}
|
|
2142
|
+
state.confirmDeleteId = null;
|
|
2143
|
+
await loadConversations();
|
|
2144
|
+
};
|
|
2145
|
+
item.appendChild(deleteBtn);
|
|
2146
|
+
|
|
2147
|
+
item.onclick = async () => {
|
|
2148
|
+
if (state.confirmDeleteId) {
|
|
2149
|
+
state.confirmDeleteId = null;
|
|
2150
|
+
}
|
|
2151
|
+
state.activeConversationId = c.conversationId;
|
|
2152
|
+
pushConversationUrl(c.conversationId);
|
|
2153
|
+
renderConversationList();
|
|
2154
|
+
await loadConversation(c.conversationId);
|
|
2155
|
+
if (isMobile()) setSidebarOpen(false);
|
|
2156
|
+
};
|
|
2157
|
+
|
|
2158
|
+
return item;
|
|
2159
|
+
};
|
|
2160
|
+
|
|
2161
|
+
const renderConversationList = () => {
|
|
2162
|
+
elements.list.innerHTML = "";
|
|
2163
|
+
const pending = state.conversations.filter(c => c.hasPendingApprovals);
|
|
2164
|
+
const rest = state.conversations.filter(c => !c.hasPendingApprovals);
|
|
2165
|
+
|
|
2166
|
+
if (pending.length > 0) {
|
|
2167
|
+
const label = document.createElement("div");
|
|
2168
|
+
label.className = "sidebar-section-label";
|
|
2169
|
+
label.textContent = "Awaiting approval";
|
|
2170
|
+
elements.list.appendChild(label);
|
|
2171
|
+
for (const c of pending) {
|
|
2172
|
+
elements.list.appendChild(buildConversationItem(c));
|
|
2173
|
+
}
|
|
2174
|
+
if (rest.length > 0) {
|
|
2175
|
+
const divider = document.createElement("div");
|
|
2176
|
+
divider.className = "sidebar-section-divider";
|
|
2177
|
+
elements.list.appendChild(divider);
|
|
2178
|
+
const recentLabel = document.createElement("div");
|
|
2179
|
+
recentLabel.className = "sidebar-section-label";
|
|
2180
|
+
recentLabel.textContent = "Recent";
|
|
2181
|
+
elements.list.appendChild(recentLabel);
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
1820
2184
|
|
|
1821
|
-
|
|
2185
|
+
for (const c of rest) {
|
|
2186
|
+
elements.list.appendChild(buildConversationItem(c));
|
|
1822
2187
|
}
|
|
1823
2188
|
};
|
|
1824
2189
|
|
|
@@ -1893,8 +2258,14 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
1893
2258
|
} else if (shouldRenderEmptyStreamingIndicator) {
|
|
1894
2259
|
content.appendChild(createThinkingIndicator(getThinkingStatusLabel(m)));
|
|
1895
2260
|
} else {
|
|
1896
|
-
//
|
|
1897
|
-
|
|
2261
|
+
// Merge stored sections (persisted) with live sections (from
|
|
2262
|
+
// an active stream). For normal messages only one source
|
|
2263
|
+
// exists; for liveOnly reconnects both contribute.
|
|
2264
|
+
const storedSections = (m.metadata && m.metadata.sections) || [];
|
|
2265
|
+
const liveSections = m._sections || [];
|
|
2266
|
+
const sections = liveSections.length > 0 && storedSections.length > 0
|
|
2267
|
+
? storedSections.concat(liveSections)
|
|
2268
|
+
: liveSections.length > 0 ? liveSections : (storedSections.length > 0 ? storedSections : null);
|
|
1898
2269
|
const pendingApprovals = Array.isArray(m._pendingApprovals) ? m._pendingApprovals : [];
|
|
1899
2270
|
|
|
1900
2271
|
if (sections && sections.length > 0) {
|
|
@@ -2035,11 +2406,24 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2035
2406
|
payload.conversation.messages || [],
|
|
2036
2407
|
payload.conversation.pendingApprovals || payload.pendingApprovals || [],
|
|
2037
2408
|
);
|
|
2409
|
+
state.contextTokens = 0;
|
|
2410
|
+
state.contextWindow = 0;
|
|
2411
|
+
updateContextRing();
|
|
2038
2412
|
renderMessages(state.activeMessages, false, { forceScrollBottom: true });
|
|
2039
2413
|
elements.prompt.focus();
|
|
2414
|
+
if (payload.hasActiveRun && !state.isStreaming) {
|
|
2415
|
+
setStreaming(true);
|
|
2416
|
+
streamConversationEvents(conversationId, { liveOnly: true }).finally(() => {
|
|
2417
|
+
if (state.activeConversationId === conversationId) {
|
|
2418
|
+
setStreaming(false);
|
|
2419
|
+
renderMessages(state.activeMessages, false);
|
|
2420
|
+
}
|
|
2421
|
+
});
|
|
2422
|
+
}
|
|
2040
2423
|
};
|
|
2041
2424
|
|
|
2042
|
-
const streamConversationEvents = (conversationId) => {
|
|
2425
|
+
const streamConversationEvents = (conversationId, options) => {
|
|
2426
|
+
const liveOnly = options && options.liveOnly;
|
|
2043
2427
|
return new Promise((resolve) => {
|
|
2044
2428
|
const localMessages = state.activeMessages || [];
|
|
2045
2429
|
const renderIfActiveConversation = (streaming) => {
|
|
@@ -2058,20 +2442,36 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2058
2442
|
_currentText: "",
|
|
2059
2443
|
_currentTools: [],
|
|
2060
2444
|
_pendingApprovals: [],
|
|
2445
|
+
_activeActivities: [],
|
|
2061
2446
|
metadata: { toolActivity: [] },
|
|
2062
2447
|
};
|
|
2063
2448
|
localMessages.push(assistantMessage);
|
|
2064
2449
|
state.activeMessages = localMessages;
|
|
2065
2450
|
}
|
|
2066
|
-
if (
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2451
|
+
if (liveOnly) {
|
|
2452
|
+
// Live-only mode: keep metadata.sections intact (the stored
|
|
2453
|
+
// base content) and start _sections empty so it only collects
|
|
2454
|
+
// NEW sections from live events. The renderer merges both.
|
|
2455
|
+
assistantMessage._sections = [];
|
|
2456
|
+
assistantMessage._currentText = "";
|
|
2457
|
+
assistantMessage._currentTools = [];
|
|
2458
|
+
if (!assistantMessage._activeActivities) assistantMessage._activeActivities = [];
|
|
2459
|
+
if (!assistantMessage._pendingApprovals) assistantMessage._pendingApprovals = [];
|
|
2460
|
+
if (!assistantMessage.metadata) assistantMessage.metadata = {};
|
|
2461
|
+
if (!assistantMessage.metadata.toolActivity) assistantMessage.metadata.toolActivity = [];
|
|
2462
|
+
} else {
|
|
2463
|
+
// Full replay mode: reset transient state so replayed events
|
|
2464
|
+
// rebuild from scratch (the buffer has the full event history).
|
|
2465
|
+
assistantMessage.content = "";
|
|
2466
|
+
assistantMessage._sections = [];
|
|
2467
|
+
assistantMessage._currentText = "";
|
|
2468
|
+
assistantMessage._currentTools = [];
|
|
2469
|
+
assistantMessage._activeActivities = [];
|
|
2470
|
+
assistantMessage._pendingApprovals = [];
|
|
2471
|
+
assistantMessage.metadata = { toolActivity: [] };
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
const url = "/api/conversations/" + encodeURIComponent(conversationId) + "/events" + (liveOnly ? "?live_only=true" : "");
|
|
2075
2475
|
fetch(url, { credentials: "include" }).then((response) => {
|
|
2076
2476
|
if (!response.ok || !response.body) {
|
|
2077
2477
|
resolve(undefined);
|
|
@@ -2092,6 +2492,11 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2092
2492
|
if (eventName === "stream:end") {
|
|
2093
2493
|
return;
|
|
2094
2494
|
}
|
|
2495
|
+
if (eventName === "run:started") {
|
|
2496
|
+
if (typeof payload.contextWindow === "number" && payload.contextWindow > 0) {
|
|
2497
|
+
state.contextWindow = payload.contextWindow;
|
|
2498
|
+
}
|
|
2499
|
+
}
|
|
2095
2500
|
if (eventName === "model:chunk") {
|
|
2096
2501
|
const chunk = String(payload.content || "");
|
|
2097
2502
|
if (assistantMessage._currentTools.length > 0 && chunk.length > 0) {
|
|
@@ -2105,6 +2510,12 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2105
2510
|
assistantMessage._currentText += chunk;
|
|
2106
2511
|
renderIfActiveConversation(true);
|
|
2107
2512
|
}
|
|
2513
|
+
if (eventName === "model:response") {
|
|
2514
|
+
if (typeof payload.usage?.input === "number") {
|
|
2515
|
+
state.contextTokens = payload.usage.input;
|
|
2516
|
+
updateContextRing();
|
|
2517
|
+
}
|
|
2518
|
+
}
|
|
2108
2519
|
if (eventName === "tool:started") {
|
|
2109
2520
|
const toolName = payload.tool || "tool";
|
|
2110
2521
|
const startedActivity = addActiveActivityFromToolStart(
|
|
@@ -2177,6 +2588,73 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2177
2588
|
assistantMessage.metadata.toolActivity.push(toolText);
|
|
2178
2589
|
renderIfActiveConversation(true);
|
|
2179
2590
|
}
|
|
2591
|
+
if (eventName === "tool:approval:required") {
|
|
2592
|
+
const toolName = payload.tool || "tool";
|
|
2593
|
+
const activeActivity = removeActiveActivityForTool(
|
|
2594
|
+
assistantMessage,
|
|
2595
|
+
toolName,
|
|
2596
|
+
);
|
|
2597
|
+
const detailFromPayload = describeToolStart(payload);
|
|
2598
|
+
const detail =
|
|
2599
|
+
(activeActivity && typeof activeActivity.detail === "string"
|
|
2600
|
+
? activeActivity.detail.trim()
|
|
2601
|
+
: "") ||
|
|
2602
|
+
(detailFromPayload && typeof detailFromPayload.detail === "string"
|
|
2603
|
+
? detailFromPayload.detail.trim()
|
|
2604
|
+
: "");
|
|
2605
|
+
const toolText =
|
|
2606
|
+
"- approval required \\x60" +
|
|
2607
|
+
toolName +
|
|
2608
|
+
"\\x60" +
|
|
2609
|
+
(detail ? " (" + detail + ")" : "");
|
|
2610
|
+
assistantMessage._currentTools.push(toolText);
|
|
2611
|
+
assistantMessage.metadata.toolActivity.push(toolText);
|
|
2612
|
+
const approvalId =
|
|
2613
|
+
typeof payload.approvalId === "string" ? payload.approvalId : "";
|
|
2614
|
+
if (approvalId) {
|
|
2615
|
+
if (!Array.isArray(assistantMessage._pendingApprovals)) {
|
|
2616
|
+
assistantMessage._pendingApprovals = [];
|
|
2617
|
+
}
|
|
2618
|
+
const exists = assistantMessage._pendingApprovals.some(
|
|
2619
|
+
(req) => req.approvalId === approvalId,
|
|
2620
|
+
);
|
|
2621
|
+
if (!exists) {
|
|
2622
|
+
assistantMessage._pendingApprovals.push({
|
|
2623
|
+
approvalId,
|
|
2624
|
+
tool: toolName,
|
|
2625
|
+
input: payload.input ?? {},
|
|
2626
|
+
state: "pending",
|
|
2627
|
+
});
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2630
|
+
renderIfActiveConversation(true);
|
|
2631
|
+
}
|
|
2632
|
+
if (eventName === "tool:approval:granted") {
|
|
2633
|
+
const toolText = "- approval granted";
|
|
2634
|
+
assistantMessage._currentTools.push(toolText);
|
|
2635
|
+
assistantMessage.metadata.toolActivity.push(toolText);
|
|
2636
|
+
const approvalId =
|
|
2637
|
+
typeof payload.approvalId === "string" ? payload.approvalId : "";
|
|
2638
|
+
if (approvalId && Array.isArray(assistantMessage._pendingApprovals)) {
|
|
2639
|
+
assistantMessage._pendingApprovals = assistantMessage._pendingApprovals.filter(
|
|
2640
|
+
(req) => req.approvalId !== approvalId,
|
|
2641
|
+
);
|
|
2642
|
+
}
|
|
2643
|
+
renderIfActiveConversation(true);
|
|
2644
|
+
}
|
|
2645
|
+
if (eventName === "tool:approval:denied") {
|
|
2646
|
+
const toolText = "- approval denied";
|
|
2647
|
+
assistantMessage._currentTools.push(toolText);
|
|
2648
|
+
assistantMessage.metadata.toolActivity.push(toolText);
|
|
2649
|
+
const approvalId =
|
|
2650
|
+
typeof payload.approvalId === "string" ? payload.approvalId : "";
|
|
2651
|
+
if (approvalId && Array.isArray(assistantMessage._pendingApprovals)) {
|
|
2652
|
+
assistantMessage._pendingApprovals = assistantMessage._pendingApprovals.filter(
|
|
2653
|
+
(req) => req.approvalId !== approvalId,
|
|
2654
|
+
);
|
|
2655
|
+
}
|
|
2656
|
+
renderIfActiveConversation(true);
|
|
2657
|
+
}
|
|
2180
2658
|
if (eventName === "run:completed") {
|
|
2181
2659
|
assistantMessage._activeActivities = [];
|
|
2182
2660
|
if (
|
|
@@ -2223,9 +2701,22 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2223
2701
|
}
|
|
2224
2702
|
if (eventName === "run:error") {
|
|
2225
2703
|
assistantMessage._activeActivities = [];
|
|
2704
|
+
if (assistantMessage._currentTools.length > 0) {
|
|
2705
|
+
assistantMessage._sections.push({
|
|
2706
|
+
type: "tools",
|
|
2707
|
+
content: assistantMessage._currentTools,
|
|
2708
|
+
});
|
|
2709
|
+
assistantMessage._currentTools = [];
|
|
2710
|
+
}
|
|
2711
|
+
if (assistantMessage._currentText.length > 0) {
|
|
2712
|
+
assistantMessage._sections.push({
|
|
2713
|
+
type: "text",
|
|
2714
|
+
content: assistantMessage._currentText,
|
|
2715
|
+
});
|
|
2716
|
+
assistantMessage._currentText = "";
|
|
2717
|
+
}
|
|
2226
2718
|
const errMsg =
|
|
2227
2719
|
payload.error?.message || "Something went wrong";
|
|
2228
|
-
assistantMessage.content = "";
|
|
2229
2720
|
assistantMessage._error = errMsg;
|
|
2230
2721
|
renderIfActiveConversation(false);
|
|
2231
2722
|
}
|
|
@@ -2298,6 +2789,9 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2298
2789
|
elements.send.disabled = value ? !canStop : false;
|
|
2299
2790
|
elements.send.innerHTML = value ? stopIconMarkup : sendIconMarkup;
|
|
2300
2791
|
elements.send.classList.toggle("stop-mode", value);
|
|
2792
|
+
if (elements.sendBtnWrapper) {
|
|
2793
|
+
elements.sendBtnWrapper.classList.toggle("stop-mode", value);
|
|
2794
|
+
}
|
|
2301
2795
|
elements.send.setAttribute("aria-label", value ? "Stop response" : "Send message");
|
|
2302
2796
|
elements.send.setAttribute(
|
|
2303
2797
|
"title",
|
|
@@ -2670,8 +3164,17 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2670
3164
|
}
|
|
2671
3165
|
if (eventName === "run:started") {
|
|
2672
3166
|
state.activeStreamRunId = typeof payload.runId === "string" ? payload.runId : null;
|
|
3167
|
+
if (typeof payload.contextWindow === "number" && payload.contextWindow > 0) {
|
|
3168
|
+
state.contextWindow = payload.contextWindow;
|
|
3169
|
+
}
|
|
2673
3170
|
setStreaming(state.isStreaming);
|
|
2674
3171
|
}
|
|
3172
|
+
if (eventName === "model:response") {
|
|
3173
|
+
if (typeof payload.usage?.input === "number") {
|
|
3174
|
+
state.contextTokens = payload.usage.input;
|
|
3175
|
+
updateContextRing();
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
2675
3178
|
if (eventName === "tool:started") {
|
|
2676
3179
|
const toolName = payload.tool || "tool";
|
|
2677
3180
|
const startedActivity = addActiveActivityFromToolStart(
|
|
@@ -2767,8 +3270,6 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2767
3270
|
const approvalId =
|
|
2768
3271
|
typeof payload.approvalId === "string" ? payload.approvalId : "";
|
|
2769
3272
|
if (approvalId) {
|
|
2770
|
-
const preview = safeJsonPreview(payload.input ?? {});
|
|
2771
|
-
const inputPreview = preview.length > 600 ? preview.slice(0, 600) + "..." : preview;
|
|
2772
3273
|
if (!Array.isArray(assistantMessage._pendingApprovals)) {
|
|
2773
3274
|
assistantMessage._pendingApprovals = [];
|
|
2774
3275
|
}
|
|
@@ -2779,7 +3280,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2779
3280
|
assistantMessage._pendingApprovals.push({
|
|
2780
3281
|
approvalId,
|
|
2781
3282
|
tool: toolName,
|
|
2782
|
-
|
|
3283
|
+
input: payload.input ?? {},
|
|
2783
3284
|
state: "pending",
|
|
2784
3285
|
});
|
|
2785
3286
|
}
|
|
@@ -2834,9 +3335,8 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2834
3335
|
renderIfActiveConversation(false);
|
|
2835
3336
|
}
|
|
2836
3337
|
if (eventName === "run:error") {
|
|
2837
|
-
|
|
3338
|
+
finalizeAssistantMessage();
|
|
2838
3339
|
const errMsg = payload.error?.message || "Something went wrong";
|
|
2839
|
-
assistantMessage.content = "";
|
|
2840
3340
|
assistantMessage._error = errMsg;
|
|
2841
3341
|
renderIfActiveConversation(false);
|
|
2842
3342
|
}
|
|
@@ -2939,6 +3439,9 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2939
3439
|
state.activeConversationId = null;
|
|
2940
3440
|
state.activeMessages = [];
|
|
2941
3441
|
state.confirmDeleteId = null;
|
|
3442
|
+
state.contextTokens = 0;
|
|
3443
|
+
state.contextWindow = 0;
|
|
3444
|
+
updateContextRing();
|
|
2942
3445
|
pushConversationUrl(null);
|
|
2943
3446
|
elements.chatTitle.textContent = "";
|
|
2944
3447
|
renderMessages([]);
|
|
@@ -2976,6 +3479,9 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
2976
3479
|
state.confirmDeleteId = null;
|
|
2977
3480
|
state.conversations = [];
|
|
2978
3481
|
state.csrfToken = "";
|
|
3482
|
+
state.contextTokens = 0;
|
|
3483
|
+
state.contextWindow = 0;
|
|
3484
|
+
updateContextRing();
|
|
2979
3485
|
await requireAuth();
|
|
2980
3486
|
});
|
|
2981
3487
|
|
|
@@ -3123,17 +3629,23 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
3123
3629
|
});
|
|
3124
3630
|
updatePendingApproval(approvalId, () => null);
|
|
3125
3631
|
renderMessages(state.activeMessages, state.isStreaming);
|
|
3632
|
+
loadConversations();
|
|
3126
3633
|
if (!wasStreaming && state.activeConversationId) {
|
|
3127
|
-
await streamConversationEvents(state.activeConversationId);
|
|
3634
|
+
await streamConversationEvents(state.activeConversationId, { liveOnly: true });
|
|
3128
3635
|
}
|
|
3129
3636
|
} catch (error) {
|
|
3130
|
-
const
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3637
|
+
const isStale = error && error.payload && error.payload.code === "APPROVAL_NOT_FOUND";
|
|
3638
|
+
if (isStale) {
|
|
3639
|
+
updatePendingApproval(approvalId, () => null);
|
|
3640
|
+
} else {
|
|
3641
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
3642
|
+
updatePendingApproval(approvalId, (request) => ({
|
|
3643
|
+
...request,
|
|
3644
|
+
state: "pending",
|
|
3645
|
+
pendingDecision: null,
|
|
3646
|
+
_error: errMsg,
|
|
3647
|
+
}));
|
|
3648
|
+
}
|
|
3137
3649
|
renderMessages(state.activeMessages, state.isStreaming);
|
|
3138
3650
|
} finally {
|
|
3139
3651
|
if (!wasStreaming) {
|
|
@@ -3180,6 +3692,9 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
3180
3692
|
} else {
|
|
3181
3693
|
state.activeConversationId = null;
|
|
3182
3694
|
state.activeMessages = [];
|
|
3695
|
+
state.contextTokens = 0;
|
|
3696
|
+
state.contextWindow = 0;
|
|
3697
|
+
updateContextRing();
|
|
3183
3698
|
elements.chatTitle.textContent = "";
|
|
3184
3699
|
renderMessages([]);
|
|
3185
3700
|
renderConversationList();
|
|
@@ -3221,6 +3736,7 @@ export const renderWebUiHtml = (options?: { agentName?: string }): string => {
|
|
|
3221
3736
|
await createConversation();
|
|
3222
3737
|
}
|
|
3223
3738
|
autoResizePrompt();
|
|
3739
|
+
updateContextRing();
|
|
3224
3740
|
elements.prompt.focus();
|
|
3225
3741
|
})();
|
|
3226
3742
|
|