/* Copyright (C) 2023-2026 QuantumNous This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . For commercial licensing, please contact support@quantumnous.com */ 'use client' import type { ToolUIPart } from 'ai' import { CheckCircleIcon, ChevronDownIcon, CircleIcon, ClockIcon, WrenchIcon, XCircleIcon, } from 'lucide-react' import { type ComponentProps, isValidElement, type ReactNode } from 'react' import { useTranslation } from 'react-i18next' import { Badge } from '@/components/ui/badge' import { Collapsible, CollapsibleContent, CollapsibleTrigger, } from '@/components/ui/collapsible' import { cn } from '@/lib/utils' import { CodeBlock } from './code-block' // Workaround for missing types in 'ai' package type ExtendedToolState = | ToolUIPart['state'] | 'approval-requested' | 'approval-responded' | 'output-denied' export type ToolProps = ComponentProps export const Tool = ({ className, ...props }: ToolProps) => ( ) export type ToolHeaderProps = { title?: string type: ToolUIPart['type'] state: ExtendedToolState className?: string } const getStatusBadge = (status: ExtendedToolState) => { const labels: Record = { 'input-streaming': 'Pending', 'input-available': 'Running', 'approval-requested': 'Awaiting Approval', 'approval-responded': 'Responded', 'output-available': 'Completed', 'output-error': 'Error', 'output-denied': 'Denied', } const icons: Record = { 'input-streaming': , 'input-available': , 'approval-requested': , 'approval-responded': , 'output-available': , 'output-error': , 'output-denied': , } return ( {icons[status]} {labels[status]} ) } export const ToolHeader = ({ className, title, type, state, ...props }: ToolHeaderProps) => (
{title ?? type.split('-').slice(1).join('-')} {getStatusBadge(state)}
) export type ToolContentProps = ComponentProps export const ToolContent = ({ className, ...props }: ToolContentProps) => ( ) export type ToolInputProps = ComponentProps<'div'> & { input: ToolUIPart['input'] } export const ToolInput = ({ className, input, ...props }: ToolInputProps) => { const { t } = useTranslation() return (

{t('Parameters')}

) } export type ToolOutputProps = ComponentProps<'div'> & { output: ToolUIPart['output'] errorText: ToolUIPart['errorText'] } export const ToolOutput = ({ className, output, errorText, ...props }: ToolOutputProps) => { if (!(output || errorText)) { return null } let Output =
{output as ReactNode}
if (typeof output === 'object' && !isValidElement(output)) { Output = ( ) } else if (typeof output === 'string') { Output = } return (

{errorText ? 'Error' : 'Result'}

{errorText &&
{errorText}
} {Output}
) }