orchid-ai 2.0.1 → 2.0.3
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/orchid-ai.css +448 -25
- package/package.json +1 -1
- package/src/components/ChatWindow.jsx +60 -26
- package/src/components/Message.jsx +261 -27
- package/src/components/visualizations/chartSchema.js +79 -28
- package/src/constants/visualizationInstructions.js +2 -2
- package/src/hooks/useOrchidAiChat.js +90 -23
- package/src/index.d.ts +75 -3
- package/src/index.js +11 -0
- package/src/orchidAiProcessTrace.js +163 -0
- package/src/orchidAiStreamingTitle.js +12 -0
package/orchid-ai.css
CHANGED
|
@@ -244,6 +244,9 @@
|
|
|
244
244
|
border: 1px solid #e5e7eb;
|
|
245
245
|
border-radius: 12px;
|
|
246
246
|
padding: 16px 20px;
|
|
247
|
+
width: 100%;
|
|
248
|
+
max-width: 420px;
|
|
249
|
+
box-sizing: border-box;
|
|
247
250
|
}
|
|
248
251
|
|
|
249
252
|
.ai-chat-suggestions span {
|
|
@@ -260,6 +263,7 @@
|
|
|
260
263
|
display: flex;
|
|
261
264
|
flex-direction: column;
|
|
262
265
|
gap: 8px;
|
|
266
|
+
padding: 0;
|
|
263
267
|
}
|
|
264
268
|
|
|
265
269
|
.ai-chat-suggestions li {
|
|
@@ -271,6 +275,8 @@
|
|
|
271
275
|
border-radius: 8px;
|
|
272
276
|
cursor: pointer;
|
|
273
277
|
transition: background 0.15s, border-color 0.15s, color 0.15s;
|
|
278
|
+
width: 100%;
|
|
279
|
+
box-sizing: border-box;
|
|
274
280
|
}
|
|
275
281
|
|
|
276
282
|
.ai-chat-suggestions li:hover {
|
|
@@ -279,6 +285,17 @@
|
|
|
279
285
|
color: #1eaaf1;
|
|
280
286
|
}
|
|
281
287
|
|
|
288
|
+
.ai-chat-suggestions--disabled li {
|
|
289
|
+
opacity: 0.45;
|
|
290
|
+
cursor: not-allowed;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.ai-chat-suggestions--disabled li:hover {
|
|
294
|
+
background: #f9fafb;
|
|
295
|
+
border-color: #e5e7eb;
|
|
296
|
+
color: #4b5563;
|
|
297
|
+
}
|
|
298
|
+
|
|
282
299
|
/* ── Messages ── */
|
|
283
300
|
|
|
284
301
|
.ai-chat-message {
|
|
@@ -347,6 +364,16 @@
|
|
|
347
364
|
border-bottom-right-radius: 4px;
|
|
348
365
|
}
|
|
349
366
|
|
|
367
|
+
.ai-chat-bubble.user .ai-chat-user-link {
|
|
368
|
+
color: #e0f2fe;
|
|
369
|
+
text-decoration: underline;
|
|
370
|
+
word-break: break-all;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
.ai-chat-bubble.user .ai-chat-user-link:hover {
|
|
374
|
+
color: #ffffff;
|
|
375
|
+
}
|
|
376
|
+
|
|
350
377
|
.ai-chat-bubble.assistant {
|
|
351
378
|
position: relative;
|
|
352
379
|
background: #ffffff;
|
|
@@ -355,6 +382,323 @@
|
|
|
355
382
|
border-bottom-left-radius: 4px;
|
|
356
383
|
}
|
|
357
384
|
|
|
385
|
+
/* ── Tool / preamble trace (Claude-style timeline, light theme) ── */
|
|
386
|
+
|
|
387
|
+
.ai-chat-process-trace {
|
|
388
|
+
--ai-process-bg: #f4f6f8;
|
|
389
|
+
--ai-process-border: #e4e8ed;
|
|
390
|
+
--ai-process-rail: #d8dde4;
|
|
391
|
+
--ai-process-text: #5c6570;
|
|
392
|
+
--ai-process-text-strong: #2d3748;
|
|
393
|
+
--ai-process-dot: #9aa5b1;
|
|
394
|
+
--ai-process-dot-tool: #059669;
|
|
395
|
+
--ai-process-dot-compile: #4f46e5;
|
|
396
|
+
--ai-process-dot-mind: #94a3b8;
|
|
397
|
+
--ai-process-interim-fg: #475569;
|
|
398
|
+
|
|
399
|
+
margin: 0 0 12px;
|
|
400
|
+
border-radius: 12px;
|
|
401
|
+
border: 1px solid transparent;
|
|
402
|
+
background: transparent;
|
|
403
|
+
box-shadow: none;
|
|
404
|
+
font-size: 12.5px;
|
|
405
|
+
line-height: 1.45;
|
|
406
|
+
color: var(--ai-process-text);
|
|
407
|
+
overflow: visible;
|
|
408
|
+
transition:
|
|
409
|
+
background 0.22s ease,
|
|
410
|
+
border-color 0.22s ease,
|
|
411
|
+
box-shadow 0.22s ease;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/* Collapsed: no chrome — summary reads as muted underlined text on the bubble background */
|
|
415
|
+
.ai-chat-process-trace:not([open]) {
|
|
416
|
+
overflow: visible;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
.ai-chat-process-trace[open] {
|
|
420
|
+
overflow: hidden;
|
|
421
|
+
border-color: var(--ai-process-border);
|
|
422
|
+
background: linear-gradient(165deg, var(--ai-process-bg) 0%, #eef1f4 100%);
|
|
423
|
+
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
.ai-chat-process-trace__summary {
|
|
427
|
+
cursor: pointer;
|
|
428
|
+
list-style: none;
|
|
429
|
+
display: flex;
|
|
430
|
+
align-items: center;
|
|
431
|
+
gap: 8px;
|
|
432
|
+
padding: 4px 0 10px;
|
|
433
|
+
margin: 0;
|
|
434
|
+
font-weight: 500;
|
|
435
|
+
font-size: 13px;
|
|
436
|
+
letter-spacing: 0.01em;
|
|
437
|
+
text-transform: none;
|
|
438
|
+
color: #6b7280;
|
|
439
|
+
text-decoration: none;
|
|
440
|
+
user-select: none;
|
|
441
|
+
background: transparent;
|
|
442
|
+
border-bottom: none;
|
|
443
|
+
transition:
|
|
444
|
+
color 0.18s ease,
|
|
445
|
+
padding 0.2s ease,
|
|
446
|
+
font-size 0.2s ease,
|
|
447
|
+
font-weight 0.2s ease,
|
|
448
|
+
letter-spacing 0.2s ease,
|
|
449
|
+
background 0.22s ease,
|
|
450
|
+
border-color 0.22s ease;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/* Collapsed: underline only the label — chevron / dots sit beside it, not underlined */
|
|
454
|
+
.ai-chat-process-trace:not([open]) > .ai-chat-process-trace__summary {
|
|
455
|
+
gap: 5px;
|
|
456
|
+
width: fit-content;
|
|
457
|
+
max-width: 100%;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.ai-chat-process-trace:not([open]) > .ai-chat-process-trace__summary:hover {
|
|
461
|
+
color: #4b5563;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.ai-chat-process-trace:not([open]) > .ai-chat-process-trace__summary:hover .ai-chat-process-trace__summary-text {
|
|
465
|
+
text-decoration-color: #4b5563;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
.ai-chat-process-trace:not([open]) > .ai-chat-process-trace__summary:focus-visible {
|
|
469
|
+
outline: 2px solid #93c5fd;
|
|
470
|
+
outline-offset: 2px;
|
|
471
|
+
border-radius: 4px;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* Expanded: restore panel header strip inside the tinted card */
|
|
475
|
+
.ai-chat-process-trace[open] > .ai-chat-process-trace__summary {
|
|
476
|
+
padding: 10px 14px;
|
|
477
|
+
font-weight: 600;
|
|
478
|
+
font-size: 12px;
|
|
479
|
+
letter-spacing: 0.02em;
|
|
480
|
+
text-transform: uppercase;
|
|
481
|
+
color: var(--ai-process-text-strong);
|
|
482
|
+
text-decoration: none;
|
|
483
|
+
background: rgba(255, 255, 255, 0.45);
|
|
484
|
+
border-bottom: 1px solid var(--ai-process-border);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
.ai-chat-process-trace__summary::-webkit-details-marker {
|
|
488
|
+
display: none;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
.ai-chat-process-trace__summary-text {
|
|
492
|
+
flex: 1;
|
|
493
|
+
text-decoration: none;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.ai-chat-process-trace:not([open]) .ai-chat-process-trace__summary-text {
|
|
497
|
+
flex: 0 1 auto;
|
|
498
|
+
text-decoration: underline;
|
|
499
|
+
text-underline-offset: 3px;
|
|
500
|
+
text-decoration-thickness: 1px;
|
|
501
|
+
transition: text-decoration-color 0.18s ease;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
.ai-chat-process-trace[open] .ai-chat-process-trace__summary-text {
|
|
505
|
+
flex: 1;
|
|
506
|
+
text-decoration: none;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/* Single expand chevron (right); hidden while streaming — dots replace it. */
|
|
510
|
+
.ai-chat-process-trace__summary-chevron {
|
|
511
|
+
display: inline-flex;
|
|
512
|
+
align-items: center;
|
|
513
|
+
justify-content: center;
|
|
514
|
+
flex-shrink: 0;
|
|
515
|
+
min-width: 1.25em;
|
|
516
|
+
font-size: 15px;
|
|
517
|
+
font-weight: 700;
|
|
518
|
+
line-height: 1;
|
|
519
|
+
opacity: 0.55;
|
|
520
|
+
text-decoration: none;
|
|
521
|
+
transition: transform 0.18s ease, opacity 0.15s ease;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.ai-chat-process-trace:not([open]) .ai-chat-process-trace__summary-chevron {
|
|
525
|
+
opacity: 0.45;
|
|
526
|
+
min-width: auto;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.ai-chat-process-trace:not([open]) .ai-chat-process-trace__mini-typing span {
|
|
530
|
+
opacity: 0.72;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.ai-chat-process-trace[open] > .ai-chat-process-trace__summary .ai-chat-process-trace__summary-chevron {
|
|
534
|
+
transform: rotate(90deg);
|
|
535
|
+
opacity: 0.78;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
.ai-chat-process-trace__mini-typing {
|
|
539
|
+
display: inline-flex;
|
|
540
|
+
align-items: center;
|
|
541
|
+
flex-shrink: 0;
|
|
542
|
+
gap: 3px;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.ai-chat-process-trace__mini-typing span {
|
|
546
|
+
width: 4px;
|
|
547
|
+
height: 4px;
|
|
548
|
+
border-radius: 50%;
|
|
549
|
+
background: var(--ai-process-dot-tool);
|
|
550
|
+
opacity: 0.85;
|
|
551
|
+
animation: ai-chat-process-mini-dot 1.05s ease-in-out infinite;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.ai-chat-process-trace__mini-typing span:nth-child(2) {
|
|
555
|
+
animation-delay: 0.12s;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
.ai-chat-process-trace__mini-typing span:nth-child(3) {
|
|
559
|
+
animation-delay: 0.24s;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
@keyframes ai-chat-process-mini-dot {
|
|
563
|
+
0%,
|
|
564
|
+
80%,
|
|
565
|
+
100% {
|
|
566
|
+
transform: translateY(0);
|
|
567
|
+
opacity: 0.35;
|
|
568
|
+
}
|
|
569
|
+
40% {
|
|
570
|
+
transform: translateY(-2px);
|
|
571
|
+
opacity: 1;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
@keyframes ai-chat-process-pulse {
|
|
576
|
+
0% {
|
|
577
|
+
box-shadow: 0 0 0 0 rgba(5, 150, 105, 0.35);
|
|
578
|
+
}
|
|
579
|
+
70% {
|
|
580
|
+
box-shadow: 0 0 0 6px rgba(5, 150, 105, 0);
|
|
581
|
+
}
|
|
582
|
+
100% {
|
|
583
|
+
box-shadow: 0 0 0 0 rgba(5, 150, 105, 0);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.ai-chat-process-trace__panel {
|
|
588
|
+
padding: 10px 12px 12px 8px;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.ai-chat-process-trace__timeline {
|
|
592
|
+
list-style: none;
|
|
593
|
+
margin: 0;
|
|
594
|
+
padding: 0;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
.ai-chat-process-trace__step {
|
|
598
|
+
display: flex;
|
|
599
|
+
align-items: stretch;
|
|
600
|
+
gap: 10px;
|
|
601
|
+
margin: 0;
|
|
602
|
+
padding: 0 0 14px;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
.ai-chat-process-trace__step:last-child {
|
|
606
|
+
padding-bottom: 0;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.ai-chat-process-trace__rail {
|
|
610
|
+
position: relative;
|
|
611
|
+
width: 18px;
|
|
612
|
+
flex-shrink: 0;
|
|
613
|
+
display: flex;
|
|
614
|
+
justify-content: center;
|
|
615
|
+
padding-top: 4px;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.ai-chat-process-trace__rail::after {
|
|
619
|
+
content: "";
|
|
620
|
+
position: absolute;
|
|
621
|
+
top: 13px;
|
|
622
|
+
bottom: -14px;
|
|
623
|
+
left: 50%;
|
|
624
|
+
width: 1px;
|
|
625
|
+
transform: translateX(-50%);
|
|
626
|
+
background: var(--ai-process-rail);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.ai-chat-process-trace__step:last-child .ai-chat-process-trace__rail::after {
|
|
630
|
+
display: none;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
.ai-chat-process-trace__dot {
|
|
634
|
+
position: relative;
|
|
635
|
+
z-index: 1;
|
|
636
|
+
width: 7px;
|
|
637
|
+
height: 7px;
|
|
638
|
+
border-radius: 50%;
|
|
639
|
+
background: var(--ai-process-dot);
|
|
640
|
+
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.85);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
.ai-chat-process-trace__step--tool .ai-chat-process-trace__dot {
|
|
644
|
+
background: var(--ai-process-dot-tool);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
.ai-chat-process-trace__step--compile .ai-chat-process-trace__dot {
|
|
648
|
+
background: var(--ai-process-dot-compile);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
.ai-chat-process-trace__step--mind .ai-chat-process-trace__dot {
|
|
652
|
+
background: var(--ai-process-dot-mind);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.ai-chat-process-trace__step--text .ai-chat-process-trace__dot {
|
|
656
|
+
background: var(--ai-process-dot);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
.ai-chat-process-trace__step--interim .ai-chat-process-trace__dot {
|
|
660
|
+
background: var(--ai-process-dot);
|
|
661
|
+
animation: ai-chat-process-pulse 1.4s ease-out infinite;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
.ai-chat-process-trace__step--live .ai-chat-process-trace__dot {
|
|
665
|
+
animation: ai-chat-process-pulse 1.2s ease-out infinite;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.ai-chat-process-trace__body {
|
|
669
|
+
flex: 1;
|
|
670
|
+
min-width: 0;
|
|
671
|
+
padding-top: 1px;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.ai-chat-process-trace__line {
|
|
675
|
+
display: block;
|
|
676
|
+
color: var(--ai-process-text-strong);
|
|
677
|
+
font-weight: 500;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
.ai-chat-process-trace__step--tool .ai-chat-process-trace__line {
|
|
681
|
+
color: #047857;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
.ai-chat-process-trace__step--compile .ai-chat-process-trace__line {
|
|
685
|
+
color: #4338ca;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
.ai-chat-process-trace__prose {
|
|
689
|
+
margin: 0;
|
|
690
|
+
white-space: pre-wrap;
|
|
691
|
+
word-break: break-word;
|
|
692
|
+
color: var(--ai-process-interim-fg);
|
|
693
|
+
font-weight: 400;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
.ai-chat-process-trace__step--interim .ai-chat-process-trace__prose {
|
|
697
|
+
border-left: 2px solid var(--ai-process-rail);
|
|
698
|
+
padding-left: 10px;
|
|
699
|
+
margin-left: 2px;
|
|
700
|
+
}
|
|
701
|
+
|
|
358
702
|
/* ── Markdown Typography (assistant bubbles) ── */
|
|
359
703
|
|
|
360
704
|
.ai-chat-bubble.assistant p {
|
|
@@ -1789,6 +2133,29 @@
|
|
|
1789
2133
|
animation-delay: 0.4s;
|
|
1790
2134
|
}
|
|
1791
2135
|
|
|
2136
|
+
/* Smaller dots for inline status (next to “Compiling…”) */
|
|
2137
|
+
.ai-chat-typing--inline {
|
|
2138
|
+
gap: 4px;
|
|
2139
|
+
padding: 0;
|
|
2140
|
+
}
|
|
2141
|
+
|
|
2142
|
+
.ai-chat-typing--inline span {
|
|
2143
|
+
width: 5px;
|
|
2144
|
+
height: 5px;
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
.ai-chat-streaming-status {
|
|
2148
|
+
display: flex;
|
|
2149
|
+
align-items: center;
|
|
2150
|
+
gap: 8px;
|
|
2151
|
+
flex-wrap: wrap;
|
|
2152
|
+
margin-bottom: 8px;
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
.ai-chat-streaming-status .ai-chat-status-text {
|
|
2156
|
+
margin: 0;
|
|
2157
|
+
}
|
|
2158
|
+
|
|
1792
2159
|
@keyframes typing {
|
|
1793
2160
|
0%,
|
|
1794
2161
|
60%,
|
|
@@ -1802,6 +2169,48 @@
|
|
|
1802
2169
|
}
|
|
1803
2170
|
}
|
|
1804
2171
|
|
|
2172
|
+
/* ── Building Block (streaming code-block placeholder) ── */
|
|
2173
|
+
|
|
2174
|
+
.ai-building-block {
|
|
2175
|
+
display: flex;
|
|
2176
|
+
align-items: center;
|
|
2177
|
+
gap: 10px;
|
|
2178
|
+
flex-wrap: wrap;
|
|
2179
|
+
padding: 8px 12px;
|
|
2180
|
+
border-radius: 8px;
|
|
2181
|
+
margin: 6px 0 0;
|
|
2182
|
+
background: #f3f4f6;
|
|
2183
|
+
border: 1px solid #e5e7eb;
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
.ai-building-block__label {
|
|
2187
|
+
font-size: 13px;
|
|
2188
|
+
font-weight: 600;
|
|
2189
|
+
color: #4b5563;
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2192
|
+
.ai-building-block__dots {
|
|
2193
|
+
display: flex;
|
|
2194
|
+
align-items: center;
|
|
2195
|
+
gap: 4px;
|
|
2196
|
+
}
|
|
2197
|
+
|
|
2198
|
+
.ai-building-block__dot {
|
|
2199
|
+
width: 5px;
|
|
2200
|
+
height: 5px;
|
|
2201
|
+
border-radius: 50%;
|
|
2202
|
+
background: #9ca3af;
|
|
2203
|
+
animation: typing 1.4s infinite;
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
.ai-building-block__dots .ai-building-block__dot:nth-child(2) {
|
|
2207
|
+
animation-delay: 0.2s;
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
.ai-building-block__dots .ai-building-block__dot:nth-child(3) {
|
|
2211
|
+
animation-delay: 0.4s;
|
|
2212
|
+
}
|
|
2213
|
+
|
|
1805
2214
|
/* ── Input Area ── */
|
|
1806
2215
|
|
|
1807
2216
|
.ai-chat-input-form {
|
|
@@ -1917,47 +2326,61 @@
|
|
|
1917
2326
|
/* ── Print (Single Response) ── */
|
|
1918
2327
|
|
|
1919
2328
|
@media print {
|
|
1920
|
-
@page {
|
|
1921
|
-
|
|
2329
|
+
@page { margin: 12mm; }
|
|
2330
|
+
|
|
2331
|
+
/*
|
|
2332
|
+
* visibility:hidden on body allows #ai-cortex-print-section descendants to
|
|
2333
|
+
* override with visibility:visible — this is a CSS guarantee that display:none
|
|
2334
|
+
* does NOT offer (Chrome's print engine ignores the specificity override for
|
|
2335
|
+
* display:none !important on body > *).
|
|
2336
|
+
*
|
|
2337
|
+
* Siblings are collapsed to height:0 so no blank space precedes the section.
|
|
2338
|
+
* position:absolute (not fixed) allows content to paginate across pages.
|
|
2339
|
+
*/
|
|
2340
|
+
body.ai-chat-printing {
|
|
2341
|
+
visibility: hidden !important;
|
|
2342
|
+
position: relative !important;
|
|
1922
2343
|
}
|
|
1923
2344
|
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
2345
|
+
body.ai-chat-printing > *:not(#ai-cortex-print-section) {
|
|
2346
|
+
height: 0 !important;
|
|
2347
|
+
overflow: hidden !important;
|
|
1927
2348
|
}
|
|
1928
2349
|
|
|
1929
2350
|
body.ai-chat-printing #ai-cortex-print-section {
|
|
2351
|
+
visibility: visible !important;
|
|
1930
2352
|
display: block !important;
|
|
2353
|
+
position: absolute !important;
|
|
2354
|
+
top: 0 !important;
|
|
2355
|
+
left: 0 !important;
|
|
2356
|
+
width: 100% !important;
|
|
2357
|
+
padding: 0 !important;
|
|
2358
|
+
background: #ffffff;
|
|
2359
|
+
color: #1f2937;
|
|
2360
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
2361
|
+
font-size: 14px;
|
|
2362
|
+
line-height: 1.6;
|
|
1931
2363
|
}
|
|
1932
2364
|
|
|
1933
|
-
/*
|
|
1934
|
-
* Kill all CSS animations and transitions inside the print section.
|
|
1935
|
-
* Browsers reset animations during the print reflow, catching elements at
|
|
1936
|
-
* their `from` keyframe (opacity: 0, scale: 0) rather than their final state.
|
|
1937
|
-
* Disabling animations lets elements fall back to their base CSS styles,
|
|
1938
|
-
* which are always the fully-visible final appearance.
|
|
1939
|
-
*
|
|
1940
|
-
* print-color-adjust: exact forces Chrome to render background colours and
|
|
1941
|
-
* images — without it Chrome strips inline background fills (e.g. dot colours
|
|
1942
|
-
* on scatter/dot charts) and the dots appear as white outlines only.
|
|
1943
|
-
*/
|
|
1944
2365
|
body.ai-chat-printing #ai-cortex-print-section * {
|
|
2366
|
+
visibility: visible !important;
|
|
1945
2367
|
animation: none !important;
|
|
1946
2368
|
transition: none !important;
|
|
2369
|
+
/* Kill any opacity:0 left by a stopped animation */
|
|
2370
|
+
opacity: 1 !important;
|
|
1947
2371
|
-webkit-print-color-adjust: exact !important;
|
|
1948
2372
|
print-color-adjust: exact !important;
|
|
1949
2373
|
}
|
|
1950
2374
|
|
|
1951
|
-
/* Clean up the bubble for print */
|
|
1952
2375
|
body.ai-chat-printing #ai-cortex-print-section .ai-chat-bubble.assistant {
|
|
1953
|
-
max-width: none;
|
|
1954
|
-
width: 100
|
|
1955
|
-
border: none;
|
|
1956
|
-
border-radius: 0;
|
|
1957
|
-
padding: 0;
|
|
1958
|
-
background: #ffffff;
|
|
1959
|
-
color: #
|
|
1960
|
-
box-shadow: none;
|
|
2376
|
+
max-width: none !important;
|
|
2377
|
+
width: 100% !important;
|
|
2378
|
+
border: none !important;
|
|
2379
|
+
border-radius: 0 !important;
|
|
2380
|
+
padding: 0 !important;
|
|
2381
|
+
background: #ffffff !important;
|
|
2382
|
+
color: #1f2937 !important;
|
|
2383
|
+
box-shadow: none !important;
|
|
1961
2384
|
}
|
|
1962
2385
|
}
|
|
1963
2386
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import React, { useRef, useEffect } from 'react';
|
|
2
2
|
import Message from './Message';
|
|
3
3
|
|
|
4
|
+
const DEFAULT_SUGGESTIONS = [
|
|
5
|
+
'Give me brief tips for navigating iLink.',
|
|
6
|
+
'What should I check before starting a dispatch?',
|
|
7
|
+
'How do I narrow down a search in Hermes command search (⌘K)?',
|
|
8
|
+
];
|
|
9
|
+
|
|
4
10
|
/**
|
|
5
|
-
*
|
|
11
|
+
* Orchid AI chat window (Markdown + optional orchid-ai-chart fenced blocks).
|
|
6
12
|
*/
|
|
7
13
|
export default function ChatWindow({
|
|
8
14
|
messages,
|
|
@@ -11,15 +17,24 @@ export default function ChatWindow({
|
|
|
11
17
|
onSuggestionClick,
|
|
12
18
|
aiEnabled,
|
|
13
19
|
organisationName,
|
|
20
|
+
appName = "Hermes Chat",
|
|
21
|
+
unavailableMessage,
|
|
22
|
+
emptyDescription,
|
|
23
|
+
suggestions = DEFAULT_SUGGESTIONS,
|
|
24
|
+
suggestionsDisabled = false,
|
|
25
|
+
showProcessTracePanel = true,
|
|
14
26
|
}) {
|
|
27
|
+
const exportPrefix = appName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
|
|
15
28
|
const bottomRef = useRef(null);
|
|
16
29
|
|
|
17
30
|
useEffect(() => {
|
|
18
31
|
bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
|
|
19
|
-
}, [messages, loading]);
|
|
32
|
+
}, [messages, loading, statusText]);
|
|
20
33
|
|
|
21
34
|
const renderEmptyState = () => {
|
|
22
35
|
if (!aiEnabled) {
|
|
36
|
+
const msg = unavailableMessage ??
|
|
37
|
+
`${appName} needs an Anthropic API key on the server. Contact your administrator if this persists.`;
|
|
23
38
|
return (
|
|
24
39
|
<div className="ai-chat-empty">
|
|
25
40
|
<div className="ai-chat-empty-icon">
|
|
@@ -37,16 +52,14 @@ export default function ChatWindow({
|
|
|
37
52
|
<line x1="4.93" y1="4.93" x2="19.07" y2="19.07" />
|
|
38
53
|
</svg>
|
|
39
54
|
</div>
|
|
40
|
-
<h2>
|
|
41
|
-
<p>
|
|
42
|
-
Hermes Chat needs an Anthropic API key on the server and an active organisation. Contact your administrator
|
|
43
|
-
if this persists.
|
|
44
|
-
</p>
|
|
55
|
+
<h2>{appName} unavailable</h2>
|
|
56
|
+
<p>{msg}</p>
|
|
45
57
|
</div>
|
|
46
58
|
);
|
|
47
59
|
}
|
|
48
60
|
|
|
49
61
|
const scope = organisationName || 'your organisation';
|
|
62
|
+
const description = emptyDescription ?? `Ask about ${scope} — shipments, schedules, data insights, or what to explore next.`;
|
|
50
63
|
|
|
51
64
|
return (
|
|
52
65
|
<div className="ai-chat-empty">
|
|
@@ -67,32 +80,53 @@ export default function ChatWindow({
|
|
|
67
80
|
</svg>
|
|
68
81
|
</div>
|
|
69
82
|
<h2>How can I help?</h2>
|
|
70
|
-
<p>{
|
|
71
|
-
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
<p>{description}</p>
|
|
84
|
+
{suggestions.length > 0 && (
|
|
85
|
+
<div className={`ai-chat-suggestions${suggestionsDisabled ? ' ai-chat-suggestions--disabled' : ''}`}>
|
|
86
|
+
<span>Try asking:</span>
|
|
87
|
+
<ul>
|
|
88
|
+
{suggestions.map((s) => (
|
|
89
|
+
<li
|
|
90
|
+
key={s}
|
|
91
|
+
onClick={suggestionsDisabled ? undefined : () => onSuggestionClick(s)}
|
|
92
|
+
aria-disabled={suggestionsDisabled || undefined}
|
|
93
|
+
>
|
|
94
|
+
{s}
|
|
95
|
+
</li>
|
|
96
|
+
))}
|
|
97
|
+
</ul>
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
85
100
|
</div>
|
|
86
101
|
);
|
|
87
102
|
};
|
|
88
103
|
|
|
104
|
+
const lastMsg = messages?.[messages.length - 1];
|
|
105
|
+
const hasStreamingMessage = lastMsg?.isStreaming === true;
|
|
106
|
+
|
|
89
107
|
return (
|
|
90
108
|
<div className="ai-chat-window">
|
|
91
109
|
{messages?.length === 0 && !loading && renderEmptyState()}
|
|
92
|
-
{(messages ?? []).map((msg, i) =>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
110
|
+
{(messages ?? []).map((msg, i) => {
|
|
111
|
+
const isLast = i === (messages?.length ?? 0) - 1;
|
|
112
|
+
const streamingStatusText =
|
|
113
|
+
loading && isLast && msg.role === 'assistant' && msg.isStreaming ? statusText : undefined;
|
|
114
|
+
return (
|
|
115
|
+
<Message
|
|
116
|
+
key={i}
|
|
117
|
+
role={msg.role}
|
|
118
|
+
content={msg.content}
|
|
119
|
+
truncated={msg.truncated}
|
|
120
|
+
exportPrefix={exportPrefix}
|
|
121
|
+
isStreaming={msg.isStreaming}
|
|
122
|
+
streamingStatusText={streamingStatusText}
|
|
123
|
+
processTrace={msg.processTrace}
|
|
124
|
+
processInterimLive={msg.processInterimLive}
|
|
125
|
+
showProcessTracePanel={showProcessTracePanel}
|
|
126
|
+
/>
|
|
127
|
+
);
|
|
128
|
+
})}
|
|
129
|
+
{loading && !hasStreamingMessage && (
|
|
96
130
|
<div className="ai-chat-message assistant">
|
|
97
131
|
<div className="ai-chat-avatar assistant">AI</div>
|
|
98
132
|
<div className="ai-chat-bubble assistant">
|