@agents24/chat-react 0.1.10 → 0.3.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/model.d.ts CHANGED
@@ -9,7 +9,6 @@ export declare const titleFromMessage: (text: string, files?: Array<{
9
9
  export declare const threadActivityDate: (thread: ChatThreadSummary) => string;
10
10
  export declare const assistantTextFromResponseBlocks: (blocks?: Array<Record<string, unknown>>) => string;
11
11
  export declare const assistantTextFromParts: (parts?: ChatPart[]) => string;
12
- export declare const textFromFinalOutput: (value: unknown) => string;
13
12
  export declare const toolStateFromStatus: (status?: unknown) => ChatToolState;
14
13
  export declare const partsFromResponseBlocks: (blocks?: Array<Record<string, unknown>>, fallbackText?: string) => ChatPart[];
15
14
  export declare const mergeReasoningSteps: (steps?: ChatReasoningStep[], options?: {
@@ -253,6 +253,7 @@ function LatestThreadScrollerOutline({
253
253
  );
254
254
  };
255
255
  updateSideRoom();
256
+ if (typeof ResizeObserver === "undefined") return;
256
257
  const resizeObserver = new ResizeObserver(updateSideRoom);
257
258
  resizeObserver.observe(root);
258
259
  const content = layout?.contentElement;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/templates/index.ts","../../src/templates/agent-chat-shell.tsx","../../src/latest-thread-scroller.tsx","../../src/ui/utils.ts"],"sourcesContent":["export * from \"./agent-chat-shell\";\n","import * as React from \"react\";\n\nimport {\n LatestThreadScroller,\n type LatestThreadScrollerOutlineItem,\n} from \"../latest-thread-scroller\";\nimport type { ChatMessage } from \"../types\";\nimport { cn } from \"../ui/utils\";\n\nexport type AgentChatShellMessage = Pick<ChatMessage, \"id\" | \"role\" | \"content\"> & {\n [key: string]: unknown;\n};\n\nexport type AgentChatShellScrollState = {\n canScroll: boolean;\n isScrolled: boolean;\n};\n\nexport type AgentChatShellProps<TMessage extends AgentChatShellMessage> = {\n className?: string;\n contentClassName?: string;\n composer?: React.ReactNode;\n composerOverlayClassName?: string;\n composerOverlayHeight?: number;\n defaultComposerOverlayHeight?: number;\n dir?: \"ltr\" | \"rtl\";\n emptyInputAttachmentCount?: number;\n emptyTitle?: string;\n hideComposer?: boolean;\n isLoadingOlder?: boolean;\n messages: TMessage[];\n onLoadOlder?: (() => Promise<unknown> | unknown) | null;\n onScrollStateChange?: (state: AgentChatShellScrollState) => void;\n outlineItems?: LatestThreadScrollerOutlineItem[];\n outlineSide?: \"left\" | \"right\";\n renderEmptyState?: (input: { composer?: React.ReactNode; title: string }) => React.ReactNode;\n renderMessage: (message: TMessage, index: number) => React.ReactNode;\n renderOlderLoader?: () => React.ReactNode;\n};\n\nexport function getAgentChatShellScrollState(\n viewport: Pick<HTMLElement, \"clientHeight\" | \"scrollHeight\" | \"scrollTop\">\n): AgentChatShellScrollState {\n const canScroll = viewport.scrollHeight - viewport.clientHeight > 1;\n return {\n canScroll,\n isScrolled: canScroll && viewport.scrollTop > 4,\n };\n}\n\nconst defaultOutlineLabel = (content: unknown, index: number) => {\n const label = String(content || \"\").replace(/\\s+/g, \" \").trim();\n return label || `Turn ${index + 1}`;\n};\n\nconst defaultOutlinePreview = (content: unknown) =>\n String(content || \"\").replace(/\\s+/g, \" \").trim();\n\nexport function buildAgentChatOutlineItems<TMessage extends AgentChatShellMessage>(\n messages: TMessage[],\n getLabel: (message: TMessage, index: number) => string = (message, index) =>\n defaultOutlineLabel(message.content, index),\n getResponsePreview: (message: TMessage) => string = (message) =>\n defaultOutlinePreview(message.content)\n): LatestThreadScrollerOutlineItem[] {\n return messages.reduce((items, message) => {\n if (message.role === \"user\") {\n items.push({\n id: message.id,\n label: getLabel(message, items.length),\n messageIds: [message.id],\n });\n return items;\n }\n const currentItem = items[items.length - 1];\n currentItem?.messageIds?.push(message.id);\n if (\n currentItem &&\n !currentItem.responsePreview &&\n message.role === \"assistant\"\n ) {\n currentItem.responsePreview = getResponsePreview(message);\n }\n return items;\n }, [] as LatestThreadScrollerOutlineItem[]);\n}\n\nexport function AgentChatShell<TMessage extends AgentChatShellMessage>({\n className,\n composer,\n composerOverlayClassName,\n composerOverlayHeight,\n contentClassName,\n defaultComposerOverlayHeight = 192,\n dir = \"ltr\",\n emptyInputAttachmentCount = 0,\n emptyTitle = \"Ready when you are.\",\n hideComposer = false,\n isLoadingOlder = false,\n messages,\n onLoadOlder,\n onScrollStateChange,\n outlineItems,\n outlineSide = \"left\",\n renderEmptyState,\n renderMessage,\n renderOlderLoader,\n}: AgentChatShellProps<TMessage>) {\n const overlayRef = React.useRef<HTMLDivElement | null>(null);\n const viewportRef = React.useRef<HTMLElement | null>(null);\n const contentRef = React.useRef<HTMLDivElement | null>(null);\n const lastScrollStateRef = React.useRef<AgentChatShellScrollState | null>(null);\n const [measuredOverlayHeight, setMeasuredOverlayHeight] = React.useState(\n defaultComposerOverlayHeight\n );\n const olderPageRequestRef = React.useRef(false);\n const items = React.useMemo(\n () => outlineItems || buildAgentChatOutlineItems(messages),\n [messages, outlineItems]\n );\n\n const updateScrollState = React.useCallback(() => {\n const viewport = viewportRef.current;\n if (!viewport || !onScrollStateChange) return;\n const next = getAgentChatShellScrollState(viewport);\n const previous = lastScrollStateRef.current;\n if (\n previous &&\n previous.canScroll === next.canScroll &&\n previous.isScrolled === next.isScrolled\n ) {\n return;\n }\n lastScrollStateRef.current = next;\n onScrollStateChange(next);\n }, [onScrollStateChange]);\n\n React.useEffect(() => {\n const overlay = overlayRef.current;\n if (!overlay || hideComposer) return;\n const updateHeight = () => {\n setMeasuredOverlayHeight(Math.ceil(overlay.getBoundingClientRect().height));\n };\n updateHeight();\n const observer = new ResizeObserver(updateHeight);\n observer.observe(overlay);\n return () => observer.disconnect();\n }, [hideComposer]);\n\n React.useEffect(() => {\n if (!onScrollStateChange) return;\n updateScrollState();\n const viewport = viewportRef.current;\n const content = contentRef.current;\n if (!viewport || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(updateScrollState);\n observer.observe(viewport);\n if (content) observer.observe(content);\n return () => observer.disconnect();\n }, [messages, onScrollStateChange, updateScrollState]);\n\n const handleScroll = React.useCallback(\n (event: React.UIEvent<HTMLDivElement>) => {\n updateScrollState();\n if (\n !onLoadOlder ||\n isLoadingOlder ||\n olderPageRequestRef.current ||\n event.currentTarget.scrollTop > 48\n ) {\n return;\n }\n olderPageRequestRef.current = true;\n void Promise.resolve(onLoadOlder()).finally(() => {\n olderPageRequestRef.current = false;\n });\n },\n [isLoadingOlder, onLoadOlder, updateScrollState]\n );\n\n const bottomPadding = hideComposer\n ? 32\n : (composerOverlayHeight ?? measuredOverlayHeight) + 72;\n const isEmptyState = messages.length === 0;\n\n if (isEmptyState) {\n return (\n <div className={cn(\"relative flex h-full min-h-0 w-full flex-col overflow-visible px-4\", className)} dir={dir}>\n {renderEmptyState ? (\n renderEmptyState({ composer: hideComposer ? undefined : composer, title: emptyTitle })\n ) : (\n <div className=\"relative z-10 flex h-full flex-1 flex-col justify-center p-0 pt-13\">\n <div className=\"flex w-full flex-col items-center pb-34 text-center animate-in fade-in slide-in-from-bottom-4 duration-500\">\n <p\n className={cn(\n \"pb-6 text-3xl font-semibold transition-transform duration-200\",\n emptyInputAttachmentCount > 0 && \"-translate-y-12\"\n )}\n >\n {emptyTitle}\n </p>\n {!hideComposer && composer ? (\n <div className=\"mx-auto w-full max-w-3xl px-4\">{composer}</div>\n ) : null}\n </div>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div className={cn(\"relative flex h-full min-h-0 w-full flex-col\", className)} dir={dir}>\n <LatestThreadScroller.Provider>\n <LatestThreadScroller.Root>\n <LatestThreadScroller.Viewport\n onScroll={handleScroll}\n onViewportChange={(node) => {\n viewportRef.current = node;\n updateScrollState();\n }}\n >\n <LatestThreadScroller.Content\n ref={contentRef}\n className={cn(\n \"mx-auto flex min-h-full w-full max-w-3xl flex-col gap-8 px-4 pt-12\",\n contentClassName\n )}\n style={{ paddingBottom: bottomPadding }}\n >\n {isLoadingOlder ? renderOlderLoader?.() : null}\n {messages.map((message, index) => (\n <LatestThreadScroller.Item\n key={message.id}\n messageId={message.id}\n scrollAnchor={message.role === \"user\"}\n >\n {renderMessage(message, index)}\n </LatestThreadScroller.Item>\n ))}\n </LatestThreadScroller.Content>\n </LatestThreadScroller.Viewport>\n <LatestThreadScroller.Outline\n dir={dir}\n items={items}\n side={outlineSide}\n />\n </LatestThreadScroller.Root>\n\n {!hideComposer && composer ? (\n <div\n ref={overlayRef}\n className={cn(\n \"pointer-events-none absolute inset-x-0 bottom-0 z-20 overflow-visible px-4 pb-4 pt-10\",\n composerOverlayClassName\n )}\n style={{\n background:\n \"linear-gradient(to bottom, transparent 0%, color-mix(in oklch, var(--chat-background, var(--background)) 85%, transparent) 45%, var(--chat-background, var(--background)) 65%, var(--chat-background, var(--background)) 100%)\",\n }}\n >\n <div className=\"pointer-events-auto absolute inset-x-0 top-0 flex -translate-y-full justify-center pb-3\">\n <LatestThreadScroller.Button />\n </div>\n <div className=\"pointer-events-auto mx-auto w-full max-w-3xl px-4\">\n {composer}\n </div>\n </div>\n ) : null}\n </LatestThreadScroller.Provider>\n </div>\n );\n}\n","import * as React from \"react\";\nimport {\n MessageScroller,\n useMessageScroller,\n useMessageScrollerVisibility,\n} from \"@shadcn/react/message-scroller\";\n\nconst cx = (...values: Array<string | false | null | undefined>) =>\n values.filter(Boolean).join(\" \");\n\ntype MessageScrollerProviderProps = React.ComponentProps<\n typeof MessageScroller.Provider\n>;\ntype MessageScrollerRootProps = React.ComponentProps<typeof MessageScroller.Root>;\ntype MessageScrollerViewportProps = React.ComponentProps<\n typeof MessageScroller.Viewport\n>;\ntype MessageScrollerContentProps = React.ComponentProps<\n typeof MessageScroller.Content\n>;\ntype MessageScrollerItemProps = React.ComponentProps<typeof MessageScroller.Item>;\ntype MessageScrollerButtonProps = React.ComponentProps<typeof MessageScroller.Button>;\n\ntype LatestThreadScrollerLayoutContextValue = {\n contentElement: HTMLElement | null;\n rootElement: HTMLElement | null;\n setContentElement: (node: HTMLElement | null) => void;\n setRootElement: (node: HTMLElement | null) => void;\n};\n\nconst LatestThreadScrollerLayoutContext =\n React.createContext<LatestThreadScrollerLayoutContextValue | null>(null);\n\nconst useLatestThreadScrollerLayout = () =>\n React.useContext(LatestThreadScrollerLayoutContext);\n\nexport type LatestThreadScrollerProviderProps = MessageScrollerProviderProps;\n\nexport function LatestThreadScrollerProvider({\n autoScroll = true,\n defaultScrollPosition = \"last-anchor\",\n scrollPreviousItemPeek = 64,\n ...props\n}: LatestThreadScrollerProviderProps) {\n return (\n <MessageScroller.Provider\n autoScroll={autoScroll}\n defaultScrollPosition={defaultScrollPosition}\n scrollPreviousItemPeek={scrollPreviousItemPeek}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerRootProps = MessageScrollerRootProps;\n\nexport function LatestThreadScrollerRoot({\n className,\n ref,\n ...props\n}: LatestThreadScrollerRootProps) {\n const [rootElement, setRootElement] = React.useState<HTMLElement | null>(null);\n const [contentElement, setContentElement] =\n React.useState<HTMLElement | null>(null);\n const layoutContext = React.useMemo<LatestThreadScrollerLayoutContextValue>(\n () => ({\n contentElement,\n rootElement,\n setContentElement,\n setRootElement,\n }),\n [contentElement, rootElement]\n );\n const setRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n setRootElement(node);\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref]\n );\n\n return (\n <LatestThreadScrollerLayoutContext.Provider value={layoutContext}>\n <MessageScroller.Root\n ref={setRef}\n className={cx(\n \"relative flex size-full min-h-0 flex-1 flex-col overflow-hidden\",\n className\n )}\n {...props}\n />\n </LatestThreadScrollerLayoutContext.Provider>\n );\n}\n\nexport type LatestThreadScrollerViewportProps =\n MessageScrollerViewportProps & {\n onViewportChange?: (node: HTMLElement | null) => void;\n };\n\nexport function LatestThreadScrollerViewport({\n className,\n onViewportChange,\n preserveScrollOnPrepend = true,\n ref,\n ...props\n}: LatestThreadScrollerViewportProps) {\n const setRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n onViewportChange?.(node);\n },\n [onViewportChange, ref]\n );\n\n return (\n <MessageScroller.Viewport\n ref={setRef}\n className={cx(\n \"size-full min-h-0 min-w-0 flex-1 overflow-y-auto overscroll-contain\",\n className\n )}\n preserveScrollOnPrepend={preserveScrollOnPrepend}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerContentProps = MessageScrollerContentProps;\n\nexport function LatestThreadScrollerContent({\n className,\n ref,\n ...props\n}: LatestThreadScrollerContentProps) {\n const layout = useLatestThreadScrollerLayout();\n const setRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n layout?.setContentElement(node);\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n },\n [layout, ref]\n );\n\n return (\n <MessageScroller.Content\n ref={setRef}\n data-agents24-latest-thread-content=\"\"\n className={cx(\"flex h-max min-h-full flex-col gap-8 p-4\", className)}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerItemProps = Omit<\n MessageScrollerItemProps,\n \"messageId\"\n> & {\n messageId: string;\n};\n\nexport function LatestThreadScrollerItem({\n className,\n messageId,\n ...props\n}: LatestThreadScrollerItemProps) {\n return (\n <MessageScroller.Item\n className={cx(\n \"min-w-0 shrink-0 overflow-visible\",\n className\n )}\n messageId={messageId}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerButtonProps = Omit<\n MessageScrollerButtonProps,\n \"render\"\n> & {\n className?: string;\n render?: MessageScrollerButtonProps[\"render\"];\n};\n\nexport function LatestThreadScrollerButton({\n children,\n className,\n direction = \"end\",\n render,\n ...props\n}: LatestThreadScrollerButtonProps) {\n if (render) {\n return (\n <MessageScroller.Button\n direction={direction}\n render={render}\n {...props}\n />\n );\n }\n\n return (\n <MessageScroller.Button\n direction={direction}\n render={(buttonProps) => (\n <button\n {...(buttonProps as Record<string, unknown>)}\n aria-label={\n direction === \"end\"\n ? \"Scroll to latest message\"\n : \"Scroll to first message\"\n }\n className={cx(\n \"absolute bottom-4 left-1/2 z-50 flex size-9 -translate-x-1/2 items-center justify-center rounded-full border border-border bg-background text-foreground shadow-md transition-all duration-200 data-[active=false]:pointer-events-none data-[active=false]:translate-y-2 data-[active=false]:opacity-0 data-[active=true]:translate-y-0 data-[active=true]:opacity-100\",\n className\n )}\n type=\"button\"\n >\n {children ?? (direction === \"end\" ? \"↓\" : \"↑\")}\n </button>\n )}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerOutlineItem = {\n id: string;\n label: string;\n messageIds?: string[];\n responsePreview?: string;\n};\n\nexport type LatestThreadScrollerOutlineProps = {\n cardClassName?: string;\n className?: string;\n contentMaxWidth?: number;\n dir?: \"ltr\" | \"rtl\";\n items: LatestThreadScrollerOutlineItem[];\n minContainerWidthForRail?: number;\n minSideGutterForRail?: number;\n side?: \"left\" | \"right\";\n};\n\nexport function LatestThreadScrollerOutline({\n cardClassName,\n className,\n contentMaxWidth = 768,\n dir = \"ltr\",\n items,\n minContainerWidthForRail = 0,\n minSideGutterForRail = 48,\n side,\n}: LatestThreadScrollerOutlineProps) {\n const navRef = React.useRef<HTMLElement | null>(null);\n const layout = useLatestThreadScrollerLayout();\n const [hasSideRoom, setHasSideRoom] = React.useState(false);\n const [hoveredIndex, setHoveredIndex] = React.useState<number | null>(null);\n const { scrollToMessage } = useMessageScroller();\n const { currentAnchorId, visibleMessageIds } = useMessageScrollerVisibility();\n const visibleMessageIdSet = React.useMemo(\n () => new Set(visibleMessageIds),\n [visibleMessageIds]\n );\n const focusIndex = hoveredIndex ?? -1;\n const railSide = side ?? (dir === \"rtl\" ? \"right\" : \"left\");\n\n React.useEffect(() => {\n const root = layout?.rootElement ?? navRef.current?.parentElement;\n if (!root) return;\n\n const updateSideRoom = () => {\n const rootRect = root.getBoundingClientRect();\n const rootWidth = rootRect.width;\n const content = layout?.contentElement;\n const sideGutter = content\n ? Math.max(\n 0,\n railSide === \"left\"\n ? content.getBoundingClientRect().left - rootRect.left\n : rootRect.right - content.getBoundingClientRect().right\n )\n : Math.max(0, (rootWidth - contentMaxWidth) / 2);\n const nextHasSideRoom =\n rootWidth >= minContainerWidthForRail &&\n sideGutter >= minSideGutterForRail;\n setHasSideRoom((current) =>\n current === nextHasSideRoom ? current : nextHasSideRoom\n );\n };\n\n updateSideRoom();\n const resizeObserver = new ResizeObserver(updateSideRoom);\n resizeObserver.observe(root);\n const content = layout?.contentElement;\n if (content) {\n resizeObserver.observe(content);\n }\n return () => resizeObserver.disconnect();\n }, [\n contentMaxWidth,\n layout?.contentElement,\n layout?.rootElement,\n minContainerWidthForRail,\n minSideGutterForRail,\n railSide,\n ]);\n\n if (items.length < 2) {\n return null;\n }\n\n return (\n <nav\n ref={navRef}\n aria-label=\"Transcript outline\"\n className={cx(\n \"pointer-events-none absolute top-[46%] z-10 max-h-[min(18rem,calc(100%-10rem))] w-16 -translate-y-1/2 overflow-visible\",\n hasSideRoom ? \"hidden md:block\" : \"hidden\",\n railSide === \"left\" ? \"left-1\" : \"right-1\",\n className\n )}\n dir={dir}\n >\n <div className=\"pointer-events-auto flex flex-col gap-0 py-1\">\n {items.map((item, index) => {\n const itemMessageIds =\n item.messageIds && item.messageIds.length > 0\n ? item.messageIds\n : [item.id];\n const active = itemMessageIds.some(\n (messageId) =>\n visibleMessageIdSet.has(messageId) || messageId === currentAnchorId\n );\n const distance =\n focusIndex >= 0 ? Math.abs(index - focusIndex) : Number.POSITIVE_INFINITY;\n const isFocused = distance === 0;\n const isNear = distance === 1;\n const isNextNear = distance === 2;\n const barWidth = isFocused\n ? 50\n : isNear\n ? 36\n : isNextNear\n ? 23\n : 10;\n const barOpacity = isFocused ? 1 : isNear ? 0.78 : isNextNear ? 0.58 : 0.36;\n const fallbackLabel = `Turn ${index + 1}`;\n const previewLabel =\n item.label && item.label !== fallbackLabel ? item.label : \"\";\n const responsePreview = (item.responsePreview || \"\").trim();\n\n return (\n <button\n key={item.id}\n type=\"button\"\n data-active={active}\n dir=\"ltr\"\n className={cx(\n \"group relative flex h-2 w-16 items-center rounded-sm outline-none\",\n railSide === \"left\" ? \"justify-start\" : \"justify-end\"\n )}\n aria-label={`Jump to ${item.label || fallbackLabel}`}\n onBlur={() => setHoveredIndex(null)}\n onFocus={() => setHoveredIndex(index)}\n onMouseEnter={() => setHoveredIndex(index)}\n onMouseLeave={() => setHoveredIndex(null)}\n onClick={() =>\n scrollToMessage(item.id, {\n align: \"start\",\n behavior: \"smooth\",\n })\n }\n >\n <span\n className=\"h-0.5 rounded-full bg-muted-foreground/55 transition-[width,background-color,opacity] duration-150 ease-out group-hover:bg-foreground group-focus-visible:bg-foreground group-data-[active=true]:bg-foreground\"\n style={{\n opacity: barOpacity,\n width: barWidth,\n }}\n />\n {previewLabel ? (\n <span\n dir={dir}\n className={cx(\n \"pointer-events-none absolute top-1/2 z-20 max-h-32 w-64 -translate-y-1/2 overflow-hidden rounded-lg border border-border/80 bg-background p-3 text-start opacity-0 shadow-lg transition-all duration-200 group-hover:pointer-events-auto group-hover:opacity-100 group-focus-visible:pointer-events-auto group-focus-visible:opacity-100\",\n railSide === \"left\"\n ? \"left-full ml-2 -translate-x-1 group-hover:translate-x-0 group-focus-visible:translate-x-0\"\n : \"right-full mr-2 translate-x-1 group-hover:translate-x-0 group-focus-visible:translate-x-0\",\n cardClassName\n )}\n >\n <span\n className=\"block overflow-hidden text-sm leading-5 text-foreground\"\n style={{\n display: \"-webkit-box\",\n WebkitBoxOrient: \"vertical\",\n WebkitLineClamp: responsePreview ? 2 : 4,\n }}\n >\n {previewLabel}\n </span>\n {responsePreview ? (\n <span\n className=\"mt-1 block overflow-hidden text-sm leading-5 text-muted-foreground\"\n style={{\n display: \"-webkit-box\",\n WebkitBoxOrient: \"vertical\",\n WebkitLineClamp: 2,\n }}\n >\n {responsePreview}\n </span>\n ) : null}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n </nav>\n );\n}\n\nexport const LatestThreadScroller = {\n Provider: LatestThreadScrollerProvider,\n Root: LatestThreadScrollerRoot,\n Viewport: LatestThreadScrollerViewport,\n Content: LatestThreadScrollerContent,\n Item: LatestThreadScrollerItem,\n Button: LatestThreadScrollerButton,\n Outline: LatestThreadScrollerOutline,\n};\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...values: ClassValue[]) {\n return twMerge(clsx(values));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,SAAuB;;;ACAvB,YAAuB;AACvB,8BAIO;AAwCH;AAtCJ,IAAM,KAAK,IAAI,WACb,OAAO,OAAO,OAAO,EAAE,KAAK,GAAG;AAsBjC,IAAM,oCACE,oBAA6D,IAAI;AAEzE,IAAM,gCAAgC,MAC9B,iBAAW,iCAAiC;AAI7C,SAAS,6BAA6B;AAAA,EAC3C,aAAa;AAAA,EACb,wBAAwB;AAAA,EACxB,yBAAyB;AAAA,EACzB,GAAG;AACL,GAAsC;AACpC,SACE;AAAA,IAAC,wCAAgB;AAAA,IAAhB;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,QAAM,CAAC,aAAa,cAAc,IAAU,eAA6B,IAAI;AAC7E,QAAM,CAAC,gBAAgB,iBAAiB,IAChC,eAA6B,IAAI;AACzC,QAAM,gBAAsB;AAAA,IAC1B,OAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB,WAAW;AAAA,EAC9B;AACA,QAAM,SAAe;AAAA,IACnB,CAAC,SAAgC;AAC/B,qBAAe,IAAI;AACnB,UAAI,OAAO,QAAQ,YAAY;AAC7B,YAAI,IAAI;AAAA,MACV,WAAW,KAAK;AACd,YAAI,UAAU;AAAA,MAChB;AAAA,IACF;AAAA,IACA,CAAC,GAAG;AAAA,EACN;AAEA,SACE,4CAAC,kCAAkC,UAAlC,EAA2C,OAAO,eACjD;AAAA,IAAC,wCAAgB;AAAA,IAAhB;AAAA,MACC,KAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA;AAAA,EACN,GACF;AAEJ;AAOO,SAAS,6BAA6B;AAAA,EAC3C;AAAA,EACA;AAAA,EACA,0BAA0B;AAAA,EAC1B;AAAA,EACA,GAAG;AACL,GAAsC;AACpC,QAAM,SAAe;AAAA,IACnB,CAAC,SAAgC;AAC/B,UAAI,OAAO,QAAQ,YAAY;AAC7B,YAAI,IAAI;AAAA,MACV,WAAW,KAAK;AACd,YAAI,UAAU;AAAA,MAChB;AACA,yBAAmB,IAAI;AAAA,IACzB;AAAA,IACA,CAAC,kBAAkB,GAAG;AAAA,EACxB;AAEA,SACE;AAAA,IAAC,wCAAgB;AAAA,IAAhB;AAAA,MACC,KAAK;AAAA,MACL,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAIO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAqC;AACnC,QAAM,SAAS,8BAA8B;AAC7C,QAAM,SAAe;AAAA,IACnB,CAAC,SAAgC;AAC/B,cAAQ,kBAAkB,IAAI;AAC9B,UAAI,OAAO,QAAQ,YAAY;AAC7B,YAAI,IAAI;AAAA,MACV,WAAW,KAAK;AACd,YAAI,UAAU;AAAA,MAChB;AAAA,IACF;AAAA,IACA,CAAC,QAAQ,GAAG;AAAA,EACd;AAEA,SACE;AAAA,IAAC,wCAAgB;AAAA,IAAhB;AAAA,MACC,KAAK;AAAA,MACL,uCAAoC;AAAA,MACpC,WAAW,GAAG,4CAA4C,SAAS;AAAA,MAClE,GAAG;AAAA;AAAA,EACN;AAEJ;AASO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAkC;AAChC,SACE;AAAA,IAAC,wCAAgB;AAAA,IAAhB;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;AAUO,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA,GAAG;AACL,GAAoC;AAClC,MAAI,QAAQ;AACV,WACE;AAAA,MAAC,wCAAgB;AAAA,MAAhB;AAAA,QACC;AAAA,QACA;AAAA,QACC,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC,wCAAgB;AAAA,IAAhB;AAAA,MACC;AAAA,MACA,QAAQ,CAAC,gBACP;AAAA,QAAC;AAAA;AAAA,UACE,GAAI;AAAA,UACL,cACE,cAAc,QACV,6BACA;AAAA,UAEN,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UACA,MAAK;AAAA,UAEJ,uBAAa,cAAc,QAAQ,WAAM;AAAA;AAAA,MAC5C;AAAA,MAED,GAAG;AAAA;AAAA,EACN;AAEJ;AAoBO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,MAAM;AAAA,EACN;AAAA,EACA,2BAA2B;AAAA,EAC3B,uBAAuB;AAAA,EACvB;AACF,GAAqC;AACnC,QAAM,SAAe,aAA2B,IAAI;AACpD,QAAM,SAAS,8BAA8B;AAC7C,QAAM,CAAC,aAAa,cAAc,IAAU,eAAS,KAAK;AAC1D,QAAM,CAAC,cAAc,eAAe,IAAU,eAAwB,IAAI;AAC1E,QAAM,EAAE,gBAAgB,QAAI,4CAAmB;AAC/C,QAAM,EAAE,iBAAiB,kBAAkB,QAAI,sDAA6B;AAC5E,QAAM,sBAA4B;AAAA,IAChC,MAAM,IAAI,IAAI,iBAAiB;AAAA,IAC/B,CAAC,iBAAiB;AAAA,EACpB;AACA,QAAM,aAAa,gBAAgB;AACnC,QAAM,WAAW,SAAS,QAAQ,QAAQ,UAAU;AAEpD,EAAM,gBAAU,MAAM;AACpB,UAAM,OAAO,QAAQ,eAAe,OAAO,SAAS;AACpD,QAAI,CAAC,KAAM;AAEX,UAAM,iBAAiB,MAAM;AAC3B,YAAM,WAAW,KAAK,sBAAsB;AAC5C,YAAM,YAAY,SAAS;AAC3B,YAAMC,WAAU,QAAQ;AACxB,YAAM,aAAaA,WACf,KAAK;AAAA,QACH;AAAA,QACA,aAAa,SACTA,SAAQ,sBAAsB,EAAE,OAAO,SAAS,OAChD,SAAS,QAAQA,SAAQ,sBAAsB,EAAE;AAAA,MACvD,IACA,KAAK,IAAI,IAAI,YAAY,mBAAmB,CAAC;AACjD,YAAM,kBACJ,aAAa,4BACb,cAAc;AAChB;AAAA,QAAe,CAAC,YACd,YAAY,kBAAkB,UAAU;AAAA,MAC1C;AAAA,IACF;AAEA,mBAAe;AACf,UAAM,iBAAiB,IAAI,eAAe,cAAc;AACxD,mBAAe,QAAQ,IAAI;AAC3B,UAAM,UAAU,QAAQ;AACxB,QAAI,SAAS;AACX,qBAAe,QAAQ,OAAO;AAAA,IAChC;AACA,WAAO,MAAM,eAAe,WAAW;AAAA,EACzC,GAAG;AAAA,IACD;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,MAAI,MAAM,SAAS,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,cAAW;AAAA,MACX,WAAW;AAAA,QACT;AAAA,QACA,cAAc,oBAAoB;AAAA,QAClC,aAAa,SAAS,WAAW;AAAA,QACjC;AAAA,MACF;AAAA,MACA;AAAA,MAEA,sDAAC,SAAI,WAAU,gDACZ,gBAAM,IAAI,CAAC,MAAM,UAAU;AAC1B,cAAM,iBACJ,KAAK,cAAc,KAAK,WAAW,SAAS,IACxC,KAAK,aACL,CAAC,KAAK,EAAE;AACd,cAAM,SAAS,eAAe;AAAA,UAC5B,CAAC,cACC,oBAAoB,IAAI,SAAS,KAAK,cAAc;AAAA,QACxD;AACA,cAAM,WACJ,cAAc,IAAI,KAAK,IAAI,QAAQ,UAAU,IAAI,OAAO;AAC1D,cAAM,YAAY,aAAa;AAC/B,cAAM,SAAS,aAAa;AAC5B,cAAM,aAAa,aAAa;AAChC,cAAM,WAAW,YACb,KACA,SACE,KACA,aACE,KACA;AACR,cAAM,aAAa,YAAY,IAAI,SAAS,OAAO,aAAa,OAAO;AACvE,cAAM,gBAAgB,QAAQ,QAAQ,CAAC;AACvC,cAAM,eACJ,KAAK,SAAS,KAAK,UAAU,gBAAgB,KAAK,QAAQ;AAC5D,cAAM,mBAAmB,KAAK,mBAAmB,IAAI,KAAK;AAE1D,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,eAAa;AAAA,YACb,KAAI;AAAA,YACJ,WAAW;AAAA,cACT;AAAA,cACA,aAAa,SAAS,kBAAkB;AAAA,YAC1C;AAAA,YACA,cAAY,WAAW,KAAK,SAAS,aAAa;AAAA,YAClD,QAAQ,MAAM,gBAAgB,IAAI;AAAA,YAClC,SAAS,MAAM,gBAAgB,KAAK;AAAA,YACpC,cAAc,MAAM,gBAAgB,KAAK;AAAA,YACzC,cAAc,MAAM,gBAAgB,IAAI;AAAA,YACxC,SAAS,MACP,gBAAgB,KAAK,IAAI;AAAA,cACvB,OAAO;AAAA,cACP,UAAU;AAAA,YACZ,CAAC;AAAA,YAGH;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,OAAO;AAAA,oBACL,SAAS;AAAA,oBACT,OAAO;AAAA,kBACT;AAAA;AAAA,cACF;AAAA,cACC,eACC;AAAA,gBAAC;AAAA;AAAA,kBACC;AAAA,kBACA,WAAW;AAAA,oBACT;AAAA,oBACA,aAAa,SACT,8FACA;AAAA,oBACJ;AAAA,kBACF;AAAA,kBAEA;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAU;AAAA,wBACV,OAAO;AAAA,0BACL,SAAS;AAAA,0BACT,iBAAiB;AAAA,0BACjB,iBAAiB,kBAAkB,IAAI;AAAA,wBACzC;AAAA,wBAEC;AAAA;AAAA,oBACH;AAAA,oBACC,kBACC;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAU;AAAA,wBACV,OAAO;AAAA,0BACL,SAAS;AAAA,0BACT,iBAAiB;AAAA,0BACjB,iBAAiB;AAAA,wBACnB;AAAA,wBAEC;AAAA;AAAA,oBACH,IACE;AAAA;AAAA;AAAA,cACN,IACE;AAAA;AAAA;AAAA,UA7DC,KAAK;AAAA,QA8DZ;AAAA,MAEJ,CAAC,GACH;AAAA;AAAA,EACF;AAEJ;AAEO,IAAM,uBAAuB;AAAA,EAClC,UAAU;AAAA,EACV,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AACX;;;AC9bA,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;AF2LY,IAAAC,sBAAA;AAxJL,SAAS,6BACd,UAC2B;AAC3B,QAAM,YAAY,SAAS,eAAe,SAAS,eAAe;AAClE,SAAO;AAAA,IACL;AAAA,IACA,YAAY,aAAa,SAAS,YAAY;AAAA,EAChD;AACF;AAEA,IAAM,sBAAsB,CAAC,SAAkB,UAAkB;AAC/D,QAAM,QAAQ,OAAO,WAAW,EAAE,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC9D,SAAO,SAAS,QAAQ,QAAQ,CAAC;AACnC;AAEA,IAAM,wBAAwB,CAAC,YAC7B,OAAO,WAAW,EAAE,EAAE,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAE3C,SAAS,2BACd,UACA,WAAyD,CAAC,SAAS,UACjE,oBAAoB,QAAQ,SAAS,KAAK,GAC5C,qBAAoD,CAAC,YACnD,sBAAsB,QAAQ,OAAO,GACJ;AACnC,SAAO,SAAS,OAAO,CAAC,OAAO,YAAY;AACzC,QAAI,QAAQ,SAAS,QAAQ;AAC3B,YAAM,KAAK;AAAA,QACT,IAAI,QAAQ;AAAA,QACZ,OAAO,SAAS,SAAS,MAAM,MAAM;AAAA,QACrC,YAAY,CAAC,QAAQ,EAAE;AAAA,MACzB,CAAC;AACD,aAAO;AAAA,IACT;AACA,UAAM,cAAc,MAAM,MAAM,SAAS,CAAC;AAC1C,iBAAa,YAAY,KAAK,QAAQ,EAAE;AACxC,QACE,eACA,CAAC,YAAY,mBACb,QAAQ,SAAS,aACjB;AACA,kBAAY,kBAAkB,mBAAmB,OAAO;AAAA,IAC1D;AACA,WAAO;AAAA,EACT,GAAG,CAAC,CAAsC;AAC5C;AAEO,SAAS,eAAuD;AAAA,EACrE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,+BAA+B;AAAA,EAC/B,MAAM;AAAA,EACN,4BAA4B;AAAA,EAC5B,aAAa;AAAA,EACb,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AACF,GAAkC;AAChC,QAAM,aAAmB,cAA8B,IAAI;AAC3D,QAAM,cAAoB,cAA2B,IAAI;AACzD,QAAM,aAAmB,cAA8B,IAAI;AAC3D,QAAM,qBAA2B,cAAyC,IAAI;AAC9E,QAAM,CAAC,uBAAuB,wBAAwB,IAAU;AAAA,IAC9D;AAAA,EACF;AACA,QAAM,sBAA4B,cAAO,KAAK;AAC9C,QAAM,QAAc;AAAA,IAClB,MAAM,gBAAgB,2BAA2B,QAAQ;AAAA,IACzD,CAAC,UAAU,YAAY;AAAA,EACzB;AAEA,QAAM,oBAA0B,mBAAY,MAAM;AAChD,UAAM,WAAW,YAAY;AAC7B,QAAI,CAAC,YAAY,CAAC,oBAAqB;AACvC,UAAM,OAAO,6BAA6B,QAAQ;AAClD,UAAM,WAAW,mBAAmB;AACpC,QACE,YACA,SAAS,cAAc,KAAK,aAC5B,SAAS,eAAe,KAAK,YAC7B;AACA;AAAA,IACF;AACA,uBAAmB,UAAU;AAC7B,wBAAoB,IAAI;AAAA,EAC1B,GAAG,CAAC,mBAAmB,CAAC;AAExB,EAAM,iBAAU,MAAM;AACpB,UAAM,UAAU,WAAW;AAC3B,QAAI,CAAC,WAAW,aAAc;AAC9B,UAAM,eAAe,MAAM;AACzB,+BAAyB,KAAK,KAAK,QAAQ,sBAAsB,EAAE,MAAM,CAAC;AAAA,IAC5E;AACA,iBAAa;AACb,UAAM,WAAW,IAAI,eAAe,YAAY;AAChD,aAAS,QAAQ,OAAO;AACxB,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,YAAY,CAAC;AAEjB,EAAM,iBAAU,MAAM;AACpB,QAAI,CAAC,oBAAqB;AAC1B,sBAAkB;AAClB,UAAM,WAAW,YAAY;AAC7B,UAAM,UAAU,WAAW;AAC3B,QAAI,CAAC,YAAY,OAAO,mBAAmB,YAAa;AACxD,UAAM,WAAW,IAAI,eAAe,iBAAiB;AACrD,aAAS,QAAQ,QAAQ;AACzB,QAAI,QAAS,UAAS,QAAQ,OAAO;AACrC,WAAO,MAAM,SAAS,WAAW;AAAA,EACnC,GAAG,CAAC,UAAU,qBAAqB,iBAAiB,CAAC;AAErD,QAAM,eAAqB;AAAA,IACzB,CAAC,UAAyC;AACxC,wBAAkB;AAClB,UACE,CAAC,eACD,kBACA,oBAAoB,WACpB,MAAM,cAAc,YAAY,IAChC;AACA;AAAA,MACF;AACA,0BAAoB,UAAU;AAC9B,WAAK,QAAQ,QAAQ,YAAY,CAAC,EAAE,QAAQ,MAAM;AAChD,4BAAoB,UAAU;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,IACA,CAAC,gBAAgB,aAAa,iBAAiB;AAAA,EACjD;AAEA,QAAM,gBAAgB,eAClB,MACC,yBAAyB,yBAAyB;AACvD,QAAM,eAAe,SAAS,WAAW;AAEzC,MAAI,cAAc;AAChB,WACE,6CAAC,SAAI,WAAW,GAAG,sEAAsE,SAAS,GAAG,KAClG,6BACC,iBAAiB,EAAE,UAAU,eAAe,SAAY,UAAU,OAAO,WAAW,CAAC,IAErF,6CAAC,SAAI,WAAU,sEACb,wDAAC,SAAI,WAAU,8GACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,4BAA4B,KAAK;AAAA,UACnC;AAAA,UAEC;AAAA;AAAA,MACH;AAAA,MACC,CAAC,gBAAgB,WAChB,6CAAC,SAAI,WAAU,iCAAiC,oBAAS,IACvD;AAAA,OACN,GACF,GAEJ;AAAA,EAEJ;AAEA,SACE,6CAAC,SAAI,WAAW,GAAG,gDAAgD,SAAS,GAAG,KAC7E,wDAAC,qBAAqB,UAArB,EACC;AAAA,kDAAC,qBAAqB,MAArB,EACC;AAAA;AAAA,QAAC,qBAAqB;AAAA,QAArB;AAAA,UACC,UAAU;AAAA,UACV,kBAAkB,CAAC,SAAS;AAC1B,wBAAY,UAAU;AACtB,8BAAkB;AAAA,UACpB;AAAA,UAEA;AAAA,YAAC,qBAAqB;AAAA,YAArB;AAAA,cACC,KAAK;AAAA,cACL,WAAW;AAAA,gBACT;AAAA,gBACA;AAAA,cACF;AAAA,cACA,OAAO,EAAE,eAAe,cAAc;AAAA,cAErC;AAAA,iCAAiB,oBAAoB,IAAI;AAAA,gBACzC,SAAS,IAAI,CAAC,SAAS,UACtB;AAAA,kBAAC,qBAAqB;AAAA,kBAArB;AAAA,oBAEC,WAAW,QAAQ;AAAA,oBACnB,cAAc,QAAQ,SAAS;AAAA,oBAE9B,wBAAc,SAAS,KAAK;AAAA;AAAA,kBAJxB,QAAQ;AAAA,gBAKf,CACD;AAAA;AAAA;AAAA,UACH;AAAA;AAAA,MACF;AAAA,MACA;AAAA,QAAC,qBAAqB;AAAA,QAArB;AAAA,UACC;AAAA,UACA;AAAA,UACA,MAAM;AAAA;AAAA,MACR;AAAA,OACF;AAAA,IAEC,CAAC,gBAAgB,WAChB;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAW;AAAA,UACT;AAAA,UACA;AAAA,QACF;AAAA,QACA,OAAO;AAAA,UACL,YACE;AAAA,QACJ;AAAA,QAEA;AAAA,uDAAC,SAAI,WAAU,2FACb,uDAAC,qBAAqB,QAArB,EAA4B,GAC/B;AAAA,UACA,6CAAC,SAAI,WAAU,qDACZ,oBACH;AAAA;AAAA;AAAA,IACF,IACE;AAAA,KACN,GACF;AAEJ;","names":["React","content","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/templates/index.ts","../../src/templates/agent-chat-shell.tsx","../../src/latest-thread-scroller.tsx","../../src/ui/utils.ts"],"sourcesContent":["export * from \"./agent-chat-shell\";\n","import * as React from \"react\";\n\nimport {\n LatestThreadScroller,\n type LatestThreadScrollerOutlineItem,\n} from \"../latest-thread-scroller\";\nimport type { ChatMessage } from \"../types\";\nimport { cn } from \"../ui/utils\";\n\nexport type AgentChatShellMessage = Pick<ChatMessage, \"id\" | \"role\" | \"content\"> & {\n [key: string]: unknown;\n};\n\nexport type AgentChatShellScrollState = {\n canScroll: boolean;\n isScrolled: boolean;\n};\n\nexport type AgentChatShellProps<TMessage extends AgentChatShellMessage> = {\n className?: string;\n contentClassName?: string;\n composer?: React.ReactNode;\n composerOverlayClassName?: string;\n composerOverlayHeight?: number;\n defaultComposerOverlayHeight?: number;\n dir?: \"ltr\" | \"rtl\";\n emptyInputAttachmentCount?: number;\n emptyTitle?: string;\n hideComposer?: boolean;\n isLoadingOlder?: boolean;\n messages: TMessage[];\n onLoadOlder?: (() => Promise<unknown> | unknown) | null;\n onScrollStateChange?: (state: AgentChatShellScrollState) => void;\n outlineItems?: LatestThreadScrollerOutlineItem[];\n outlineSide?: \"left\" | \"right\";\n renderEmptyState?: (input: { composer?: React.ReactNode; title: string }) => React.ReactNode;\n renderMessage: (message: TMessage, index: number) => React.ReactNode;\n renderOlderLoader?: () => React.ReactNode;\n};\n\nexport function getAgentChatShellScrollState(\n viewport: Pick<HTMLElement, \"clientHeight\" | \"scrollHeight\" | \"scrollTop\">\n): AgentChatShellScrollState {\n const canScroll = viewport.scrollHeight - viewport.clientHeight > 1;\n return {\n canScroll,\n isScrolled: canScroll && viewport.scrollTop > 4,\n };\n}\n\nconst defaultOutlineLabel = (content: unknown, index: number) => {\n const label = String(content || \"\").replace(/\\s+/g, \" \").trim();\n return label || `Turn ${index + 1}`;\n};\n\nconst defaultOutlinePreview = (content: unknown) =>\n String(content || \"\").replace(/\\s+/g, \" \").trim();\n\nexport function buildAgentChatOutlineItems<TMessage extends AgentChatShellMessage>(\n messages: TMessage[],\n getLabel: (message: TMessage, index: number) => string = (message, index) =>\n defaultOutlineLabel(message.content, index),\n getResponsePreview: (message: TMessage) => string = (message) =>\n defaultOutlinePreview(message.content)\n): LatestThreadScrollerOutlineItem[] {\n return messages.reduce((items, message) => {\n if (message.role === \"user\") {\n items.push({\n id: message.id,\n label: getLabel(message, items.length),\n messageIds: [message.id],\n });\n return items;\n }\n const currentItem = items[items.length - 1];\n currentItem?.messageIds?.push(message.id);\n if (\n currentItem &&\n !currentItem.responsePreview &&\n message.role === \"assistant\"\n ) {\n currentItem.responsePreview = getResponsePreview(message);\n }\n return items;\n }, [] as LatestThreadScrollerOutlineItem[]);\n}\n\nexport function AgentChatShell<TMessage extends AgentChatShellMessage>({\n className,\n composer,\n composerOverlayClassName,\n composerOverlayHeight,\n contentClassName,\n defaultComposerOverlayHeight = 192,\n dir = \"ltr\",\n emptyInputAttachmentCount = 0,\n emptyTitle = \"Ready when you are.\",\n hideComposer = false,\n isLoadingOlder = false,\n messages,\n onLoadOlder,\n onScrollStateChange,\n outlineItems,\n outlineSide = \"left\",\n renderEmptyState,\n renderMessage,\n renderOlderLoader,\n}: AgentChatShellProps<TMessage>) {\n const overlayRef = React.useRef<HTMLDivElement | null>(null);\n const viewportRef = React.useRef<HTMLElement | null>(null);\n const contentRef = React.useRef<HTMLDivElement | null>(null);\n const lastScrollStateRef = React.useRef<AgentChatShellScrollState | null>(null);\n const [measuredOverlayHeight, setMeasuredOverlayHeight] = React.useState(\n defaultComposerOverlayHeight\n );\n const olderPageRequestRef = React.useRef(false);\n const items = React.useMemo(\n () => outlineItems || buildAgentChatOutlineItems(messages),\n [messages, outlineItems]\n );\n\n const updateScrollState = React.useCallback(() => {\n const viewport = viewportRef.current;\n if (!viewport || !onScrollStateChange) return;\n const next = getAgentChatShellScrollState(viewport);\n const previous = lastScrollStateRef.current;\n if (\n previous &&\n previous.canScroll === next.canScroll &&\n previous.isScrolled === next.isScrolled\n ) {\n return;\n }\n lastScrollStateRef.current = next;\n onScrollStateChange(next);\n }, [onScrollStateChange]);\n\n React.useEffect(() => {\n const overlay = overlayRef.current;\n if (!overlay || hideComposer) return;\n const updateHeight = () => {\n setMeasuredOverlayHeight(Math.ceil(overlay.getBoundingClientRect().height));\n };\n updateHeight();\n const observer = new ResizeObserver(updateHeight);\n observer.observe(overlay);\n return () => observer.disconnect();\n }, [hideComposer]);\n\n React.useEffect(() => {\n if (!onScrollStateChange) return;\n updateScrollState();\n const viewport = viewportRef.current;\n const content = contentRef.current;\n if (!viewport || typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(updateScrollState);\n observer.observe(viewport);\n if (content) observer.observe(content);\n return () => observer.disconnect();\n }, [messages, onScrollStateChange, updateScrollState]);\n\n const handleScroll = React.useCallback(\n (event: React.UIEvent<HTMLDivElement>) => {\n updateScrollState();\n if (\n !onLoadOlder ||\n isLoadingOlder ||\n olderPageRequestRef.current ||\n event.currentTarget.scrollTop > 48\n ) {\n return;\n }\n olderPageRequestRef.current = true;\n void Promise.resolve(onLoadOlder()).finally(() => {\n olderPageRequestRef.current = false;\n });\n },\n [isLoadingOlder, onLoadOlder, updateScrollState]\n );\n\n const bottomPadding = hideComposer\n ? 32\n : (composerOverlayHeight ?? measuredOverlayHeight) + 72;\n const isEmptyState = messages.length === 0;\n\n if (isEmptyState) {\n return (\n <div className={cn(\"relative flex h-full min-h-0 w-full flex-col overflow-visible px-4\", className)} dir={dir}>\n {renderEmptyState ? (\n renderEmptyState({ composer: hideComposer ? undefined : composer, title: emptyTitle })\n ) : (\n <div className=\"relative z-10 flex h-full flex-1 flex-col justify-center p-0 pt-13\">\n <div className=\"flex w-full flex-col items-center pb-34 text-center animate-in fade-in slide-in-from-bottom-4 duration-500\">\n <p\n className={cn(\n \"pb-6 text-3xl font-semibold transition-transform duration-200\",\n emptyInputAttachmentCount > 0 && \"-translate-y-12\"\n )}\n >\n {emptyTitle}\n </p>\n {!hideComposer && composer ? (\n <div className=\"mx-auto w-full max-w-3xl px-4\">{composer}</div>\n ) : null}\n </div>\n </div>\n )}\n </div>\n );\n }\n\n return (\n <div className={cn(\"relative flex h-full min-h-0 w-full flex-col\", className)} dir={dir}>\n <LatestThreadScroller.Provider>\n <LatestThreadScroller.Root>\n <LatestThreadScroller.Viewport\n onScroll={handleScroll}\n onViewportChange={(node) => {\n viewportRef.current = node;\n updateScrollState();\n }}\n >\n <LatestThreadScroller.Content\n ref={contentRef}\n className={cn(\n \"mx-auto flex min-h-full w-full max-w-3xl flex-col gap-8 px-4 pt-12\",\n contentClassName\n )}\n style={{ paddingBottom: bottomPadding }}\n >\n {isLoadingOlder ? renderOlderLoader?.() : null}\n {messages.map((message, index) => (\n <LatestThreadScroller.Item\n key={message.id}\n messageId={message.id}\n scrollAnchor={message.role === \"user\"}\n >\n {renderMessage(message, index)}\n </LatestThreadScroller.Item>\n ))}\n </LatestThreadScroller.Content>\n </LatestThreadScroller.Viewport>\n <LatestThreadScroller.Outline\n dir={dir}\n items={items}\n side={outlineSide}\n />\n </LatestThreadScroller.Root>\n\n {!hideComposer && composer ? (\n <div\n ref={overlayRef}\n className={cn(\n \"pointer-events-none absolute inset-x-0 bottom-0 z-20 overflow-visible px-4 pb-4 pt-10\",\n composerOverlayClassName\n )}\n style={{\n background:\n \"linear-gradient(to bottom, transparent 0%, color-mix(in oklch, var(--chat-background, var(--background)) 85%, transparent) 45%, var(--chat-background, var(--background)) 65%, var(--chat-background, var(--background)) 100%)\",\n }}\n >\n <div className=\"pointer-events-auto absolute inset-x-0 top-0 flex -translate-y-full justify-center pb-3\">\n <LatestThreadScroller.Button />\n </div>\n <div className=\"pointer-events-auto mx-auto w-full max-w-3xl px-4\">\n {composer}\n </div>\n </div>\n ) : null}\n </LatestThreadScroller.Provider>\n </div>\n );\n}\n","import * as React from \"react\";\nimport {\n MessageScroller,\n useMessageScroller,\n useMessageScrollerVisibility,\n} from \"@shadcn/react/message-scroller\";\n\nconst cx = (...values: Array<string | false | null | undefined>) =>\n values.filter(Boolean).join(\" \");\n\ntype MessageScrollerProviderProps = React.ComponentProps<\n typeof MessageScroller.Provider\n>;\ntype MessageScrollerRootProps = React.ComponentProps<typeof MessageScroller.Root>;\ntype MessageScrollerViewportProps = React.ComponentProps<\n typeof MessageScroller.Viewport\n>;\ntype MessageScrollerContentProps = React.ComponentProps<\n typeof MessageScroller.Content\n>;\ntype MessageScrollerItemProps = React.ComponentProps<typeof MessageScroller.Item>;\ntype MessageScrollerButtonProps = React.ComponentProps<typeof MessageScroller.Button>;\n\ntype LatestThreadScrollerLayoutContextValue = {\n contentElement: HTMLElement | null;\n rootElement: HTMLElement | null;\n setContentElement: (node: HTMLElement | null) => void;\n setRootElement: (node: HTMLElement | null) => void;\n};\n\nconst LatestThreadScrollerLayoutContext =\n React.createContext<LatestThreadScrollerLayoutContextValue | null>(null);\n\nconst useLatestThreadScrollerLayout = () =>\n React.useContext(LatestThreadScrollerLayoutContext);\n\nexport type LatestThreadScrollerProviderProps = MessageScrollerProviderProps;\n\nexport function LatestThreadScrollerProvider({\n autoScroll = true,\n defaultScrollPosition = \"last-anchor\",\n scrollPreviousItemPeek = 64,\n ...props\n}: LatestThreadScrollerProviderProps) {\n return (\n <MessageScroller.Provider\n autoScroll={autoScroll}\n defaultScrollPosition={defaultScrollPosition}\n scrollPreviousItemPeek={scrollPreviousItemPeek}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerRootProps = MessageScrollerRootProps;\n\nexport function LatestThreadScrollerRoot({\n className,\n ref,\n ...props\n}: LatestThreadScrollerRootProps) {\n const [rootElement, setRootElement] = React.useState<HTMLElement | null>(null);\n const [contentElement, setContentElement] =\n React.useState<HTMLElement | null>(null);\n const layoutContext = React.useMemo<LatestThreadScrollerLayoutContextValue>(\n () => ({\n contentElement,\n rootElement,\n setContentElement,\n setRootElement,\n }),\n [contentElement, rootElement]\n );\n const setRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n setRootElement(node);\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref]\n );\n\n return (\n <LatestThreadScrollerLayoutContext.Provider value={layoutContext}>\n <MessageScroller.Root\n ref={setRef}\n className={cx(\n \"relative flex size-full min-h-0 flex-1 flex-col overflow-hidden\",\n className\n )}\n {...props}\n />\n </LatestThreadScrollerLayoutContext.Provider>\n );\n}\n\nexport type LatestThreadScrollerViewportProps =\n MessageScrollerViewportProps & {\n onViewportChange?: (node: HTMLElement | null) => void;\n };\n\nexport function LatestThreadScrollerViewport({\n className,\n onViewportChange,\n preserveScrollOnPrepend = true,\n ref,\n ...props\n}: LatestThreadScrollerViewportProps) {\n const setRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n onViewportChange?.(node);\n },\n [onViewportChange, ref]\n );\n\n return (\n <MessageScroller.Viewport\n ref={setRef}\n className={cx(\n \"size-full min-h-0 min-w-0 flex-1 overflow-y-auto overscroll-contain\",\n className\n )}\n preserveScrollOnPrepend={preserveScrollOnPrepend}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerContentProps = MessageScrollerContentProps;\n\nexport function LatestThreadScrollerContent({\n className,\n ref,\n ...props\n}: LatestThreadScrollerContentProps) {\n const layout = useLatestThreadScrollerLayout();\n const setRef = React.useCallback(\n (node: HTMLDivElement | null) => {\n layout?.setContentElement(node);\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n },\n [layout, ref]\n );\n\n return (\n <MessageScroller.Content\n ref={setRef}\n data-agents24-latest-thread-content=\"\"\n className={cx(\"flex h-max min-h-full flex-col gap-8 p-4\", className)}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerItemProps = Omit<\n MessageScrollerItemProps,\n \"messageId\"\n> & {\n messageId: string;\n};\n\nexport function LatestThreadScrollerItem({\n className,\n messageId,\n ...props\n}: LatestThreadScrollerItemProps) {\n return (\n <MessageScroller.Item\n className={cx(\n \"min-w-0 shrink-0 overflow-visible\",\n className\n )}\n messageId={messageId}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerButtonProps = Omit<\n MessageScrollerButtonProps,\n \"render\"\n> & {\n className?: string;\n render?: MessageScrollerButtonProps[\"render\"];\n};\n\nexport function LatestThreadScrollerButton({\n children,\n className,\n direction = \"end\",\n render,\n ...props\n}: LatestThreadScrollerButtonProps) {\n if (render) {\n return (\n <MessageScroller.Button\n direction={direction}\n render={render}\n {...props}\n />\n );\n }\n\n return (\n <MessageScroller.Button\n direction={direction}\n render={(buttonProps) => (\n <button\n {...(buttonProps as Record<string, unknown>)}\n aria-label={\n direction === \"end\"\n ? \"Scroll to latest message\"\n : \"Scroll to first message\"\n }\n className={cx(\n \"absolute bottom-4 left-1/2 z-50 flex size-9 -translate-x-1/2 items-center justify-center rounded-full border border-border bg-background text-foreground shadow-md transition-all duration-200 data-[active=false]:pointer-events-none data-[active=false]:translate-y-2 data-[active=false]:opacity-0 data-[active=true]:translate-y-0 data-[active=true]:opacity-100\",\n className\n )}\n type=\"button\"\n >\n {children ?? (direction === \"end\" ? \"↓\" : \"↑\")}\n </button>\n )}\n {...props}\n />\n );\n}\n\nexport type LatestThreadScrollerOutlineItem = {\n id: string;\n label: string;\n messageIds?: string[];\n responsePreview?: string;\n};\n\nexport type LatestThreadScrollerOutlineProps = {\n cardClassName?: string;\n className?: string;\n contentMaxWidth?: number;\n dir?: \"ltr\" | \"rtl\";\n items: LatestThreadScrollerOutlineItem[];\n minContainerWidthForRail?: number;\n minSideGutterForRail?: number;\n side?: \"left\" | \"right\";\n};\n\nexport function LatestThreadScrollerOutline({\n cardClassName,\n className,\n contentMaxWidth = 768,\n dir = \"ltr\",\n items,\n minContainerWidthForRail = 0,\n minSideGutterForRail = 48,\n side,\n}: LatestThreadScrollerOutlineProps) {\n const navRef = React.useRef<HTMLElement | null>(null);\n const layout = useLatestThreadScrollerLayout();\n const [hasSideRoom, setHasSideRoom] = React.useState(false);\n const [hoveredIndex, setHoveredIndex] = React.useState<number | null>(null);\n const { scrollToMessage } = useMessageScroller();\n const { currentAnchorId, visibleMessageIds } = useMessageScrollerVisibility();\n const visibleMessageIdSet = React.useMemo(\n () => new Set(visibleMessageIds),\n [visibleMessageIds]\n );\n const focusIndex = hoveredIndex ?? -1;\n const railSide = side ?? (dir === \"rtl\" ? \"right\" : \"left\");\n\n React.useEffect(() => {\n const root = layout?.rootElement ?? navRef.current?.parentElement;\n if (!root) return;\n\n const updateSideRoom = () => {\n const rootRect = root.getBoundingClientRect();\n const rootWidth = rootRect.width;\n const content = layout?.contentElement;\n const sideGutter = content\n ? Math.max(\n 0,\n railSide === \"left\"\n ? content.getBoundingClientRect().left - rootRect.left\n : rootRect.right - content.getBoundingClientRect().right\n )\n : Math.max(0, (rootWidth - contentMaxWidth) / 2);\n const nextHasSideRoom =\n rootWidth >= minContainerWidthForRail &&\n sideGutter >= minSideGutterForRail;\n setHasSideRoom((current) =>\n current === nextHasSideRoom ? current : nextHasSideRoom\n );\n };\n\n updateSideRoom();\n if (typeof ResizeObserver === \"undefined\") return;\n const resizeObserver = new ResizeObserver(updateSideRoom);\n resizeObserver.observe(root);\n const content = layout?.contentElement;\n if (content) {\n resizeObserver.observe(content);\n }\n return () => resizeObserver.disconnect();\n }, [\n contentMaxWidth,\n layout?.contentElement,\n layout?.rootElement,\n minContainerWidthForRail,\n minSideGutterForRail,\n railSide,\n ]);\n\n if (items.length < 2) {\n return null;\n }\n\n return (\n <nav\n ref={navRef}\n aria-label=\"Transcript outline\"\n className={cx(\n \"pointer-events-none absolute top-[46%] z-10 max-h-[min(18rem,calc(100%-10rem))] w-16 -translate-y-1/2 overflow-visible\",\n hasSideRoom ? \"hidden md:block\" : \"hidden\",\n railSide === \"left\" ? \"left-1\" : \"right-1\",\n className\n )}\n dir={dir}\n >\n <div className=\"pointer-events-auto flex flex-col gap-0 py-1\">\n {items.map((item, index) => {\n const itemMessageIds =\n item.messageIds && item.messageIds.length > 0\n ? item.messageIds\n : [item.id];\n const active = itemMessageIds.some(\n (messageId) =>\n visibleMessageIdSet.has(messageId) || messageId === currentAnchorId\n );\n const distance =\n focusIndex >= 0 ? Math.abs(index - focusIndex) : Number.POSITIVE_INFINITY;\n const isFocused = distance === 0;\n const isNear = distance === 1;\n const isNextNear = distance === 2;\n const barWidth = isFocused\n ? 50\n : isNear\n ? 36\n : isNextNear\n ? 23\n : 10;\n const barOpacity = isFocused ? 1 : isNear ? 0.78 : isNextNear ? 0.58 : 0.36;\n const fallbackLabel = `Turn ${index + 1}`;\n const previewLabel =\n item.label && item.label !== fallbackLabel ? item.label : \"\";\n const responsePreview = (item.responsePreview || \"\").trim();\n\n return (\n <button\n key={item.id}\n type=\"button\"\n data-active={active}\n dir=\"ltr\"\n className={cx(\n \"group relative flex h-2 w-16 items-center rounded-sm outline-none\",\n railSide === \"left\" ? \"justify-start\" : \"justify-end\"\n )}\n aria-label={`Jump to ${item.label || fallbackLabel}`}\n onBlur={() => setHoveredIndex(null)}\n onFocus={() => setHoveredIndex(index)}\n onMouseEnter={() => setHoveredIndex(index)}\n onMouseLeave={() => setHoveredIndex(null)}\n onClick={() =>\n scrollToMessage(item.id, {\n align: \"start\",\n behavior: \"smooth\",\n })\n }\n >\n <span\n className=\"h-0.5 rounded-full bg-muted-foreground/55 transition-[width,background-color,opacity] duration-150 ease-out group-hover:bg-foreground group-focus-visible:bg-foreground group-data-[active=true]:bg-foreground\"\n style={{\n opacity: barOpacity,\n width: barWidth,\n }}\n />\n {previewLabel ? (\n <span\n dir={dir}\n className={cx(\n \"pointer-events-none absolute top-1/2 z-20 max-h-32 w-64 -translate-y-1/2 overflow-hidden rounded-lg border border-border/80 bg-background p-3 text-start opacity-0 shadow-lg transition-all duration-200 group-hover:pointer-events-auto group-hover:opacity-100 group-focus-visible:pointer-events-auto group-focus-visible:opacity-100\",\n railSide === \"left\"\n ? \"left-full ml-2 -translate-x-1 group-hover:translate-x-0 group-focus-visible:translate-x-0\"\n : \"right-full mr-2 translate-x-1 group-hover:translate-x-0 group-focus-visible:translate-x-0\",\n cardClassName\n )}\n >\n <span\n className=\"block overflow-hidden text-sm leading-5 text-foreground\"\n style={{\n display: \"-webkit-box\",\n WebkitBoxOrient: \"vertical\",\n WebkitLineClamp: responsePreview ? 2 : 4,\n }}\n >\n {previewLabel}\n </span>\n {responsePreview ? (\n <span\n className=\"mt-1 block overflow-hidden text-sm leading-5 text-muted-foreground\"\n style={{\n display: \"-webkit-box\",\n WebkitBoxOrient: \"vertical\",\n WebkitLineClamp: 2,\n }}\n >\n {responsePreview}\n </span>\n ) : null}\n </span>\n ) : null}\n </button>\n );\n })}\n </div>\n </nav>\n );\n}\n\nexport const LatestThreadScroller = {\n Provider: LatestThreadScrollerProvider,\n Root: LatestThreadScrollerRoot,\n Viewport: LatestThreadScrollerViewport,\n Content: LatestThreadScrollerContent,\n Item: LatestThreadScrollerItem,\n Button: LatestThreadScrollerButton,\n Outline: LatestThreadScrollerOutline,\n};\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...values: ClassValue[]) {\n return twMerge(clsx(values));\n}\n"],"mappings":"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","names":["React","content","import_jsx_runtime"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  LatestThreadScroller
3
- } from "../chunk-E3TJ3I6G.js";
3
+ } from "../chunk-FFO6KEB4.js";
4
4
  import {
5
5
  cn
6
6
  } from "../chunk-UU7OXHL3.js";
package/dist/types.d.ts CHANGED
@@ -80,13 +80,30 @@ export type ChatUiBlocksPart = {
80
80
  errorText?: string | null;
81
81
  raw: Record<string, unknown>;
82
82
  };
83
+ export type ChatHitlKind = "tool_review" | "mcp_auth" | "user_approval" | "app_data_permission";
84
+ export type ChatHitlAction = "approve" | "reject" | "connect" | "skip";
85
+ export type ChatHitlStatus = "pending" | "resolved" | "expired" | "cancelled" | "invalidated";
86
+ export type ChatHitlResolution = {
87
+ action?: ChatHitlAction | null;
88
+ outcome?: string | null;
89
+ reason?: string | null;
90
+ resolvedAt?: string | null;
91
+ resolver?: {
92
+ principalType?: string | null;
93
+ principalId?: string | null;
94
+ } | null;
95
+ };
83
96
  export type ChatHitlPart = {
84
97
  id: string;
85
98
  type: "hitl";
86
99
  kind: "hitl";
87
- hitl: Record<string, unknown>;
88
- interruptId?: string | null;
89
- hitlKind?: string | null;
100
+ interruptId: string;
101
+ hitlKind: ChatHitlKind;
102
+ message: string;
103
+ allowedActions: ChatHitlAction[];
104
+ status: ChatHitlStatus;
105
+ presentation: Record<string, unknown>;
106
+ resolution?: ChatHitlResolution | null;
90
107
  raw: Record<string, unknown>;
91
108
  };
92
109
  export type ChatErrorPart = {
@@ -225,7 +242,7 @@ export type ChatSubmitInput = {
225
242
  text: string;
226
243
  threadId?: string | null;
227
244
  files?: ChatAttachment[];
228
- signal?: AbortSignal;
245
+ signal: AbortSignal;
229
246
  state?: Record<string, unknown>;
230
247
  [key: string]: unknown;
231
248
  };
@@ -235,21 +252,21 @@ export type ChatSubmitMessage = {
235
252
  state?: Record<string, unknown>;
236
253
  [key: string]: unknown;
237
254
  };
238
- export type ChatHitlDecisionType = "approve" | "edit" | "reject" | "respond" | "connect" | string;
239
- export type ChatHitlResumeDecision = {
240
- type: ChatHitlDecisionType;
241
- action_id?: string | null;
242
- message?: string;
243
- response?: string;
244
- edited_action?: Record<string, unknown>;
245
- [key: string]: unknown;
246
- };
247
255
  export type ChatHitlResumeInput = {
248
256
  runId: string;
249
257
  interruptId: string;
250
- decisions: ChatHitlResumeDecision[];
258
+ action: ChatHitlAction;
259
+ comment?: string;
251
260
  client?: Record<string, unknown>;
252
261
  };
262
+ export type ChatHitlResumeResult = {
263
+ run_id: string;
264
+ thread_id?: string | null;
265
+ interrupt_id: string;
266
+ run_status: string;
267
+ resolution_status: string;
268
+ idempotent: boolean;
269
+ };
253
270
  export type ChatMcpAuthStartInput = {
254
271
  runId: string;
255
272
  interruptId?: string | null;
@@ -278,7 +295,7 @@ export type ChatTransport = {
278
295
  streamMessage: (input: ChatSubmitInput, onEvent: (event: ChatRuntimeEvent) => void | Promise<void>) => Promise<ChatStreamResult>;
279
296
  attachRun: (input: {
280
297
  runId: string;
281
- signal?: AbortSignal;
298
+ signal: AbortSignal;
282
299
  }, onEvent: (event: ChatRuntimeEvent) => void | Promise<void>) => Promise<ChatStreamResult>;
283
300
  cancelRun: (input: {
284
301
  runId: string;
@@ -296,15 +313,11 @@ export type ChatTransport = {
296
313
  file: File;
297
314
  signal?: AbortSignal;
298
315
  }) => Promise<ChatAttachment>;
299
- resumeHitl?: (input: ChatHitlResumeInput) => Promise<{
300
- run_id?: string;
301
- status?: string;
302
- thread_id?: string | null;
303
- }>;
316
+ resumeHitl?: (input: ChatHitlResumeInput) => Promise<ChatHitlResumeResult>;
304
317
  startMcpAuth?: (input: ChatMcpAuthStartInput) => Promise<ChatMcpAuthStartResult>;
305
318
  subscribeThreadEvents?: (input: {
306
319
  cursor?: number | null;
307
- signal?: AbortSignal;
320
+ signal: AbortSignal;
308
321
  }, onEvent: (event: ChatThreadSummaryEvent) => void | Promise<void>) => Promise<void>;
309
322
  };
310
323
  export type ChatStreamResult = {
@@ -346,8 +359,13 @@ export type ChatController = {
346
359
  copiedMessageId: string | null;
347
360
  lastThinkingDurationMs: number | null;
348
361
  activeRunId: string | null;
362
+ pendingHitl: ChatHitlPart | null;
363
+ isResolvingHitl: boolean;
349
364
  handleSubmit: (message: ChatSubmitMessage) => Promise<void>;
350
365
  attachRun: (runId: string, threadId?: string | null) => Promise<void>;
366
+ resumeHitl: (input: Omit<ChatHitlResumeInput, "runId"> & {
367
+ runId?: string;
368
+ }) => Promise<ChatHitlResumeResult>;
351
369
  handleStop: () => void;
352
370
  handleCopy: (content: string, messageId: string) => void;
353
371
  handleLike: (msg: ChatMessage) => Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
- import type { ChatHitlPart, ChatMessage, ChatPart } from "../types";
3
- import { type McpConnectRequiredStatus } from "./mcp-connect-required-card";
2
+ import type { ChatHitlAction, ChatHitlPart, ChatMessage, ChatPart } from "../types";
3
+ import type { McpConnectRequiredStatus } from "./mcp-connect-required-card";
4
4
  export type AgentChatPartActionState = {
5
5
  status?: McpConnectRequiredStatus | string;
6
6
  error?: string | null;
@@ -9,7 +9,7 @@ export type AgentResponseTimelineProps = {
9
9
  getHitlActionState?: (part: ChatHitlPart) => AgentChatPartActionState | undefined;
10
10
  isLoading?: boolean;
11
11
  message: ChatMessage;
12
- onHitlAction?: (part: ChatHitlPart, decision: string) => void;
12
+ onHitlAction?: (part: ChatHitlPart, action: ChatHitlAction, comment?: string) => void;
13
13
  renderPart?: (part: ChatPart, message: ChatMessage) => React.ReactNode;
14
14
  };
15
15
  declare function DefaultPartRow({ activeToolId, getHitlActionState, isLoading, message, onHitlAction, part, }: {