@pikku/assistant-ui 0.12.4 → 0.12.6
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/CHANGELOG.md +12 -1
- package/dist/cjs/index.d.ts +3 -0
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/model-capabilities.d.ts +1 -0
- package/dist/cjs/model-capabilities.js +16 -0
- package/dist/cjs/pikku-agent-chat.d.ts +4 -0
- package/dist/cjs/pikku-agent-chat.js +91 -63
- package/dist/cjs/use-file-attachment.d.ts +26 -0
- package/dist/cjs/use-file-attachment.js +99 -0
- package/dist/cjs/use-pikku-agent-runtime.d.ts +4 -0
- package/dist/cjs/use-pikku-agent-runtime.js +72 -35
- package/dist/esm/index.d.ts +3 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/model-capabilities.d.ts +1 -0
- package/dist/esm/model-capabilities.js +13 -0
- package/dist/esm/pikku-agent-chat.d.ts +4 -0
- package/dist/esm/pikku-agent-chat.js +102 -67
- package/dist/esm/use-file-attachment.d.ts +26 -0
- package/dist/esm/use-file-attachment.js +85 -0
- package/dist/esm/use-pikku-agent-runtime.d.ts +4 -0
- package/dist/esm/use-pikku-agent-runtime.js +72 -19
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/index.ts +3 -0
- package/src/model-capabilities.ts +14 -0
- package/src/pikku-agent-chat.tsx +362 -156
- package/src/use-file-attachment.ts +110 -0
- package/src/use-pikku-agent-runtime.ts +109 -15
package/src/pikku-agent-chat.tsx
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
4
|
+
useState,
|
|
5
|
+
useMemo,
|
|
6
|
+
useEffect,
|
|
7
|
+
useRef,
|
|
8
|
+
type ComponentType,
|
|
9
|
+
type FunctionComponent,
|
|
10
|
+
type ReactNode,
|
|
11
|
+
} from 'react'
|
|
2
12
|
import Markdown from 'react-markdown'
|
|
3
13
|
import {
|
|
4
14
|
AssistantRuntimeProvider,
|
|
5
15
|
ThreadPrimitive,
|
|
6
16
|
MessagePrimitive,
|
|
7
17
|
ComposerPrimitive,
|
|
18
|
+
useComposerRuntime,
|
|
8
19
|
type ToolCallMessagePartComponent,
|
|
9
20
|
} from '@assistant-ui/react'
|
|
10
21
|
import {
|
|
@@ -17,6 +28,7 @@ import {
|
|
|
17
28
|
} from './use-pikku-agent-runtime.js'
|
|
18
29
|
|
|
19
30
|
export interface PikkuAgentChatProps extends PikkuAgentRuntimeOptions {
|
|
31
|
+
initialPrompt?: string
|
|
20
32
|
emptyMessage?: string
|
|
21
33
|
/** Hide tool calls from the chat display.
|
|
22
34
|
* - `true`: hide all non-approval tool calls
|
|
@@ -37,6 +49,8 @@ export interface PikkuAgentChatProps extends PikkuAgentRuntimeOptions {
|
|
|
37
49
|
* (which still respects `hideToolCalls` and the approval-request UI).
|
|
38
50
|
*/
|
|
39
51
|
toolComponents?: Record<string, ToolCallMessagePartComponent>
|
|
52
|
+
renderAssistantText?: (text: string) => ReactNode
|
|
53
|
+
generativeUIComponents?: Record<string, ComponentType<any>>
|
|
40
54
|
}
|
|
41
55
|
|
|
42
56
|
interface ChatColors {
|
|
@@ -103,10 +117,18 @@ const darkColors: ChatColors = {
|
|
|
103
117
|
}
|
|
104
118
|
|
|
105
119
|
const ColorsContext = createContext<ChatColors>(lightColors)
|
|
106
|
-
const HideToolCallsContext = createContext<boolean | string[] | undefined>(
|
|
120
|
+
const HideToolCallsContext = createContext<boolean | string[] | undefined>(
|
|
121
|
+
undefined
|
|
122
|
+
)
|
|
107
123
|
const ToolComponentsContext = createContext<
|
|
108
124
|
Record<string, ToolCallMessagePartComponent> | undefined
|
|
109
125
|
>(undefined)
|
|
126
|
+
const GenerativeUIComponentsContext = createContext<
|
|
127
|
+
Record<string, ComponentType<any>> | undefined
|
|
128
|
+
>(undefined)
|
|
129
|
+
const RenderAssistantTextContext = createContext<
|
|
130
|
+
((text: string) => ReactNode) | undefined
|
|
131
|
+
>(undefined)
|
|
110
132
|
|
|
111
133
|
function shouldHideToolCall(
|
|
112
134
|
hideToolCalls: boolean | string[] | undefined,
|
|
@@ -133,9 +155,7 @@ const ToolCallDisplay: FunctionComponent<{
|
|
|
133
155
|
const approvalReason = (args as any)?.__approvalReason
|
|
134
156
|
const displayArgs = { ...args }
|
|
135
157
|
delete (displayArgs as any).__approvalReason
|
|
136
|
-
const [responded, setResponded] = useState<'approved' | 'denied' | null>(
|
|
137
|
-
null
|
|
138
|
-
)
|
|
158
|
+
const [responded, setResponded] = useState<'approved' | 'denied' | null>(null)
|
|
139
159
|
|
|
140
160
|
// Hide responded approval tool calls
|
|
141
161
|
if (isApproval && responded && shouldHideToolCall(hideToolCalls, toolName)) {
|
|
@@ -172,7 +192,9 @@ const ToolCallDisplay: FunctionComponent<{
|
|
|
172
192
|
Approval required
|
|
173
193
|
</div>
|
|
174
194
|
{approvalReason && (
|
|
175
|
-
<div style={{ fontSize: 13, marginBottom: 4, color: colors.text }}>
|
|
195
|
+
<div style={{ fontSize: 13, marginBottom: 4, color: colors.text }}>
|
|
196
|
+
{approvalReason}
|
|
197
|
+
</div>
|
|
176
198
|
)}
|
|
177
199
|
<div style={{ fontSize: 12, color: colors.textMuted, marginBottom: 4 }}>
|
|
178
200
|
The agent wants to call <code>{toolName}</code>
|
|
@@ -253,8 +275,12 @@ const ToolCallDisplay: FunctionComponent<{
|
|
|
253
275
|
fontSize: 11,
|
|
254
276
|
padding: '2px 6px',
|
|
255
277
|
borderRadius: 3,
|
|
256
|
-
background:
|
|
257
|
-
|
|
278
|
+
background:
|
|
279
|
+
responded === 'approved' ? colors.successBg : colors.errorBg,
|
|
280
|
+
color:
|
|
281
|
+
responded === 'approved'
|
|
282
|
+
? colors.successColor
|
|
283
|
+
: colors.errorColor,
|
|
258
284
|
}}
|
|
259
285
|
>
|
|
260
286
|
{responded}
|
|
@@ -292,7 +318,9 @@ const ToolCallDisplay: FunctionComponent<{
|
|
|
292
318
|
{toolName}
|
|
293
319
|
</span>
|
|
294
320
|
{status.type === 'running' && (
|
|
295
|
-
<span style={{ fontSize: 11, color: colors.textMuted }}>
|
|
321
|
+
<span style={{ fontSize: 11, color: colors.textMuted }}>
|
|
322
|
+
running...
|
|
323
|
+
</span>
|
|
296
324
|
)}
|
|
297
325
|
{status.type === 'error' && (
|
|
298
326
|
<span
|
|
@@ -349,7 +377,9 @@ const ToolCallDisplay: FunctionComponent<{
|
|
|
349
377
|
</button>
|
|
350
378
|
{expanded && (
|
|
351
379
|
<div style={{ marginTop: 8 }}>
|
|
352
|
-
<div
|
|
380
|
+
<div
|
|
381
|
+
style={{ fontSize: 12, color: colors.textMuted, marginBottom: 2 }}
|
|
382
|
+
>
|
|
353
383
|
Arguments:
|
|
354
384
|
</div>
|
|
355
385
|
<pre
|
|
@@ -367,7 +397,12 @@ const ToolCallDisplay: FunctionComponent<{
|
|
|
367
397
|
{result !== undefined && (
|
|
368
398
|
<>
|
|
369
399
|
<div
|
|
370
|
-
style={{
|
|
400
|
+
style={{
|
|
401
|
+
fontSize: 12,
|
|
402
|
+
color: colors.textMuted,
|
|
403
|
+
marginTop: 8,
|
|
404
|
+
marginBottom: 2,
|
|
405
|
+
}}
|
|
371
406
|
>
|
|
372
407
|
Result:
|
|
373
408
|
</div>
|
|
@@ -393,49 +428,141 @@ const ToolCallDisplay: FunctionComponent<{
|
|
|
393
428
|
)
|
|
394
429
|
}
|
|
395
430
|
|
|
396
|
-
const MarkdownText: FunctionComponent<{ text: string; colors: ChatColors }> = ({
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
431
|
+
const MarkdownText: FunctionComponent<{ text: string; colors: ChatColors }> = ({
|
|
432
|
+
text,
|
|
433
|
+
colors,
|
|
434
|
+
}) => {
|
|
435
|
+
const components = useMemo(
|
|
436
|
+
() => ({
|
|
437
|
+
p: ({ children }: any) => (
|
|
438
|
+
<p
|
|
439
|
+
style={{
|
|
440
|
+
margin: '0 0 8px',
|
|
441
|
+
fontSize: 14,
|
|
442
|
+
lineHeight: 1.6,
|
|
443
|
+
color: colors.text,
|
|
444
|
+
}}
|
|
445
|
+
>
|
|
446
|
+
{children}
|
|
447
|
+
</p>
|
|
448
|
+
),
|
|
449
|
+
strong: ({ children }: any) => (
|
|
450
|
+
<strong style={{ fontWeight: 600, color: colors.text }}>
|
|
451
|
+
{children}
|
|
452
|
+
</strong>
|
|
453
|
+
),
|
|
454
|
+
em: ({ children }: any) => (
|
|
455
|
+
<em style={{ color: colors.text }}>{children}</em>
|
|
456
|
+
),
|
|
457
|
+
ul: ({ children }: any) => (
|
|
458
|
+
<ul
|
|
459
|
+
style={{
|
|
460
|
+
margin: '4px 0 8px',
|
|
461
|
+
paddingLeft: 20,
|
|
462
|
+
fontSize: 14,
|
|
463
|
+
color: colors.text,
|
|
464
|
+
}}
|
|
465
|
+
>
|
|
466
|
+
{children}
|
|
467
|
+
</ul>
|
|
468
|
+
),
|
|
469
|
+
ol: ({ children }: any) => (
|
|
470
|
+
<ol
|
|
471
|
+
style={{
|
|
472
|
+
margin: '4px 0 8px',
|
|
473
|
+
paddingLeft: 20,
|
|
474
|
+
fontSize: 14,
|
|
475
|
+
color: colors.text,
|
|
476
|
+
}}
|
|
477
|
+
>
|
|
478
|
+
{children}
|
|
479
|
+
</ol>
|
|
480
|
+
),
|
|
481
|
+
li: ({ children }: any) => (
|
|
482
|
+
<li style={{ marginBottom: 2, lineHeight: 1.6 }}>{children}</li>
|
|
483
|
+
),
|
|
484
|
+
code: ({ children, className }: any) => {
|
|
485
|
+
const isBlock = className?.startsWith('language-')
|
|
486
|
+
if (isBlock) {
|
|
487
|
+
return (
|
|
488
|
+
<pre
|
|
489
|
+
style={{
|
|
490
|
+
background: colors.codeBg,
|
|
491
|
+
padding: 10,
|
|
492
|
+
borderRadius: 4,
|
|
493
|
+
overflow: 'auto',
|
|
494
|
+
margin: '4px 0 8px',
|
|
495
|
+
fontSize: 12,
|
|
496
|
+
}}
|
|
497
|
+
>
|
|
498
|
+
<code style={{ color: colors.text }}>{children}</code>
|
|
499
|
+
</pre>
|
|
500
|
+
)
|
|
501
|
+
}
|
|
419
502
|
return (
|
|
420
|
-
<
|
|
421
|
-
|
|
422
|
-
|
|
503
|
+
<code
|
|
504
|
+
style={{
|
|
505
|
+
background: colors.codeBg,
|
|
506
|
+
padding: '1px 4px',
|
|
507
|
+
borderRadius: 3,
|
|
508
|
+
fontSize: 13,
|
|
509
|
+
color: colors.text,
|
|
510
|
+
}}
|
|
511
|
+
>
|
|
512
|
+
{children}
|
|
513
|
+
</code>
|
|
423
514
|
)
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
|
|
515
|
+
},
|
|
516
|
+
pre: ({ children }: any) => <>{children}</>,
|
|
517
|
+
h1: ({ children }: any) => (
|
|
518
|
+
<h3
|
|
519
|
+
style={{
|
|
520
|
+
margin: '8px 0 4px',
|
|
521
|
+
fontSize: 16,
|
|
522
|
+
fontWeight: 600,
|
|
523
|
+
color: colors.text,
|
|
524
|
+
}}
|
|
525
|
+
>
|
|
526
|
+
{children}
|
|
527
|
+
</h3>
|
|
528
|
+
),
|
|
529
|
+
h2: ({ children }: any) => (
|
|
530
|
+
<h4
|
|
531
|
+
style={{
|
|
532
|
+
margin: '8px 0 4px',
|
|
533
|
+
fontSize: 15,
|
|
534
|
+
fontWeight: 600,
|
|
535
|
+
color: colors.text,
|
|
536
|
+
}}
|
|
537
|
+
>
|
|
538
|
+
{children}
|
|
539
|
+
</h4>
|
|
540
|
+
),
|
|
541
|
+
h3: ({ children }: any) => (
|
|
542
|
+
<h5
|
|
543
|
+
style={{
|
|
544
|
+
margin: '8px 0 4px',
|
|
545
|
+
fontSize: 14,
|
|
546
|
+
fontWeight: 600,
|
|
547
|
+
color: colors.text,
|
|
548
|
+
}}
|
|
549
|
+
>
|
|
550
|
+
{children}
|
|
551
|
+
</h5>
|
|
552
|
+
),
|
|
553
|
+
a: ({ href, children }: any) => (
|
|
554
|
+
<a
|
|
555
|
+
href={href}
|
|
556
|
+
target="_blank"
|
|
557
|
+
rel="noopener noreferrer"
|
|
558
|
+
style={{ color: colors.textMuted, textDecoration: 'underline' }}
|
|
559
|
+
>
|
|
427
560
|
{children}
|
|
428
|
-
</
|
|
429
|
-
)
|
|
430
|
-
},
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
h2: ({ children }: any) => <h4 style={{ margin: '8px 0 4px', fontSize: 15, fontWeight: 600, color: colors.text }}>{children}</h4>,
|
|
434
|
-
h3: ({ children }: any) => <h5 style={{ margin: '8px 0 4px', fontSize: 14, fontWeight: 600, color: colors.text }}>{children}</h5>,
|
|
435
|
-
a: ({ href, children }: any) => (
|
|
436
|
-
<a href={href} target="_blank" rel="noopener noreferrer" style={{ color: colors.textMuted, textDecoration: 'underline' }}>{children}</a>
|
|
437
|
-
),
|
|
438
|
-
}), [colors])
|
|
561
|
+
</a>
|
|
562
|
+
),
|
|
563
|
+
}),
|
|
564
|
+
[colors]
|
|
565
|
+
)
|
|
439
566
|
|
|
440
567
|
return <Markdown components={components}>{text}</Markdown>
|
|
441
568
|
}
|
|
@@ -471,7 +598,13 @@ const UserMessage: FunctionComponent = () => {
|
|
|
471
598
|
<MessagePrimitive.Content
|
|
472
599
|
components={{
|
|
473
600
|
Text: ({ text }) => (
|
|
474
|
-
<span
|
|
601
|
+
<span
|
|
602
|
+
style={{
|
|
603
|
+
fontSize: 14,
|
|
604
|
+
whiteSpace: 'pre-wrap',
|
|
605
|
+
color: colors.text,
|
|
606
|
+
}}
|
|
607
|
+
>
|
|
475
608
|
{text}
|
|
476
609
|
</span>
|
|
477
610
|
),
|
|
@@ -486,6 +619,8 @@ const UserMessage: FunctionComponent = () => {
|
|
|
486
619
|
const AssistantMessage: FunctionComponent = () => {
|
|
487
620
|
const colors = useContext(ColorsContext)
|
|
488
621
|
const toolComponents = useContext(ToolComponentsContext)
|
|
622
|
+
const generativeUIComponents = useContext(GenerativeUIComponentsContext)
|
|
623
|
+
const renderAssistantText = useContext(RenderAssistantTextContext)
|
|
489
624
|
return (
|
|
490
625
|
<div
|
|
491
626
|
style={{
|
|
@@ -507,9 +642,12 @@ const AssistantMessage: FunctionComponent = () => {
|
|
|
507
642
|
>
|
|
508
643
|
<MessagePrimitive.Content
|
|
509
644
|
components={{
|
|
510
|
-
Text: ({ text }) =>
|
|
511
|
-
|
|
512
|
-
|
|
645
|
+
Text: ({ text }) =>
|
|
646
|
+
renderAssistantText ? (
|
|
647
|
+
<>{renderAssistantText(text)}</>
|
|
648
|
+
) : (
|
|
649
|
+
<MarkdownText text={text} colors={colors} />
|
|
650
|
+
),
|
|
513
651
|
tools: {
|
|
514
652
|
by_name: toolComponents,
|
|
515
653
|
Fallback: (props) => (
|
|
@@ -523,6 +661,13 @@ const AssistantMessage: FunctionComponent = () => {
|
|
|
523
661
|
/>
|
|
524
662
|
),
|
|
525
663
|
},
|
|
664
|
+
...(generativeUIComponents
|
|
665
|
+
? {
|
|
666
|
+
generativeUI: {
|
|
667
|
+
components: generativeUIComponents,
|
|
668
|
+
},
|
|
669
|
+
}
|
|
670
|
+
: {}),
|
|
526
671
|
}}
|
|
527
672
|
/>
|
|
528
673
|
<MessagePrimitive.If last>
|
|
@@ -547,61 +692,95 @@ const AssistantMessage: FunctionComponent = () => {
|
|
|
547
692
|
)
|
|
548
693
|
}
|
|
549
694
|
|
|
695
|
+
const ComposerPrefill: FunctionComponent<{ text?: string }> = ({ text }) => {
|
|
696
|
+
const composer = useComposerRuntime()
|
|
697
|
+
const filled = useRef(false)
|
|
698
|
+
useEffect(() => {
|
|
699
|
+
if (filled.current || !text) return
|
|
700
|
+
filled.current = true
|
|
701
|
+
if (composer.getState().text === '') composer.setText(text)
|
|
702
|
+
}, [text, composer])
|
|
703
|
+
return null
|
|
704
|
+
}
|
|
705
|
+
|
|
550
706
|
const PikkuComposer: FunctionComponent<{ disabled?: boolean }> = ({
|
|
551
707
|
disabled,
|
|
552
708
|
}) => {
|
|
553
709
|
const colors = useContext(ColorsContext)
|
|
710
|
+
|
|
554
711
|
return (
|
|
555
712
|
<div style={{ padding: '8px 0 16px' }}>
|
|
556
713
|
<ComposerPrimitive.Root>
|
|
557
714
|
<div
|
|
558
715
|
style={{
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
overflow: 'hidden',
|
|
716
|
+
position: 'relative',
|
|
717
|
+
zIndex: 2,
|
|
562
718
|
display: 'flex',
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
719
|
+
flexDirection: 'column',
|
|
720
|
+
gap: 10,
|
|
721
|
+
backgroundColor: colors.assistantBubble,
|
|
722
|
+
border: `1px solid ${colors.border}`,
|
|
723
|
+
borderRadius: 24,
|
|
724
|
+
padding: '14px 12px 10px',
|
|
725
|
+
boxShadow:
|
|
726
|
+
darkColors.text === colors.text
|
|
727
|
+
? '0 14px 30px rgba(0,0,0,0.24)'
|
|
728
|
+
: '0 14px 30px rgba(0,0,0,0.08)',
|
|
729
|
+
...(disabled
|
|
730
|
+
? { opacity: 0.5, pointerEvents: 'none' as const }
|
|
731
|
+
: {}),
|
|
567
732
|
}}
|
|
568
733
|
>
|
|
569
734
|
<ComposerPrimitive.Input
|
|
570
|
-
placeholder={
|
|
571
|
-
|
|
572
|
-
|
|
735
|
+
placeholder={
|
|
736
|
+
disabled ? 'Respond to approval request above...' : 'Message...'
|
|
737
|
+
}
|
|
738
|
+
rows={1}
|
|
739
|
+
disabled={disabled ?? false}
|
|
573
740
|
style={{
|
|
574
|
-
|
|
741
|
+
width: '100%',
|
|
742
|
+
background: 'transparent',
|
|
575
743
|
border: 'none',
|
|
576
744
|
outline: 'none',
|
|
577
|
-
|
|
745
|
+
color: colors.text,
|
|
578
746
|
fontSize: 14,
|
|
579
747
|
fontFamily: 'inherit',
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
748
|
+
resize: 'none',
|
|
749
|
+
lineHeight: 1.5,
|
|
750
|
+
overflowY: 'auto',
|
|
583
751
|
}}
|
|
584
752
|
/>
|
|
585
|
-
<
|
|
586
|
-
disabled={disabled}
|
|
753
|
+
<div
|
|
587
754
|
style={{
|
|
588
|
-
width:
|
|
589
|
-
height: 28,
|
|
590
|
-
borderRadius: '50%',
|
|
591
|
-
border: 'none',
|
|
592
|
-
background: disabled ? colors.textMuted : colors.sendBg,
|
|
593
|
-
color: colors.sendColor,
|
|
594
|
-
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
755
|
+
width: '100%',
|
|
595
756
|
display: 'flex',
|
|
596
757
|
alignItems: 'center',
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
fontSize: 14,
|
|
758
|
+
gap: 6,
|
|
759
|
+
minWidth: 0,
|
|
760
|
+
justifyContent: 'flex-end',
|
|
601
761
|
}}
|
|
602
762
|
>
|
|
603
|
-
|
|
604
|
-
|
|
763
|
+
<ComposerPrimitive.Send
|
|
764
|
+
disabled={disabled ?? false}
|
|
765
|
+
style={{
|
|
766
|
+
width: 30,
|
|
767
|
+
height: 30,
|
|
768
|
+
borderRadius: 999,
|
|
769
|
+
border: `1px solid ${colors.border}`,
|
|
770
|
+
background: '#e8e8e8',
|
|
771
|
+
color: '#111111',
|
|
772
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
773
|
+
display: 'flex',
|
|
774
|
+
alignItems: 'center',
|
|
775
|
+
justifyContent: 'center',
|
|
776
|
+
flexShrink: 0,
|
|
777
|
+
transition:
|
|
778
|
+
'background-color 150ms ease, color 150ms ease, border-color 150ms ease',
|
|
779
|
+
}}
|
|
780
|
+
>
|
|
781
|
+
↑
|
|
782
|
+
</ComposerPrimitive.Send>
|
|
783
|
+
</div>
|
|
605
784
|
</div>
|
|
606
785
|
</ComposerPrimitive.Root>
|
|
607
786
|
</div>
|
|
@@ -609,7 +788,17 @@ const PikkuComposer: FunctionComponent<{ disabled?: boolean }> = ({
|
|
|
609
788
|
}
|
|
610
789
|
|
|
611
790
|
export function PikkuAgentChat(props: PikkuAgentChatProps) {
|
|
612
|
-
const {
|
|
791
|
+
const {
|
|
792
|
+
emptyMessage,
|
|
793
|
+
hideToolCalls,
|
|
794
|
+
dark,
|
|
795
|
+
maxWidth = 768,
|
|
796
|
+
toolComponents,
|
|
797
|
+
renderAssistantText,
|
|
798
|
+
generativeUIComponents,
|
|
799
|
+
initialPrompt,
|
|
800
|
+
...runtimeOptions
|
|
801
|
+
} = props
|
|
613
802
|
const { runtime, isAwaitingApproval, pendingApprovals, handleApproval } =
|
|
614
803
|
usePikkuAgentRuntime(runtimeOptions)
|
|
615
804
|
|
|
@@ -617,78 +806,95 @@ export function PikkuAgentChat(props: PikkuAgentChatProps) {
|
|
|
617
806
|
|
|
618
807
|
return (
|
|
619
808
|
<ColorsContext.Provider value={colors}>
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
<ToolComponentsContext.Provider value={toolComponents}>
|
|
623
|
-
<AssistantRuntimeProvider runtime={runtime}>
|
|
624
|
-
<div
|
|
625
|
-
style={{
|
|
626
|
-
height: '100%',
|
|
627
|
-
display: 'flex',
|
|
628
|
-
flexDirection: 'column',
|
|
629
|
-
background: colors.bg,
|
|
630
|
-
}}
|
|
809
|
+
<PikkuApprovalContext.Provider
|
|
810
|
+
value={{ pendingApprovals, handleApproval }}
|
|
631
811
|
>
|
|
632
|
-
<
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
flex: 1,
|
|
637
|
-
minHeight: 0,
|
|
638
|
-
}}
|
|
639
|
-
>
|
|
640
|
-
<ThreadPrimitive.Viewport
|
|
641
|
-
style={{
|
|
642
|
-
flex: 1,
|
|
643
|
-
minHeight: 0,
|
|
644
|
-
overflowY: 'auto',
|
|
645
|
-
}}
|
|
646
|
-
>
|
|
647
|
-
<div
|
|
648
|
-
style={{
|
|
649
|
-
maxWidth: maxWidth === 'none' ? undefined : maxWidth,
|
|
650
|
-
margin: '0 auto',
|
|
651
|
-
padding: 16,
|
|
652
|
-
display: 'flex',
|
|
653
|
-
flexDirection: 'column',
|
|
654
|
-
gap: 16,
|
|
655
|
-
}}
|
|
812
|
+
<HideToolCallsContext.Provider value={hideToolCalls}>
|
|
813
|
+
<ToolComponentsContext.Provider value={toolComponents}>
|
|
814
|
+
<GenerativeUIComponentsContext.Provider
|
|
815
|
+
value={generativeUIComponents}
|
|
656
816
|
>
|
|
657
|
-
<
|
|
658
|
-
<
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
817
|
+
<RenderAssistantTextContext.Provider value={renderAssistantText}>
|
|
818
|
+
<AssistantRuntimeProvider runtime={runtime}>
|
|
819
|
+
<ComposerPrefill text={initialPrompt} />
|
|
820
|
+
<div
|
|
821
|
+
style={{
|
|
822
|
+
height: '100%',
|
|
823
|
+
display: 'flex',
|
|
824
|
+
flexDirection: 'column',
|
|
825
|
+
background: colors.bg,
|
|
826
|
+
}}
|
|
827
|
+
>
|
|
828
|
+
<ThreadPrimitive.Root
|
|
829
|
+
style={{
|
|
830
|
+
display: 'flex',
|
|
831
|
+
flexDirection: 'column',
|
|
832
|
+
flex: 1,
|
|
833
|
+
minHeight: 0,
|
|
834
|
+
}}
|
|
835
|
+
>
|
|
836
|
+
<ThreadPrimitive.Viewport
|
|
837
|
+
style={{
|
|
838
|
+
flex: 1,
|
|
839
|
+
minHeight: 0,
|
|
840
|
+
overflowY: 'auto',
|
|
841
|
+
}}
|
|
842
|
+
>
|
|
843
|
+
<div
|
|
844
|
+
style={{
|
|
845
|
+
maxWidth:
|
|
846
|
+
maxWidth === 'none' ? undefined : maxWidth,
|
|
847
|
+
margin: '0 auto',
|
|
848
|
+
padding: 16,
|
|
849
|
+
display: 'flex',
|
|
850
|
+
flexDirection: 'column',
|
|
851
|
+
gap: 16,
|
|
852
|
+
}}
|
|
853
|
+
>
|
|
854
|
+
<ThreadPrimitive.Empty>
|
|
855
|
+
<div
|
|
856
|
+
style={{
|
|
857
|
+
display: 'flex',
|
|
858
|
+
alignItems: 'center',
|
|
859
|
+
justifyContent: 'center',
|
|
860
|
+
minHeight: 300,
|
|
861
|
+
color: colors.textMuted,
|
|
862
|
+
textAlign: 'center',
|
|
863
|
+
fontSize: 14,
|
|
864
|
+
}}
|
|
865
|
+
>
|
|
866
|
+
{emptyMessage ??
|
|
867
|
+
(props.threadId
|
|
868
|
+
? 'Send a message to start the conversation.'
|
|
869
|
+
: 'Start a new conversation.')}
|
|
870
|
+
</div>
|
|
871
|
+
</ThreadPrimitive.Empty>
|
|
872
|
+
<ThreadPrimitive.Messages
|
|
873
|
+
components={{
|
|
874
|
+
UserMessage,
|
|
875
|
+
AssistantMessage,
|
|
876
|
+
}}
|
|
877
|
+
/>
|
|
878
|
+
</div>
|
|
879
|
+
</ThreadPrimitive.Viewport>
|
|
880
|
+
<div
|
|
881
|
+
style={{
|
|
882
|
+
maxWidth: maxWidth === 'none' ? undefined : maxWidth,
|
|
883
|
+
margin: '0 auto',
|
|
884
|
+
width: '100%',
|
|
885
|
+
padding: '0 16px',
|
|
886
|
+
}}
|
|
887
|
+
>
|
|
888
|
+
<PikkuComposer disabled={isAwaitingApproval} />
|
|
889
|
+
</div>
|
|
890
|
+
</ThreadPrimitive.Root>
|
|
891
|
+
</div>
|
|
892
|
+
</AssistantRuntimeProvider>
|
|
893
|
+
</RenderAssistantTextContext.Provider>
|
|
894
|
+
</GenerativeUIComponentsContext.Provider>
|
|
895
|
+
</ToolComponentsContext.Provider>
|
|
896
|
+
</HideToolCallsContext.Provider>
|
|
897
|
+
</PikkuApprovalContext.Provider>
|
|
692
898
|
</ColorsContext.Provider>
|
|
693
899
|
)
|
|
694
900
|
}
|