@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.
@@ -1,10 +1,21 @@
1
- import { createContext, useContext, useState, useMemo, type FunctionComponent } from 'react'
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>(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 }}>{approvalReason}</div>
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: responded === 'approved' ? colors.successBg : colors.errorBg,
257
- color: responded === 'approved' ? colors.successColor : colors.errorColor,
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 }}>running...</span>
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 style={{ fontSize: 12, color: colors.textMuted, marginBottom: 2 }}>
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={{ fontSize: 12, color: colors.textMuted, marginTop: 8, marginBottom: 2 }}
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 }> = ({ text, colors }) => {
397
- const components = useMemo(() => ({
398
- p: ({ children }: any) => (
399
- <p style={{ margin: '0 0 8px', fontSize: 14, lineHeight: 1.6, color: colors.text }}>{children}</p>
400
- ),
401
- strong: ({ children }: any) => (
402
- <strong style={{ fontWeight: 600, color: colors.text }}>{children}</strong>
403
- ),
404
- em: ({ children }: any) => (
405
- <em style={{ color: colors.text }}>{children}</em>
406
- ),
407
- ul: ({ children }: any) => (
408
- <ul style={{ margin: '4px 0 8px', paddingLeft: 20, fontSize: 14, color: colors.text }}>{children}</ul>
409
- ),
410
- ol: ({ children }: any) => (
411
- <ol style={{ margin: '4px 0 8px', paddingLeft: 20, fontSize: 14, color: colors.text }}>{children}</ol>
412
- ),
413
- li: ({ children }: any) => (
414
- <li style={{ marginBottom: 2, lineHeight: 1.6 }}>{children}</li>
415
- ),
416
- code: ({ children, className }: any) => {
417
- const isBlock = className?.startsWith('language-')
418
- if (isBlock) {
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
- <pre style={{ background: colors.codeBg, padding: 10, borderRadius: 4, overflow: 'auto', margin: '4px 0 8px', fontSize: 12 }}>
421
- <code style={{ color: colors.text }}>{children}</code>
422
- </pre>
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
- return (
426
- <code style={{ background: colors.codeBg, padding: '1px 4px', borderRadius: 3, fontSize: 13, color: colors.text }}>
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
- </code>
429
- )
430
- },
431
- pre: ({ children }: any) => <>{children}</>,
432
- h1: ({ children }: any) => <h3 style={{ margin: '8px 0 4px', fontSize: 16, fontWeight: 600, color: colors.text }}>{children}</h3>,
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 style={{ fontSize: 14, whiteSpace: 'pre-wrap', color: colors.text }}>
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
- <MarkdownText text={text} colors={colors} />
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
- border: `1px solid ${colors.border}`,
560
- borderRadius: 12,
561
- overflow: 'hidden',
716
+ position: 'relative',
717
+ zIndex: 2,
562
718
  display: 'flex',
563
- alignItems: 'flex-end',
564
- padding: '6px 12px',
565
- gap: 8,
566
- ...(disabled ? { opacity: 0.5, pointerEvents: 'none' as const } : {}),
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={disabled ? 'Respond to approval request above...' : 'Message...'}
571
- rows={2}
572
- disabled={disabled}
735
+ placeholder={
736
+ disabled ? 'Respond to approval request above...' : 'Message...'
737
+ }
738
+ rows={1}
739
+ disabled={disabled ?? false}
573
740
  style={{
574
- flex: 1,
741
+ width: '100%',
742
+ background: 'transparent',
575
743
  border: 'none',
576
744
  outline: 'none',
577
- resize: 'none',
745
+ color: colors.text,
578
746
  fontSize: 14,
579
747
  fontFamily: 'inherit',
580
- padding: '4px 0',
581
- background: colors.inputBg,
582
- color: colors.text,
748
+ resize: 'none',
749
+ lineHeight: 1.5,
750
+ overflowY: 'auto',
583
751
  }}
584
752
  />
585
- <ComposerPrimitive.Send
586
- disabled={disabled}
753
+ <div
587
754
  style={{
588
- width: 28,
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
- justifyContent: 'center',
598
- flexShrink: 0,
599
- marginBottom: 2,
600
- fontSize: 14,
758
+ gap: 6,
759
+ minWidth: 0,
760
+ justifyContent: 'flex-end',
601
761
  }}
602
762
  >
603
- &#9654;
604
- </ComposerPrimitive.Send>
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 { emptyMessage, hideToolCalls, dark, maxWidth = 768, toolComponents, ...runtimeOptions } = props
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
- <PikkuApprovalContext.Provider value={{ pendingApprovals, handleApproval }}>
621
- <HideToolCallsContext.Provider value={hideToolCalls}>
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
- <ThreadPrimitive.Root
633
- style={{
634
- display: 'flex',
635
- flexDirection: 'column',
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
- <ThreadPrimitive.Empty>
658
- <div
659
- style={{
660
- display: 'flex',
661
- alignItems: 'center',
662
- justifyContent: 'center',
663
- minHeight: 300,
664
- color: colors.textMuted,
665
- textAlign: 'center',
666
- fontSize: 14,
667
- }}
668
- >
669
- {emptyMessage ??
670
- (props.threadId
671
- ? 'Send a message to start the conversation.'
672
- : 'Start a new conversation.')}
673
- </div>
674
- </ThreadPrimitive.Empty>
675
- <ThreadPrimitive.Messages
676
- components={{
677
- UserMessage,
678
- AssistantMessage,
679
- }}
680
- />
681
- </div>
682
- </ThreadPrimitive.Viewport>
683
- <div style={{ maxWidth: maxWidth === 'none' ? undefined : maxWidth, margin: '0 auto', width: '100%', padding: '0 16px' }}>
684
- <PikkuComposer disabled={isAwaitingApproval} />
685
- </div>
686
- </ThreadPrimitive.Root>
687
- </div>
688
- </AssistantRuntimeProvider>
689
- </ToolComponentsContext.Provider>
690
- </HideToolCallsContext.Provider>
691
- </PikkuApprovalContext.Provider>
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
  }