@budibase/frontend-core 3.26.0 → 3.26.2
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/package.json +2 -2
- package/src/components/Chatbox/index.svelte +362 -64
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/frontend-core",
|
|
3
|
-
"version": "3.26.
|
|
3
|
+
"version": "3.26.2",
|
|
4
4
|
"description": "Budibase frontend core libraries used in builder and client",
|
|
5
5
|
"author": "Budibase",
|
|
6
6
|
"license": "MPL-2.0",
|
|
@@ -19,5 +19,5 @@
|
|
|
19
19
|
"shortid": "2.2.15",
|
|
20
20
|
"socket.io-client": "^4.7.5"
|
|
21
21
|
},
|
|
22
|
-
"gitHead": "
|
|
22
|
+
"gitHead": "908ec20f1124a11b0cbe3bed8d2bc4a04e856cfe"
|
|
23
23
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
notifications,
|
|
5
5
|
Icon,
|
|
6
6
|
ProgressCircle,
|
|
7
|
+
Body,
|
|
7
8
|
} from "@budibase/bbui"
|
|
8
9
|
import type {
|
|
9
10
|
ChatConversation,
|
|
@@ -11,7 +12,6 @@
|
|
|
11
12
|
AgentMessageMetadata,
|
|
12
13
|
} from "@budibase/types"
|
|
13
14
|
import { Header } from "@budibase/shared-core"
|
|
14
|
-
import BBAI from "../../icons/BBAI.svelte"
|
|
15
15
|
import { tick } from "svelte"
|
|
16
16
|
import { createAPIClient } from "@budibase/frontend-core"
|
|
17
17
|
import { Chat } from "@ai-sdk/svelte"
|
|
@@ -30,16 +30,20 @@
|
|
|
30
30
|
workspaceId: string
|
|
31
31
|
chat: ChatConversationLike
|
|
32
32
|
persistConversation?: boolean
|
|
33
|
+
conversationStarters?: { prompt: string }[]
|
|
33
34
|
onchatsaved?: (_event: {
|
|
34
35
|
detail: { chatId?: string; chat: ChatConversationLike }
|
|
35
36
|
}) => void
|
|
37
|
+
isAgentPreviewChat?: boolean
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
let {
|
|
39
41
|
workspaceId,
|
|
40
42
|
chat = $bindable(),
|
|
41
43
|
persistConversation = true,
|
|
44
|
+
conversationStarters = [],
|
|
42
45
|
onchatsaved,
|
|
46
|
+
isAgentPreviewChat = false,
|
|
43
47
|
}: Props = $props()
|
|
44
48
|
|
|
45
49
|
let API = $state(
|
|
@@ -56,10 +60,59 @@
|
|
|
56
60
|
let textareaElement = $state<HTMLTextAreaElement>()
|
|
57
61
|
let expandedTools = $state<Record<string, boolean>>({})
|
|
58
62
|
let inputValue = $state("")
|
|
63
|
+
let reasoningTimers = $state<Record<string, number>>({})
|
|
64
|
+
|
|
65
|
+
$effect(() => {
|
|
66
|
+
const interval = setInterval(() => {
|
|
67
|
+
let updated = false
|
|
68
|
+
const newTimers = { ...reasoningTimers }
|
|
69
|
+
|
|
70
|
+
for (const message of messages) {
|
|
71
|
+
if (message.role !== "assistant") continue
|
|
72
|
+
const createdAt = message.metadata?.createdAt
|
|
73
|
+
const completedAt = message.metadata?.completedAt
|
|
74
|
+
|
|
75
|
+
for (const [index, part] of (message.parts ?? []).entries()) {
|
|
76
|
+
if (!isReasoningUIPart(part)) continue
|
|
77
|
+
|
|
78
|
+
const id = `${message.id}-reasoning-${index}`
|
|
79
|
+
|
|
80
|
+
if (completedAt && createdAt) {
|
|
81
|
+
const finalElapsed = (completedAt - createdAt) / 1000
|
|
82
|
+
if (newTimers[id] !== finalElapsed) {
|
|
83
|
+
newTimers[id] = finalElapsed
|
|
84
|
+
updated = true
|
|
85
|
+
}
|
|
86
|
+
} else if (part.state === "streaming" && createdAt) {
|
|
87
|
+
const newElapsed = (Date.now() - createdAt) / 1000
|
|
88
|
+
if (newTimers[id] !== newElapsed) {
|
|
89
|
+
newTimers[id] = newElapsed
|
|
90
|
+
updated = true
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (updated) {
|
|
97
|
+
reasoningTimers = newTimers
|
|
98
|
+
}
|
|
99
|
+
}, 100)
|
|
100
|
+
|
|
101
|
+
return () => clearInterval(interval)
|
|
102
|
+
})
|
|
59
103
|
|
|
60
104
|
let resolvedChatAppId = $state<string | undefined>()
|
|
61
105
|
let resolvedConversationId = $state<string | undefined>()
|
|
62
106
|
|
|
107
|
+
const applyConversationStarter = async (starterPrompt: string) => {
|
|
108
|
+
if (isBusy) {
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
inputValue = starterPrompt
|
|
112
|
+
await sendMessage()
|
|
113
|
+
tick().then(() => textareaElement?.focus())
|
|
114
|
+
}
|
|
115
|
+
|
|
63
116
|
const chatInstance = new Chat<UIMessage<AgentMessageMetadata>>({
|
|
64
117
|
transport: new DefaultChatTransport({
|
|
65
118
|
headers: () => ({ [Header.APP_ID]: workspaceId }),
|
|
@@ -116,6 +169,13 @@
|
|
|
116
169
|
let isBusy = $derived(
|
|
117
170
|
chatInstance.status === "streaming" || chatInstance.status === "submitted"
|
|
118
171
|
)
|
|
172
|
+
let hasMessages = $derived(Boolean(chat?.messages?.length))
|
|
173
|
+
let showConversationStarters = $derived(
|
|
174
|
+
!isBusy &&
|
|
175
|
+
!hasMessages &&
|
|
176
|
+
conversationStarters.length > 0 &&
|
|
177
|
+
!isAgentPreviewChat
|
|
178
|
+
)
|
|
119
179
|
|
|
120
180
|
let lastChatId = $state<string | undefined>(chat?._id)
|
|
121
181
|
$effect(() => {
|
|
@@ -285,6 +345,36 @@
|
|
|
285
345
|
|
|
286
346
|
<div class="chat-area" bind:this={chatAreaElement}>
|
|
287
347
|
<div class="chatbox">
|
|
348
|
+
{#if showConversationStarters}
|
|
349
|
+
<div class="starter-section">
|
|
350
|
+
<div class="starter-title">Conversation starters</div>
|
|
351
|
+
<div class="starter-grid">
|
|
352
|
+
{#each conversationStarters as starter, index (index)}
|
|
353
|
+
<button
|
|
354
|
+
type="button"
|
|
355
|
+
class="starter-card"
|
|
356
|
+
onclick={() => applyConversationStarter(starter.prompt)}
|
|
357
|
+
>
|
|
358
|
+
{starter.prompt}
|
|
359
|
+
</button>
|
|
360
|
+
{/each}
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
{:else}
|
|
364
|
+
<div class="empty-state">
|
|
365
|
+
<div class="empty-state-icon">
|
|
366
|
+
<Icon
|
|
367
|
+
name="chat-circle"
|
|
368
|
+
size="L"
|
|
369
|
+
weight="fill"
|
|
370
|
+
color="var(--spectrum-global-color-gray-500)"
|
|
371
|
+
/>
|
|
372
|
+
</div>
|
|
373
|
+
<Body size="S" color="var(--spectrum-global-color-gray-700)">
|
|
374
|
+
Your conversation will appear here.
|
|
375
|
+
</Body>
|
|
376
|
+
</div>
|
|
377
|
+
{/if}
|
|
288
378
|
{#each messages as message (message.id)}
|
|
289
379
|
{#if message.role === "user"}
|
|
290
380
|
<div class="message user">
|
|
@@ -292,13 +382,46 @@
|
|
|
292
382
|
</div>
|
|
293
383
|
{:else if message.role === "assistant"}
|
|
294
384
|
<div class="message assistant">
|
|
295
|
-
{#each message.parts
|
|
385
|
+
{#each message.parts ?? [] as part, partIndex}
|
|
296
386
|
{#if isTextUIPart(part)}
|
|
297
387
|
<MarkdownViewer value={part.text} />
|
|
298
388
|
{:else if isReasoningUIPart(part)}
|
|
389
|
+
{@const reasoningId = `${message.id}-reasoning-${partIndex}`}
|
|
299
390
|
<div class="reasoning-part">
|
|
300
|
-
<
|
|
301
|
-
|
|
391
|
+
<button
|
|
392
|
+
class="reasoning-toggle"
|
|
393
|
+
type="button"
|
|
394
|
+
onclick={() =>
|
|
395
|
+
(expandedTools = {
|
|
396
|
+
...expandedTools,
|
|
397
|
+
[reasoningId]: !expandedTools[reasoningId],
|
|
398
|
+
})}
|
|
399
|
+
>
|
|
400
|
+
<span
|
|
401
|
+
class="reasoning-icon"
|
|
402
|
+
class:shimmer={part.state === "streaming"}
|
|
403
|
+
>
|
|
404
|
+
<Icon
|
|
405
|
+
name="brain"
|
|
406
|
+
size="M"
|
|
407
|
+
color="var(--spectrum-global-color-gray-600)"
|
|
408
|
+
/>
|
|
409
|
+
</span>
|
|
410
|
+
<span
|
|
411
|
+
class="reasoning-label"
|
|
412
|
+
class:shimmer={part.state === "streaming"}
|
|
413
|
+
>
|
|
414
|
+
{part.state === "streaming" ? "Thinking" : "Thought for"}
|
|
415
|
+
{#if reasoningTimers[reasoningId]}
|
|
416
|
+
<span class="reasoning-timer"
|
|
417
|
+
>{reasoningTimers[reasoningId].toFixed(1)}s</span
|
|
418
|
+
>
|
|
419
|
+
{/if}
|
|
420
|
+
</span>
|
|
421
|
+
</button>
|
|
422
|
+
{#if expandedTools[reasoningId]}
|
|
423
|
+
<div class="reasoning-content">{part.text}</div>
|
|
424
|
+
{/if}
|
|
302
425
|
</div>
|
|
303
426
|
{:else if isToolUIPart(part)}
|
|
304
427
|
{@const toolId = `${message.id}-${getToolName(part)}-${partIndex}`}
|
|
@@ -310,6 +433,7 @@
|
|
|
310
433
|
<div class="tool-part" class:tool-running={isRunning}>
|
|
311
434
|
<button
|
|
312
435
|
class="tool-header"
|
|
436
|
+
class:tool-header-expanded={expandedTools[toolId]}
|
|
313
437
|
type="button"
|
|
314
438
|
onclick={() => toggleTool(toolId)}
|
|
315
439
|
>
|
|
@@ -317,29 +441,40 @@
|
|
|
317
441
|
class="tool-chevron"
|
|
318
442
|
class:expanded={expandedTools[toolId]}
|
|
319
443
|
>
|
|
320
|
-
<
|
|
321
|
-
</span>
|
|
322
|
-
<span class="tool-icon">
|
|
323
|
-
<Icon name="wrench" size="S" />
|
|
324
|
-
</span>
|
|
325
|
-
<span class="tool-name">{getToolName(part)}</span>
|
|
326
|
-
<span class="tool-status">
|
|
327
|
-
{#if isRunning}
|
|
328
|
-
<ProgressCircle size="S" />
|
|
329
|
-
{:else if isSuccess}
|
|
444
|
+
<span class="tool-chevron-icon tool-chevron-icon-default">
|
|
330
445
|
<Icon
|
|
331
|
-
name="
|
|
332
|
-
size="
|
|
333
|
-
|
|
446
|
+
name="globe-simple"
|
|
447
|
+
size="M"
|
|
448
|
+
weight="regular"
|
|
449
|
+
color="var(--spectrum-global-color-gray-600)"
|
|
334
450
|
/>
|
|
335
|
-
|
|
451
|
+
</span>
|
|
452
|
+
<span class="tool-chevron-icon tool-chevron-icon-expanded">
|
|
336
453
|
<Icon
|
|
337
|
-
name="
|
|
338
|
-
size="
|
|
339
|
-
|
|
454
|
+
name="minus"
|
|
455
|
+
size="M"
|
|
456
|
+
weight="regular"
|
|
457
|
+
color="var(--spectrum-global-color-gray-600)"
|
|
340
458
|
/>
|
|
341
|
-
|
|
459
|
+
</span>
|
|
342
460
|
</span>
|
|
461
|
+
<span class="tool-call-label">Tool call</span>
|
|
462
|
+
<div class="tool-name-wrapper">
|
|
463
|
+
<span class="tool-name">{getToolName(part)}</span>
|
|
464
|
+
</div>
|
|
465
|
+
{#if isRunning || isError}
|
|
466
|
+
<span class="tool-status">
|
|
467
|
+
{#if isRunning}
|
|
468
|
+
<ProgressCircle size="S" />
|
|
469
|
+
{:else if isError}
|
|
470
|
+
<Icon
|
|
471
|
+
name="x"
|
|
472
|
+
size="S"
|
|
473
|
+
color="var(--spectrum-global-color-red-600)"
|
|
474
|
+
/>
|
|
475
|
+
{/if}
|
|
476
|
+
</span>
|
|
477
|
+
{/if}
|
|
343
478
|
</button>
|
|
344
479
|
{#if expandedTools[toolId]}
|
|
345
480
|
<div class="tool-details">
|
|
@@ -394,11 +529,6 @@
|
|
|
394
529
|
</div>
|
|
395
530
|
{/if}
|
|
396
531
|
{/each}
|
|
397
|
-
{#if isBusy}
|
|
398
|
-
<div class="message system">
|
|
399
|
-
<BBAI size="48px" animate />
|
|
400
|
-
</div>
|
|
401
|
-
{/if}
|
|
402
532
|
</div>
|
|
403
533
|
|
|
404
534
|
<div class="input-wrapper">
|
|
@@ -415,11 +545,11 @@
|
|
|
415
545
|
|
|
416
546
|
<style>
|
|
417
547
|
.chat-area {
|
|
418
|
-
flex: 1 1
|
|
548
|
+
flex: 1 1 0;
|
|
419
549
|
display: flex;
|
|
420
550
|
flex-direction: column;
|
|
421
551
|
overflow-y: auto;
|
|
422
|
-
height: 0;
|
|
552
|
+
min-height: 0;
|
|
423
553
|
}
|
|
424
554
|
.chatbox {
|
|
425
555
|
display: flex;
|
|
@@ -430,9 +560,59 @@
|
|
|
430
560
|
padding: 48px 0 24px 0;
|
|
431
561
|
}
|
|
432
562
|
|
|
563
|
+
.empty-state {
|
|
564
|
+
display: flex;
|
|
565
|
+
flex-direction: column;
|
|
566
|
+
align-items: center;
|
|
567
|
+
justify-content: center;
|
|
568
|
+
gap: 8px;
|
|
569
|
+
flex: 1 1 auto;
|
|
570
|
+
min-height: 0;
|
|
571
|
+
width: 100%;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.empty-state-icon {
|
|
575
|
+
--size: 24px;
|
|
576
|
+
}
|
|
577
|
+
.starter-section {
|
|
578
|
+
display: flex;
|
|
579
|
+
flex-direction: column;
|
|
580
|
+
gap: var(--spacing-s);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
.starter-title {
|
|
584
|
+
font-size: 12px;
|
|
585
|
+
text-transform: uppercase;
|
|
586
|
+
letter-spacing: 0.08em;
|
|
587
|
+
color: var(--spectrum-global-color-gray-600);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.starter-grid {
|
|
591
|
+
display: grid;
|
|
592
|
+
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
|
593
|
+
gap: var(--spacing-s);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
.starter-card {
|
|
597
|
+
border: 1px solid var(--grey-3);
|
|
598
|
+
border-radius: 12px;
|
|
599
|
+
padding: var(--spacing-m);
|
|
600
|
+
background: var(--grey-2);
|
|
601
|
+
color: var(--spectrum-global-color-gray-900);
|
|
602
|
+
font: inherit;
|
|
603
|
+
text-align: left;
|
|
604
|
+
cursor: pointer;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
.starter-card:hover {
|
|
608
|
+
border-color: var(--grey-4);
|
|
609
|
+
background: var(--grey-1);
|
|
610
|
+
}
|
|
611
|
+
|
|
433
612
|
.message {
|
|
434
613
|
display: flex;
|
|
435
614
|
flex-direction: column;
|
|
615
|
+
gap: 16px;
|
|
436
616
|
max-width: 80%;
|
|
437
617
|
padding: var(--spacing-l);
|
|
438
618
|
border-radius: 20px;
|
|
@@ -441,14 +621,22 @@
|
|
|
441
621
|
}
|
|
442
622
|
|
|
443
623
|
.message.user {
|
|
624
|
+
border-radius: 8px;
|
|
444
625
|
align-self: flex-end;
|
|
445
|
-
background-color:
|
|
626
|
+
background-color: #215f9e33;
|
|
627
|
+
font-size: 14px;
|
|
628
|
+
color: var(--spectrum-global-color-gray-800);
|
|
446
629
|
}
|
|
447
630
|
|
|
448
631
|
.message.assistant {
|
|
449
632
|
align-self: flex-start;
|
|
450
|
-
background-color:
|
|
451
|
-
border:
|
|
633
|
+
background-color: transparent;
|
|
634
|
+
border: none;
|
|
635
|
+
padding: 0;
|
|
636
|
+
font-size: 14px;
|
|
637
|
+
color: var(--spectrum-global-color-gray-800);
|
|
638
|
+
line-height: 1.4;
|
|
639
|
+
max-width: 100%;
|
|
452
640
|
}
|
|
453
641
|
|
|
454
642
|
.message.system {
|
|
@@ -463,6 +651,8 @@
|
|
|
463
651
|
width: 100%;
|
|
464
652
|
display: flex;
|
|
465
653
|
flex-direction: column;
|
|
654
|
+
flex-shrink: 0;
|
|
655
|
+
line-height: 1.4;
|
|
466
656
|
}
|
|
467
657
|
|
|
468
658
|
.input {
|
|
@@ -472,21 +662,39 @@
|
|
|
472
662
|
resize: none;
|
|
473
663
|
padding: 20px;
|
|
474
664
|
font-size: 16px;
|
|
475
|
-
background-color: var(--
|
|
665
|
+
background-color: var(--spectrum-global-color-gray-200);
|
|
476
666
|
color: var(--grey-9);
|
|
477
|
-
border-radius:
|
|
478
|
-
border:
|
|
667
|
+
border-radius: 10px;
|
|
668
|
+
border: 1px solid var(--spectrum-global-color-gray-300) !important;
|
|
479
669
|
outline: none;
|
|
480
670
|
min-height: 100px;
|
|
481
671
|
}
|
|
482
672
|
|
|
673
|
+
.input:focus {
|
|
674
|
+
border: 1px solid #215f9e33 !important;
|
|
675
|
+
}
|
|
676
|
+
|
|
483
677
|
.input::placeholder {
|
|
484
678
|
color: var(--spectrum-global-color-gray-600);
|
|
485
679
|
}
|
|
486
680
|
|
|
487
681
|
/* Style the markdown tool sections in assistant messages */
|
|
488
682
|
:global(.assistant strong) {
|
|
489
|
-
color: var(--spectrum-global-color-
|
|
683
|
+
color: var(--spectrum-global-color-gray-900);
|
|
684
|
+
font-weight: 500;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
:global(.assistant .markdown-viewer p) {
|
|
688
|
+
margin-top: 8px;
|
|
689
|
+
margin-bottom: 8px;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
:global(.assistant .markdown-viewer p:first-child) {
|
|
693
|
+
margin-top: 0;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
:global(.assistant .markdown-viewer p:last-child) {
|
|
697
|
+
margin-bottom: 0;
|
|
490
698
|
}
|
|
491
699
|
|
|
492
700
|
:global(.assistant h3) {
|
|
@@ -500,37 +708,37 @@
|
|
|
500
708
|
border-radius: 4px;
|
|
501
709
|
}
|
|
502
710
|
|
|
711
|
+
:global(.assistant ul) {
|
|
712
|
+
padding-inline-start: 20px;
|
|
713
|
+
}
|
|
714
|
+
|
|
503
715
|
/* Tool parts styling */
|
|
504
|
-
.tool-part {
|
|
505
|
-
margin:
|
|
506
|
-
padding: var(--spacing-m);
|
|
507
|
-
background-color: var(--grey-2);
|
|
508
|
-
border: 1px solid var(--grey-3);
|
|
509
|
-
border-radius: 8px;
|
|
510
|
-
transition: border-color 0.2s ease;
|
|
716
|
+
.tool-part + .tool-part {
|
|
717
|
+
margin-top: 2px;
|
|
511
718
|
}
|
|
512
719
|
|
|
513
|
-
.tool-part
|
|
514
|
-
|
|
720
|
+
.tool-part {
|
|
721
|
+
position: relative;
|
|
722
|
+
margin-top: var(--spacing-l);
|
|
723
|
+
margin-bottom: 0;
|
|
515
724
|
}
|
|
516
725
|
|
|
517
726
|
.tool-header {
|
|
518
727
|
display: flex;
|
|
519
728
|
align-items: center;
|
|
520
|
-
gap:
|
|
521
|
-
width: 100%;
|
|
729
|
+
gap: 8px;
|
|
522
730
|
padding: 0;
|
|
523
731
|
margin: 0;
|
|
524
732
|
background: none;
|
|
525
733
|
border: none;
|
|
734
|
+
border-radius: 4px;
|
|
526
735
|
cursor: pointer;
|
|
527
|
-
font-weight: 600;
|
|
528
736
|
font-size: 14px;
|
|
529
737
|
text-align: left;
|
|
530
738
|
}
|
|
531
739
|
|
|
532
740
|
.tool-header:hover {
|
|
533
|
-
|
|
741
|
+
background-color: var(--spectrum-global-color-gray-100);
|
|
534
742
|
}
|
|
535
743
|
|
|
536
744
|
.tool-chevron {
|
|
@@ -541,20 +749,59 @@
|
|
|
541
749
|
color: var(--spectrum-global-color-gray-600);
|
|
542
750
|
}
|
|
543
751
|
|
|
752
|
+
.tool-chevron :global(i) {
|
|
753
|
+
--size: 16px !important;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
.tool-chevron-icon-expanded :global(i) {
|
|
757
|
+
--size: 16px !important;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
.tool-chevron-icon {
|
|
761
|
+
display: flex;
|
|
762
|
+
align-items: center;
|
|
763
|
+
justify-content: center;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
.tool-chevron-icon-expanded {
|
|
767
|
+
display: none;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
.tool-header-expanded .tool-chevron-icon-default {
|
|
771
|
+
display: none !important;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
.tool-header-expanded .tool-chevron-icon-expanded {
|
|
775
|
+
display: flex !important;
|
|
776
|
+
}
|
|
777
|
+
|
|
544
778
|
.tool-chevron.expanded {
|
|
545
779
|
transform: rotate(90deg);
|
|
546
780
|
}
|
|
547
781
|
|
|
548
|
-
.tool-
|
|
782
|
+
.tool-header-expanded .tool-chevron {
|
|
783
|
+
transform: none;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
.tool-call-label {
|
|
787
|
+
font-size: 14px;
|
|
788
|
+
color: var(--spectrum-global-color-gray-900);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.tool-name-wrapper {
|
|
549
792
|
display: flex;
|
|
550
793
|
align-items: center;
|
|
551
|
-
|
|
552
|
-
|
|
794
|
+
gap: var(--spacing-s);
|
|
795
|
+
padding: 3px 6px;
|
|
796
|
+
background-color: var(--spectrum-global-color-gray-200);
|
|
797
|
+
border-radius: 4px;
|
|
553
798
|
}
|
|
554
799
|
|
|
555
800
|
.tool-name {
|
|
556
|
-
color: var(--spectrum-global-color-gray-900);
|
|
557
801
|
font-family: var(--font-mono), monospace;
|
|
802
|
+
font-size: 13px;
|
|
803
|
+
color: var(--spectrum-global-color-gray-800);
|
|
804
|
+
font-weight: 400;
|
|
558
805
|
}
|
|
559
806
|
|
|
560
807
|
.tool-status {
|
|
@@ -565,10 +812,24 @@
|
|
|
565
812
|
}
|
|
566
813
|
|
|
567
814
|
.tool-details {
|
|
815
|
+
position: absolute;
|
|
816
|
+
top: 100%;
|
|
817
|
+
left: 0;
|
|
568
818
|
margin-top: var(--spacing-m);
|
|
819
|
+
width: 100%;
|
|
820
|
+
max-width: 100%;
|
|
821
|
+
box-sizing: border-box;
|
|
569
822
|
display: flex;
|
|
570
823
|
flex-direction: column;
|
|
571
824
|
gap: var(--spacing-s);
|
|
825
|
+
background: var(--background);
|
|
826
|
+
border: 1px solid var(--spectrum-global-color-gray-200);
|
|
827
|
+
border-radius: 6px;
|
|
828
|
+
padding: var(--spacing-m);
|
|
829
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
|
|
830
|
+
z-index: 1;
|
|
831
|
+
overflow-x: hidden;
|
|
832
|
+
min-width: 0;
|
|
572
833
|
}
|
|
573
834
|
|
|
574
835
|
.tool-section {
|
|
@@ -592,12 +853,14 @@
|
|
|
592
853
|
padding: var(--spacing-s);
|
|
593
854
|
font-size: 12px;
|
|
594
855
|
font-family: var(--font-mono), monospace;
|
|
595
|
-
overflow-x: auto;
|
|
596
856
|
white-space: pre-wrap;
|
|
597
857
|
word-break: break-word;
|
|
858
|
+
overflow-wrap: break-word;
|
|
598
859
|
margin: 0;
|
|
599
860
|
max-height: 200px;
|
|
600
861
|
overflow-y: auto;
|
|
862
|
+
overflow-x: hidden;
|
|
863
|
+
min-width: 0;
|
|
601
864
|
}
|
|
602
865
|
|
|
603
866
|
.tool-error .tool-section-label {
|
|
@@ -611,26 +874,61 @@
|
|
|
611
874
|
|
|
612
875
|
/* Reasoning parts styling */
|
|
613
876
|
.reasoning-part {
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
877
|
+
display: flex;
|
|
878
|
+
flex-direction: column;
|
|
879
|
+
gap: 8px;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.reasoning-toggle {
|
|
883
|
+
display: flex;
|
|
884
|
+
align-items: center;
|
|
885
|
+
gap: 6px;
|
|
886
|
+
padding: 0;
|
|
887
|
+
margin: 0;
|
|
888
|
+
background: none;
|
|
889
|
+
border: none;
|
|
890
|
+
cursor: pointer;
|
|
618
891
|
border-radius: 4px;
|
|
619
892
|
}
|
|
620
893
|
|
|
894
|
+
.reasoning-icon {
|
|
895
|
+
display: flex;
|
|
896
|
+
align-items: center;
|
|
897
|
+
justify-content: center;
|
|
898
|
+
flex-shrink: 0;
|
|
899
|
+
}
|
|
900
|
+
|
|
621
901
|
.reasoning-label {
|
|
902
|
+
font-size: 13px;
|
|
903
|
+
color: var(--spectrum-global-color-gray-600);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.reasoning-timer {
|
|
622
907
|
font-size: 12px;
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
908
|
+
color: var(--spectrum-global-color-gray-600);
|
|
909
|
+
font-weight: 400;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
.reasoning-label.shimmer,
|
|
913
|
+
.reasoning-icon.shimmer {
|
|
914
|
+
animation: shimmer 2s ease-in-out infinite;
|
|
628
915
|
}
|
|
629
916
|
|
|
630
917
|
.reasoning-content {
|
|
631
918
|
font-size: 13px;
|
|
632
|
-
color: var(--spectrum-global-color-gray-
|
|
919
|
+
color: var(--spectrum-global-color-gray-600);
|
|
633
920
|
font-style: italic;
|
|
921
|
+
line-height: 1.4;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
@keyframes shimmer {
|
|
925
|
+
0%,
|
|
926
|
+
100% {
|
|
927
|
+
opacity: 0.6;
|
|
928
|
+
}
|
|
929
|
+
50% {
|
|
930
|
+
opacity: 1;
|
|
931
|
+
}
|
|
634
932
|
}
|
|
635
933
|
|
|
636
934
|
.sources {
|