import { useState, type FunctionComponent } from 'react'; import { ActionList, ActionListProps, ActionListGroup, ActionListGroupProps, ActionListItem, ActionListItemProps, Button, ButtonProps, Card, CardProps, CardBody, CardBodyProps, CardFooter, CardFooterProps, ExpandableSection, ExpandableSectionProps, Spinner, SpinnerProps } from '@patternfly/react-core'; import MarkdownContent from '../MarkdownContent'; import type { MarkdownContentProps } from '../MarkdownContent'; export interface ToolCallProps { /** Title text for the tool call. */ titleText: string; /** Loading text for the tool call. */ loadingText?: string; /** Flag indicating whether the tool call is loading or not. */ isLoading?: boolean; /** Additional props for the spinner that is rendered when isLoading is true. */ spinnerProps?: SpinnerProps; /** Content to render within an expandable section. */ expandableContent?: React.ReactNode; /** Flag indicating whether the expandable content is expanded by default. */ isDefaultExpanded?: boolean; /** Text content for the "run" action button. */ runButtonText?: string; /** Additional props for the "run" action button. */ runButtonProps?: ButtonProps; /** Additional props for the "run" action list item. */ runActionItemProps?: ActionListItemProps; /** Text content for the "cancel" action button. */ cancelButtonText?: string; /** Additional props for the "cancel" action button. */ cancelButtonProps?: ButtonProps; /** Additional props for the "cancel" action list item. */ cancelActionItemProps?: ActionListItemProps; /** Custom actions to render, typically a "cancel" and "run" action. This will override the default actions. */ actions?: React.ReactNode[]; /** Additional props for the action list */ actionListProps?: ActionListProps; /** Additional props for the action list group. */ actionListGroupProps?: ActionListGroupProps; /** Additional props for all action list items. */ actionListItemProps?: ActionListItemProps; /** Additional props for the card. */ cardProps?: CardProps; /** Additional props for the card body that contains the main tool call content. */ cardBodyProps?: CardBodyProps; /** Additional props for the card footer that contains the tool call actions. */ cardFooterProps?: CardFooterProps; /** Additional props for the expandable section when expandableContent is passed. */ expandableSectionProps?: Omit; /** Whether to enable markdown rendering for titleText. When true, titleText will be parsed as markdown. */ isTitleMarkdown?: boolean; /** Whether to enable markdown rendering for expandableContent. When true and expandableContent is a string, it will be parsed as markdown. */ isExpandableContentMarkdown?: boolean; /** Props passed to MarkdownContent component when markdown is enabled */ markdownContentProps?: Omit; /** Whether to retain styles in the MarkdownContent component. Defaults to false. */ shouldRetainStyles?: boolean; } export const ToolCall: FunctionComponent = ({ titleText, loadingText, isLoading, expandableContent, isDefaultExpanded = false, runButtonText = 'Run tool', runButtonProps, runActionItemProps, cancelButtonText = 'Cancel', cancelButtonProps, cancelActionItemProps, actions, actionListProps, actionListGroupProps, actionListItemProps, cardProps, cardBodyProps, cardFooterProps, expandableSectionProps, spinnerProps, isTitleMarkdown, isExpandableContentMarkdown, markdownContentProps, shouldRetainStyles = false }: ToolCallProps) => { const [isExpanded, setIsExpanded] = useState(isDefaultExpanded); const onToggle = (_event: React.MouseEvent, isExpanded: boolean) => { setIsExpanded(isExpanded); }; const renderTitle = () => { if (isTitleMarkdown) { return ; } return titleText; }; const titleContent = ( {isLoading ? ( <> {' '} {{loadingText}} ) : ( {renderTitle()} )} ); const renderExpandableContent = () => { if (isExpandableContentMarkdown && typeof expandableContent === 'string') { return ( ); } return expandableContent; }; const defaultActions = ( <> ); const customActions = actions && actions.map((action, index) => ( {action} )); return ( {expandableContent && !isLoading ? ( {renderExpandableContent()} ) : ( titleContent )} {!isLoading && ( {customActions || defaultActions} )} ); }; export default ToolCall;