@timbal-ai/timbal-react 0.3.0 → 0.5.0

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/dist/index.d.cts CHANGED
@@ -1,13 +1,12 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as React from 'react';
3
- import React__default, { ReactNode, FC, ComponentType, Dispatch, ComponentPropsWithRef, ElementType } from 'react';
3
+ import React__default, { ReactNode, FC, ComponentType, Dispatch, ElementType } from 'react';
4
4
  import { AttachmentAdapter, ToolCallMessagePartComponent } from '@assistant-ui/react';
5
- export { ActionBarPrimitive, AssistantRuntimeProvider, AttachmentAdapter, ComposerPrimitive, MessagePrimitive, ThreadPrimitive, useComposerRuntime, useMessageRuntime, useThread, useThreadRuntime } from '@assistant-ui/react';
5
+ export { ActionBarPrimitive, AssistantRuntimeProvider, AttachmentAdapter, AuiIf, ComposerPrimitive, MessagePrimitive, ThreadPrimitive, useComposerRuntime, useMessageRuntime, useThread, useThreadRuntime } from '@assistant-ui/react';
6
6
  import { WorkforceItem, Session } from '@timbal-ai/timbal-sdk';
7
7
  export { parseSSELine } from '@timbal-ai/timbal-sdk';
8
8
  import * as class_variance_authority_types from 'class-variance-authority/types';
9
9
  import { VariantProps } from 'class-variance-authority';
10
- import { SyntaxHighlighterProps } from '@assistant-ui/react-markdown';
11
10
  import { Tooltip as Tooltip$1, Avatar as Avatar$1, Dialog as Dialog$1 } from 'radix-ui';
12
11
  import { ClassValue } from 'clsx';
13
12
 
@@ -217,41 +216,36 @@ interface ComposerProps {
217
216
  /** Placeholder shown in the textarea. Default: "Send a message..." */
218
217
  placeholder?: string;
219
218
  /**
220
- * Show the file-attach button. Default: true. Disable when the agent has
221
- * no use for attachments to keep the UI clean.
219
+ * Show the file-attach button. Default: true. Disable when the agent has no
220
+ * use for attachments to keep the toolbar clean.
222
221
  */
223
222
  showAttachments?: boolean;
224
- /**
225
- * Extra content rendered inside the toolbar, to the left of the send
226
- * button. Use for custom buttons (voice, model picker, etc).
227
- */
223
+ /** Extra content rendered inside the toolbar, left of the send button. */
228
224
  toolbar?: ReactNode;
229
- /**
230
- * Tooltip on the send button. Default: "Send message".
231
- */
225
+ /** Tooltip shown on the send button. Default: "Send message". */
232
226
  sendTooltip?: string;
233
- /** Disable autofocus on mount. Default: false (autofocused). */
227
+ /** Disable autofocus on mount. Default: false. */
234
228
  noAutoFocus?: boolean;
235
229
  /** Extra className applied to the outer composer wrapper. */
236
230
  className?: string;
237
231
  }
238
232
  /**
239
- * Composer v2 — auto-resizing textarea, Enter-to-send / Shift+Enter newline,
240
- * attach button on the left, send/stop on the right. Use as a top-level
241
- * component inside `<TimbalRuntimeProvider>` (or via `<Thread components={{
242
- * Composer }}>`).
233
+ * Default chat composer — auto-resizing textarea with Enter-to-send,
234
+ * Shift+Enter for newline, attach pill on the left, and a circular send /
235
+ * cancel button on the right. Wraps `ComposerPrimitive` so consumers can
236
+ * override individual slots without losing the Studio chrome.
243
237
  */
244
238
  declare const Composer: FC<ComposerProps>;
245
239
 
246
240
  interface ThreadSuggestion {
247
- /** Title shown on the chip. Also sent verbatim as the user message. */
241
+ /** Title shown on the row. Also sent verbatim as the user message. */
248
242
  title: string;
249
243
  /** Optional secondary line. */
250
244
  description?: string;
251
245
  /** Optional leading icon. */
252
246
  icon?: ReactNode;
253
247
  /**
254
- * Override the prompt sent when the chip is clicked. Useful when the chip
248
+ * Override the prompt sent when the row is clicked. Useful when the row
255
249
  * label is short ("Weekly recap") but the prompt should be longer.
256
250
  */
257
251
  prompt?: string;
@@ -263,18 +257,14 @@ interface ThreadSuggestion {
263
257
  type SuggestionsSource = ThreadSuggestion[] | (() => ThreadSuggestion[] | Promise<ThreadSuggestion[]>);
264
258
  interface ThreadSuggestionsProps {
265
259
  suggestions?: SuggestionsSource;
266
- /**
267
- * Compact layout: single row, horizontally scrollable, smaller chips. Use
268
- * inline (e.g. above the composer or after a message) where vertical
269
- * space is tight.
270
- */
271
- layout?: "grid" | "row";
272
260
  className?: string;
273
261
  }
274
262
  /**
275
- * Render suggestion chips. Resolves both static arrays and async sources.
276
- * On click, appends the suggestion's `prompt` (or `title` if no prompt) as
277
- * a user message via the thread runtime.
263
+ * Render suggestions as a stacked column of full-width rows. Each row reads
264
+ * like a list item rather than a chip, matching the Studio playground.
265
+ *
266
+ * On click the row's `prompt` (or `title` if no prompt) is appended as a
267
+ * user message via the thread runtime.
278
268
  */
279
269
  declare const Suggestions: FC<ThreadSuggestionsProps>;
280
270
  /**
@@ -283,12 +273,9 @@ declare const Suggestions: FC<ThreadSuggestionsProps>;
283
273
  * async functions stream in once the promise settles.
284
274
  */
285
275
  declare function useResolvedSuggestions(source?: SuggestionsSource): ThreadSuggestion[] | undefined;
286
- /**
287
- * Props passed to a custom `Suggestions` slot component. Replace the default
288
- * via `<Thread components={{ Suggestions: MySuggestions }}>`.
289
- */
290
276
  interface SuggestionsSlotProps {
291
277
  suggestions?: SuggestionsSource;
278
+ className?: string;
292
279
  }
293
280
  type SuggestionsComponent = ComponentType<SuggestionsSlotProps>;
294
281
 
@@ -584,6 +571,12 @@ declare function useUiCustomNodeRegistry(): Record<string, UiCustomNodeRenderer>
584
571
  interface ThreadWelcomeConfig {
585
572
  heading?: string;
586
573
  subheading?: string;
574
+ /**
575
+ * Optional brand icon rendered above the heading. Pass any ReactNode — the
576
+ * SDK no longer ships a default sparkle icon so apps can drop in their
577
+ * own logo or stay minimal.
578
+ */
579
+ icon?: ReactNode;
587
580
  }
588
581
  interface ThreadWelcomeProps {
589
582
  config?: ThreadWelcomeConfig;
@@ -596,17 +589,17 @@ interface ThreadWelcomeProps {
596
589
  Suggestions?: SuggestionsComponent;
597
590
  }
598
591
  interface ThreadComponents {
599
- /** Replace the user message bubble. Access message content via `MessagePrimitive.Parts`. */
592
+ /** Replace the user message bubble. Access content via `MessagePrimitive.Parts`. */
600
593
  UserMessage?: ComponentType;
601
- /** Replace the assistant message bubble. Access message content via `MessagePrimitive.Parts`. */
594
+ /** Replace the assistant message bubble. Access content via `MessagePrimitive.Parts`. */
602
595
  AssistantMessage?: ComponentType;
603
596
  /** Replace the inline edit composer. */
604
597
  EditComposer?: ComponentType;
605
598
  /** Replace the composer (input bar). Receives all `ComposerProps` from the parent. */
606
599
  Composer?: ComponentType<ComposerProps>;
607
- /** Replace the welcome / empty state. Receives `config` and `suggestions` props. Controls its own visibility — use `useThread(s => s.isEmpty)` to replicate the default behaviour. */
600
+ /** Replace the welcome / empty state. Renders only while the thread is empty. */
608
601
  Welcome?: ComponentType<ThreadWelcomeProps>;
609
- /** Replace the suggestion chip block (rendered inside Welcome and inline). */
602
+ /** Replace the suggestion list (rendered inside Welcome). */
610
603
  Suggestions?: SuggestionsComponent;
611
604
  /** Replace the scroll-to-bottom button. */
612
605
  ScrollToBottom?: ComponentType;
@@ -620,16 +613,16 @@ interface ThreadArtifactsConfig {
620
613
 
621
614
  interface ThreadProps {
622
615
  className?: string;
623
- /** Max width of the message column. Default: "44rem" */
616
+ /** Max width of the message column. Default: "44rem". */
624
617
  maxWidth?: string;
625
- /** Welcome screen text */
618
+ /** Welcome screen text + optional brand icon. */
626
619
  welcome?: ThreadWelcomeConfig;
627
620
  /**
628
- * Welcome-screen suggestion chips. Accepts a static array, a thunk, or an
621
+ * Welcome-screen suggestion rows. Accepts a static array, a thunk, or an
629
622
  * async function for per-user suggestions.
630
623
  */
631
624
  suggestions?: SuggestionsSource;
632
- /** Composer input placeholder. Default: "Send a message..." */
625
+ /** Composer input placeholder. Default: "Send a message...". */
633
626
  composerPlaceholder?: string;
634
627
  /** Override individual UI slots while keeping the rest as defaults. */
635
628
  components?: ThreadComponents;
@@ -642,8 +635,9 @@ interface ThreadProps {
642
635
  artifacts?: ThreadArtifactsConfig;
643
636
  /**
644
637
  * Called when a `ui` artifact fires an `{ kind: "emit" }` action. Use this
645
- * to react to slider commits, drag gestures, or other host-side logic beyond
646
- * the built-in `message` action (which already appends a user message).
638
+ * to react to slider commits, drag gestures, or other host-side logic
639
+ * beyond the built-in `message` action (which already appends a user
640
+ * message).
647
641
  */
648
642
  onArtifactEvent?: (event: UiEventEnvelope) => void;
649
643
  }
@@ -653,10 +647,234 @@ interface TimbalChatProps extends Omit<TimbalRuntimeProviderProps, "children">,
653
647
  }
654
648
  declare function TimbalChat({ workforceId, baseUrl, fetch, attachments, attachmentsUploadUrl, attachmentsAccept, debug, ...threadProps }: TimbalChatProps): react_jsx_runtime.JSX.Element;
655
649
 
650
+ interface TimbalChatShellProps extends Omit<TimbalChatProps, "workforceId"> {
651
+ /**
652
+ * Pre-selected workforce id. When omitted, the shell fetches the workforce
653
+ * list from `{baseUrl}/workforce` and picks the first agent automatically.
654
+ */
655
+ workforceId?: string;
656
+ /** Branding rendered at the start of the header (logo, etc). */
657
+ brand?: ReactNode;
658
+ /** Extra content rendered at the end of the header (theme toggle, logout). */
659
+ headerActions?: ReactNode;
660
+ /** Hide the built-in workforce selector. Default: false. */
661
+ hideWorkforceSelector?: boolean;
662
+ /** Class for the outer flex container. */
663
+ className?: string;
664
+ /** Class for the header bar. */
665
+ headerClassName?: string;
666
+ }
667
+ /**
668
+ * Drop-in shell that wraps `TimbalChat` with the Studio playground chrome:
669
+ * floating topbar with brand + workforce selector + actions, soft gradient
670
+ * background, and the chat thread filling the remaining vertical space.
671
+ *
672
+ * Falls back to picking the first available workforce when `workforceId`
673
+ * isn't supplied.
674
+ */
675
+ declare const TimbalChatShell: FC<TimbalChatShellProps>;
676
+
677
+ interface TimbalStudioShellProps extends Omit<TimbalChatProps, "workforceId"> {
678
+ /**
679
+ * Pin the chat to a specific workforce. When omitted, the shell fetches
680
+ * the workforce list via `useWorkforces()` and lets the sidebar drive
681
+ * selection.
682
+ */
683
+ workforceId?: string;
684
+ /**
685
+ * Pre-loaded workforce list. When omitted, the shell fetches it.
686
+ * Useful for stories / SSR / preview environments.
687
+ */
688
+ workforces?: WorkforceItem[];
689
+ /** Custom fetch for the workforce list (mock fetch in preview mode). */
690
+ workforcesFetch?: (url: string, options?: RequestInit) => Promise<Response>;
691
+ /** Base URL for the workforce list. Default: `/api`. */
692
+ workforcesBaseUrl?: string;
693
+ /** Brand mark rendered in the sidebar header. Default: `<TimbalMark />`. */
694
+ brand?: ReactNode;
695
+ /** Extra actions rendered at the right of the floating top bar. */
696
+ headerActions?: ReactNode;
697
+ /** Nodes rendered at the left of the floating top bar (after the menu button). */
698
+ headerStart?: ReactNode;
699
+ /** Initial collapse state when no persisted value exists. Default: false. */
700
+ defaultCollapsed?: boolean;
701
+ /** localStorage key for persisting the collapse state. Default set. */
702
+ persistKey?: string | null;
703
+ /** Pixel breakpoint below which the sidebar becomes a drawer. Default 768. */
704
+ mobileBreakpointPx?: number;
705
+ /** Caption shown in the sidebar footer when no user is signed in. */
706
+ sidebarEmptyCaption?: string | null;
707
+ }
708
+ /**
709
+ * Opinionated Timbal studio layout — floating sidebar with workforce picker,
710
+ * top bar with optional mode toggle / actions, and a `<TimbalChat />` filling
711
+ * the rest. Manages collapse state, mobile drawer, and workforce selection
712
+ * out of the box. For more control compose `StudioSidebar` + `TimbalChat`
713
+ * directly.
714
+ */
715
+ declare const TimbalStudioShell: FC<TimbalStudioShellProps>;
716
+
656
717
  declare const MarkdownText: React.MemoExoticComponent<() => react_jsx_runtime.JSX.Element>;
657
718
 
719
+ interface ToolStatus {
720
+ type: string;
721
+ reason?: string;
722
+ }
723
+ declare function useToolRunning(props: {
724
+ status?: ToolStatus;
725
+ result?: unknown;
726
+ }): boolean;
658
727
  declare const ToolFallback: ToolCallMessagePartComponent;
659
728
 
729
+ interface WorkforceSelectorProps {
730
+ /** List of workforces to choose from. */
731
+ workforces: WorkforceItem[];
732
+ /** Currently selected workforce id. */
733
+ value: string;
734
+ /** Called when the user picks a different workforce. */
735
+ onChange: (id: string) => void;
736
+ /** Hide the selector when there's only one option. Default: true. */
737
+ hideWhenSingle?: boolean;
738
+ className?: string;
739
+ placeholder?: string;
740
+ }
741
+ /**
742
+ * Minimal headless workforce picker. Wraps a styled native `<select>` so
743
+ * the SDK doesn't need to depend on `@radix-ui/react-select`, while still
744
+ * matching the Studio chrome (gradient pill, soft border, chevron).
745
+ *
746
+ * Apps that want a richer UI (search, descriptions, agent icons) can build
747
+ * their own using `useWorkforces()`.
748
+ */
749
+ declare const WorkforceSelector: FC<WorkforceSelectorProps>;
750
+
751
+ interface StudioSidebarProps {
752
+ /**
753
+ * Workforces to display. When omitted, the sidebar fetches them via the
754
+ * shared `useWorkforces()` hook.
755
+ */
756
+ workforces?: WorkforceItem[];
757
+ selectedId?: string;
758
+ onSelect?: (id: string) => void;
759
+ /** Initial collapse state when no persisted value exists. Default: false. */
760
+ defaultCollapsed?: boolean;
761
+ /**
762
+ * localStorage key for persisting the collapse state. Pass `null` to
763
+ * disable persistence. Default: `"timbal-studio-sidebar-collapsed"`.
764
+ */
765
+ persistKey?: string | null;
766
+ /**
767
+ * Pixel breakpoint below which the sidebar becomes a drawer.
768
+ * Default: 768.
769
+ */
770
+ mobileBreakpointPx?: number;
771
+ /** Brand element rendered in the sidebar header. Default: `<TimbalMark />`. */
772
+ brand?: ReactNode;
773
+ /** Caption shown in the footer when no user is signed in. */
774
+ emptyCaption?: string | null;
775
+ /** External control over the mobile drawer (used by `TimbalStudioShell`). */
776
+ mobileOpen?: boolean;
777
+ onMobileOpenChange?: (open: boolean) => void;
778
+ }
779
+ /**
780
+ * Floating, collapsible workforce sidebar. Manages its own collapse state
781
+ * (persisted to localStorage by default) and mobile drawer behaviour. For
782
+ * a fully composed shell with the chat already wired use
783
+ * `TimbalStudioShell`.
784
+ */
785
+ declare const StudioSidebar: FC<StudioSidebarProps>;
786
+
787
+ interface TimbalMarkProps {
788
+ className?: string;
789
+ /** Square size in CSS pixels (matches `--studio-chrome-pill-height` at 40). */
790
+ size?: number;
791
+ /**
792
+ * Override the symbol shown inside the shader. Defaults to the embedded
793
+ * Timbal mark — pass any image URL or data URI to brand the chat with
794
+ * your own logo while keeping the liquid-metal motion.
795
+ */
796
+ src?: string;
797
+ }
798
+ /**
799
+ * Timbal mark rendered with the Paper Design LiquidMetal shader.
800
+ *
801
+ * The Timbal symbol is embedded as a data URI so the library works without
802
+ * the consumer having to host the asset. Pass `src` to use a custom logo.
803
+ */
804
+ declare function TimbalMark({ className, size, src, }: TimbalMarkProps): react_jsx_runtime.JSX.Element;
805
+
806
+ type ModeToggleTheme = "light" | "dark" | "system";
807
+ interface ModeToggleProps {
808
+ /**
809
+ * Current theme. When omitted, the toggle reads from / writes to the
810
+ * `.dark` class on `<html>` directly — useful for apps that don't have
811
+ * a theme manager yet.
812
+ */
813
+ theme?: ModeToggleTheme | string;
814
+ /** Called when the user clicks the toggle. */
815
+ setTheme?: (theme: ModeToggleTheme) => void;
816
+ className?: string;
817
+ /** ARIA label / tooltip. Default: "Toggle theme". */
818
+ label?: string;
819
+ }
820
+ /**
821
+ * Sun/moon theme toggle styled to sit in the studio top bar.
822
+ *
823
+ * Two integration modes:
824
+ *
825
+ * 1. Pass `theme` + `setTheme` (e.g. from `next-themes`'s `useTheme`).
826
+ * The component is then fully controlled.
827
+ * 2. Omit both. The toggle reads the current state from `.dark` on
828
+ * `<html>` and flips it on click. Good enough for prototypes and
829
+ * cases where there is no theme manager.
830
+ */
831
+ declare const ModeToggle: FC<ModeToggleProps>;
832
+
833
+ interface StudioWelcomeProps extends ThreadWelcomeProps {
834
+ /** Override the brand mark rendered above the heading. */
835
+ icon?: ReactNode;
836
+ }
837
+ /**
838
+ * Welcome screen with the staggered Timbal mark + heading + subheading.
839
+ * Drop in as the `components.Welcome` slot of `<Thread />` /
840
+ * `<TimbalChat />` to replace the default sparkle illustration.
841
+ */
842
+ declare const StudioWelcome: FC<StudioWelcomeProps>;
843
+
844
+ type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;
845
+ interface UseWorkforcesOptions {
846
+ /** Base URL for API calls. Default: `/api`. */
847
+ baseUrl?: string;
848
+ /** Custom fetch (defaults to `authFetch` for token-auth flows). */
849
+ fetch?: FetchFn;
850
+ /**
851
+ * Pick the initial selected workforce. By default we prefer the first
852
+ * `type === "agent"` entry, falling back to the first item. Pass a custom
853
+ * resolver to override (e.g. remember the user's last choice).
854
+ */
855
+ pickInitial?: (items: WorkforceItem[]) => WorkforceItem | undefined;
856
+ /** When false, the hook returns an empty list and skips the network fetch. */
857
+ enabled?: boolean;
858
+ }
859
+ interface UseWorkforcesResult {
860
+ workforces: WorkforceItem[];
861
+ /** Currently selected workforce identifier (id ?? uid ?? name). */
862
+ selectedId: string;
863
+ setSelectedId: (id: string) => void;
864
+ /** The full `WorkforceItem` for `selectedId`, if any. */
865
+ selected: WorkforceItem | undefined;
866
+ isLoading: boolean;
867
+ error: Error | null;
868
+ /** Re-fetch the list. Resets `error`. */
869
+ refresh: () => Promise<void>;
870
+ }
871
+ /**
872
+ * Fetch the list of workforces exposed by the blueprint API and track a
873
+ * selection. Used to power `<WorkforceSelector />` but exported separately
874
+ * so apps can drive their own UI (e.g. a sidebar tree).
875
+ */
876
+ declare function useWorkforces(options?: UseWorkforcesOptions): UseWorkforcesResult;
877
+
660
878
  /**
661
879
  * Copy-paste this into a workforce agent system prompt (or append it to your
662
880
  * blueprint's tool-result instructions) so the model knows which artifact
@@ -737,13 +955,12 @@ type MarkdownSegment = {
737
955
  declare function splitMarkdownByArtifacts(markdown: string): MarkdownSegment[];
738
956
 
739
957
  /**
740
- * Drop-in replacement for `ToolFallback` that first tries to render the tool
741
- * result as an artifact via the registry. Falls back to the standard tool
742
- * panel when the result isn't artifact-shaped (or while the tool is still
743
- * running).
958
+ * Default `tools.Override` for assistant messages.
744
959
  *
745
- * Use this as the `tools.Fallback` in `MessagePrimitive.Parts` to enable
746
- * artifact rendering for any tool the agent calls.
960
+ * Renders the tool result as a registered artifact when possible; otherwise
961
+ * falls back to the timeline `ToolFallback`. Wraps the artifact in
962
+ * `ToolMotion` so it shares the same rise-from-below polish as the rest of
963
+ * the chat surface.
747
964
  */
748
965
  declare const ToolArtifactFallback: ToolCallMessagePartComponent;
749
966
 
@@ -773,10 +990,10 @@ declare const ChartArtifactView: FC<{
773
990
  }>;
774
991
 
775
992
  /**
776
- * Inline choice widget. Single-select submits immediately on click;
777
- * multi-select shows a confirm button. The answer is sent as a regular user
778
- * message via the assistant-ui runtime, so the agent treats it like any
779
- * other reply.
993
+ * In-thread choice widget. Single-select submits immediately on click;
994
+ * multi-select shows a confirm button. The answer is sent as a regular
995
+ * user message via the assistant-ui runtime so the agent treats it like
996
+ * any other reply.
780
997
  */
781
998
  declare const QuestionArtifactView: FC<{
782
999
  artifact: QuestionArtifact;
@@ -804,103 +1021,6 @@ declare const TableArtifactView: FC<{
804
1021
  artifact: TableArtifact;
805
1022
  }>;
806
1023
 
807
- declare const UserMessageAttachments: FC;
808
- declare const ComposerAttachments: FC;
809
- declare const ComposerAddAttachment: FC;
810
-
811
- declare const buttonVariants: (props?: ({
812
- variant?: "default" | "outline" | "ghost" | "secondary" | "destructive" | "link" | null | undefined;
813
- size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
814
- } & class_variance_authority_types.ClassProp) | undefined) => string;
815
- declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
816
- asChild?: boolean;
817
- }): react_jsx_runtime.JSX.Element;
818
-
819
- type TooltipIconButtonProps = ComponentPropsWithRef<typeof Button> & {
820
- tooltip: string;
821
- side?: "top" | "bottom" | "left" | "right";
822
- };
823
- declare const TooltipIconButton: React.ForwardRefExoticComponent<Omit<TooltipIconButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
824
-
825
- declare const ShikiSyntaxHighlighter: FC<SyntaxHighlighterProps>;
826
-
827
- type FetchFn = (url: string, options?: RequestInit) => Promise<Response>;
828
- interface UseWorkforcesOptions {
829
- /** Base URL for API calls. Default: `/api`. */
830
- baseUrl?: string;
831
- /** Custom fetch (defaults to `authFetch` for token-auth flows). */
832
- fetch?: FetchFn;
833
- /**
834
- * Pick the initial selected workforce. By default we prefer the first
835
- * `type === "agent"` entry, falling back to the first item. Pass a custom
836
- * resolver to override (e.g. remember the user's last choice).
837
- */
838
- pickInitial?: (items: WorkforceItem[]) => WorkforceItem | undefined;
839
- }
840
- interface UseWorkforcesResult {
841
- workforces: WorkforceItem[];
842
- /** Currently selected workforce identifier (id ?? uid ?? name). */
843
- selectedId: string;
844
- setSelectedId: (id: string) => void;
845
- /** The full `WorkforceItem` for `selectedId`, if any. */
846
- selected: WorkforceItem | undefined;
847
- isLoading: boolean;
848
- error: Error | null;
849
- /** Re-fetch the list. Resets `error`. */
850
- refresh: () => Promise<void>;
851
- }
852
- /**
853
- * Fetch the list of workforces exposed by the blueprint API and track a
854
- * selection. Used to power `<WorkforceSelector />` but exported separately
855
- * so apps can drive their own UI (e.g. a sidebar tree).
856
- */
857
- declare function useWorkforces(options?: UseWorkforcesOptions): UseWorkforcesResult;
858
-
859
- interface WorkforceSelectorProps {
860
- /** List of workforces to choose from. */
861
- workforces: WorkforceItem[];
862
- /** Currently selected workforce id. */
863
- value: string;
864
- /** Called when the user picks a different workforce. */
865
- onChange: (id: string) => void;
866
- /** Hide the selector when there's only one option. Default: true. */
867
- hideWhenSingle?: boolean;
868
- className?: string;
869
- placeholder?: string;
870
- }
871
- /**
872
- * Minimal headless workforce picker — wraps a styled native `<select>` so
873
- * `timbal-react` doesn't need a Radix dropdown dependency. Apps that want a
874
- * richer UI (search, descriptions) can build their own using
875
- * `useWorkforces()`.
876
- */
877
- declare const WorkforceSelector: FC<WorkforceSelectorProps>;
878
-
879
- interface TimbalChatShellProps extends Omit<TimbalChatProps, "workforceId"> {
880
- /**
881
- * Pre-selected workforce id. When omitted, the shell fetches the workforce
882
- * list from `{baseUrl}/workforce` and picks the first agent automatically.
883
- */
884
- workforceId?: string;
885
- /** Branding rendered at the start of the header (logo, etc). */
886
- brand?: ReactNode;
887
- /** Extra content rendered at the end of the header (theme toggle, logout). */
888
- headerActions?: ReactNode;
889
- /** Hide the built-in workforce selector. Default: false. */
890
- hideWorkforceSelector?: boolean;
891
- /** Class for the outer flex container. */
892
- className?: string;
893
- /** Class for the header bar. */
894
- headerClassName?: string;
895
- }
896
- /**
897
- * Drop-in shell that combines the most common blueprint patterns: a header
898
- * with brand + workforce selector + actions, plus the chat thread occupying
899
- * the remaining vertical space. Falls back to `<TimbalChat>` directly when
900
- * `workforceId` is provided.
901
- */
902
- declare const TimbalChatShell: FC<TimbalChatShellProps>;
903
-
904
1024
  interface SessionContextType {
905
1025
  user: Session | null;
906
1026
  loading: boolean;
@@ -909,6 +1029,12 @@ interface SessionContextType {
909
1029
  logout: () => void;
910
1030
  }
911
1031
  declare const useSession: () => SessionContextType;
1032
+ /**
1033
+ * Read the session without throwing when no `SessionProvider` is present.
1034
+ * Returns `null` when auth is not wired into the tree — useful for surfaces
1035
+ * (e.g. sidebar footers) that should gracefully render without auth.
1036
+ */
1037
+ declare const useOptionalSession: () => SessionContextType | null;
912
1038
  interface SessionProviderProps {
913
1039
  children: React__default.ReactNode;
914
1040
  /** When false, session is always null and loading is false. Default: true */
@@ -933,6 +1059,14 @@ declare const refreshAccessToken: () => Promise<boolean>;
933
1059
  declare const authFetch: (url: string, options?: RequestInit) => Promise<Response>;
934
1060
  declare const fetchCurrentUser: () => Promise<Session | null>;
935
1061
 
1062
+ declare const buttonVariants: (props?: ({
1063
+ variant?: "default" | "outline" | "ghost" | "secondary" | "destructive" | "link" | null | undefined;
1064
+ size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
1065
+ } & class_variance_authority_types.ClassProp) | undefined) => string;
1066
+ declare function Button({ className, variant, size, asChild, ...props }: React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
1067
+ asChild?: boolean;
1068
+ }): react_jsx_runtime.JSX.Element;
1069
+
936
1070
  declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof Tooltip$1.Provider>): react_jsx_runtime.JSX.Element;
937
1071
  declare function Tooltip({ ...props }: React.ComponentProps<typeof Tooltip$1.Root>): react_jsx_runtime.JSX.Element;
938
1072
  declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof Tooltip$1.Trigger>): react_jsx_runtime.JSX.Element;
@@ -963,6 +1097,47 @@ interface TextShimmerProps {
963
1097
  }
964
1098
  declare const Shimmer: React.MemoExoticComponent<({ children, as: Component, className, duration, spread, }: TextShimmerProps) => react_jsx_runtime.JSX.Element>;
965
1099
 
1100
+ /**
1101
+ * Timbal V2 button design tokens.
1102
+ *
1103
+ * Mirrors the `timbal-platform` design language (`TimbalV2Button`) so chat
1104
+ * surfaces built with the SDK feel identical to the Timbal Studio. Each record
1105
+ * is keyed by variant or size and ships only Tailwind utility classes — no
1106
+ * runtime JS — so consumers can compose them with `cn(...)` and add their own
1107
+ * overrides without ejecting.
1108
+ *
1109
+ * Every colour is resolved through semantic CSS variables defined in
1110
+ * `styles.css`. There are NO hardcoded palette literals — light/dark mode
1111
+ * flips by swapping the variable values, not by toggling Tailwind classes.
1112
+ */
1113
+ type TimbalV2Variant = "primary" | "secondary" | "ghost" | "informative" | "destructive" | "link";
1114
+ type TimbalV2Size = "xs" | "sm" | "md" | "lg";
1115
+
1116
+ interface TimbalV2ButtonProps extends React.ComponentProps<"button"> {
1117
+ variant?: TimbalV2Variant;
1118
+ size?: TimbalV2Size;
1119
+ isIconOnly?: boolean;
1120
+ isLoading?: boolean;
1121
+ fullWidth?: boolean;
1122
+ /** When true, renders children as the underlying element (Radix Slot pattern). */
1123
+ asChild?: boolean;
1124
+ }
1125
+
1126
+ interface TooltipIconButtonProps extends Omit<TimbalV2ButtonProps, "isIconOnly"> {
1127
+ /** Visible tooltip + accessible label. Always required. */
1128
+ tooltip: string;
1129
+ /** Tooltip placement. Default: "bottom". */
1130
+ side?: "top" | "bottom" | "left" | "right";
1131
+ }
1132
+ /**
1133
+ * Icon-only Timbal pill button with a tooltip. Used by every chat-surface
1134
+ * toolbar (composer send/cancel, message action bar, scroll-to-bottom).
1135
+ *
1136
+ * Defaults to a soft `secondary` variant so it sits cleanly inside composers,
1137
+ * message bubbles, and the action bar. Override via `variant`.
1138
+ */
1139
+ declare const TooltipIconButton: React.ForwardRefExoticComponent<Omit<TooltipIconButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
1140
+
966
1141
  declare function cn(...inputs: ClassValue[]): string;
967
1142
 
968
- export { ARTIFACT_AGENT_INSTRUCTIONS, ARTIFACT_FENCE_LANGUAGES, type AnyArtifact, ArtifactCard, type ArtifactRegistry, ArtifactRegistryProvider, type ArtifactRenderer, type ArtifactRendererProps, ArtifactView, AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, type ChartArtifact, ChartArtifactView, type ChatAttachment, type ChatMessage, Composer, ComposerAddAttachment, ComposerAttachments, type ComposerProps, type ContentPart, type CreateDefaultAttachmentAdapterOptions, type CreateUploadAttachmentAdapterOptions, DEFAULT_UPLOAD_ACCEPT, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, type HtmlArtifact, HtmlArtifactView, type JsonArtifact, JsonArtifactView, type MarkdownArtifactMatch, type MarkdownSegment, MarkdownText, type QuestionArtifact, QuestionArtifactView, type QuestionOption, type ResolveAttachmentAdapterOptions, type SendOptions, SessionProvider, Shimmer, Suggestions, type SuggestionsComponent, type SuggestionsSlotProps, type SuggestionsSource, ShikiSyntaxHighlighter as SyntaxHighlighter, type TableArtifact, TableArtifactView, type TextContentPart, type TextShimmerProps, type ThinkingContentPart, Thread, type ThreadArtifactsConfig, type ThreadComponents, type ThreadProps, type ThreadSuggestion, type ThreadSuggestionsProps, type ThreadWelcomeConfig, type ThreadWelcomeProps, type TimbalArtifact, type TimbalAttachmentsConfig, type TimbalAttachmentsProp, TimbalChat, type TimbalChatProps, TimbalChatShell, type TimbalChatShellProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, type TimbalStreamApi, ToolArtifactFallback, type ToolCallContentPart, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, type UiAction, type UiArtifact, UiArtifactView, UiCustomNodeRegistryProvider, type UiEventEnvelope, UiEventProvider, type UiNode, UiNodeView, type UploadFetchFn, type UseTimbalStreamOptions, type UseWorkforcesOptions, type UseWorkforcesResult, UserMessageAttachments, WorkforceSelector, type WorkforceSelectorProps, authFetch, buttonVariants, clearTokens, cn, createDefaultAttachmentAdapter, createUploadAttachmentAdapter, defaultArtifactRenderers, fetchCurrentUser, findMarkdownArtifacts, getAccessToken, getPath, getRefreshToken, isArtifact, isArtifactFenceLanguage, isUiBinding, parseArtifactFromToolResult, refreshAccessToken, resolveAttachmentAdapter, resolveBindable, setAccessToken, setPath, setRefreshToken, splitMarkdownByArtifacts, useArtifactRegistry, useResolvedSuggestions, useSession, useTimbalRuntime, useTimbalStream, useUiCustomNodeRegistry, useUiDispatch, useUiEventEmitter, useUiState, useWorkforces };
1143
+ export { ARTIFACT_AGENT_INSTRUCTIONS, ARTIFACT_FENCE_LANGUAGES, type AnyArtifact, ArtifactCard, type ArtifactRegistry, ArtifactRegistryProvider, type ArtifactRenderer, type ArtifactRendererProps, ArtifactView, AuthGuard, Avatar, AvatarFallback, AvatarImage, Button, type ChartArtifact, ChartArtifactView, type ChatAttachment, type ChatMessage, Composer, type ComposerProps, type ContentPart, type CreateDefaultAttachmentAdapterOptions, type CreateUploadAttachmentAdapterOptions, DEFAULT_UPLOAD_ACCEPT, Dialog, DialogClose, DialogContent, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, type HtmlArtifact, HtmlArtifactView, type JsonArtifact, JsonArtifactView, type MarkdownArtifactMatch, type MarkdownSegment, MarkdownText, ModeToggle, type ModeToggleProps, type ModeToggleTheme, type QuestionArtifact, QuestionArtifactView, type QuestionOption, type ResolveAttachmentAdapterOptions, type SendOptions, SessionProvider, Shimmer, StudioSidebar, type StudioSidebarProps, StudioWelcome, type StudioWelcomeProps, Suggestions, type SuggestionsComponent, type SuggestionsSlotProps, type SuggestionsSource, type TableArtifact, TableArtifactView, type TextContentPart, type TextShimmerProps, type ThinkingContentPart, Thread, type ThreadArtifactsConfig, type ThreadComponents, type ThreadProps, type ThreadSuggestion, type ThreadSuggestionsProps, type ThreadWelcomeConfig, type ThreadWelcomeProps, type TimbalArtifact, type TimbalAttachmentsConfig, type TimbalAttachmentsProp, TimbalChat, type TimbalChatProps, TimbalChatShell, type TimbalChatShellProps, TimbalMark, type TimbalMarkProps, TimbalRuntimeProvider, type TimbalRuntimeProviderProps, type TimbalStreamApi, TimbalStudioShell, type TimbalStudioShellProps, ToolArtifactFallback, type ToolCallContentPart, ToolFallback, Tooltip, TooltipContent, TooltipIconButton, type TooltipIconButtonProps, TooltipProvider, TooltipTrigger, type UiAction, type UiArtifact, UiArtifactView, UiCustomNodeRegistryProvider, type UiEventEnvelope, UiEventProvider, type UiNode, UiNodeView, type UploadFetchFn, type UseTimbalStreamOptions, type UseWorkforcesOptions, type UseWorkforcesResult, WorkforceSelector, type WorkforceSelectorProps, authFetch, clearTokens, cn, createDefaultAttachmentAdapter, createUploadAttachmentAdapter, defaultArtifactRenderers, fetchCurrentUser, findMarkdownArtifacts, getAccessToken, getPath, getRefreshToken, isArtifact, isArtifactFenceLanguage, isUiBinding, parseArtifactFromToolResult, refreshAccessToken, resolveAttachmentAdapter, resolveBindable, setAccessToken, setPath, setRefreshToken, splitMarkdownByArtifacts, useArtifactRegistry, useOptionalSession, useResolvedSuggestions, useSession, useTimbalRuntime, useTimbalStream, useToolRunning, useUiCustomNodeRegistry, useUiDispatch, useUiEventEmitter, useUiState, useWorkforces };