/**
* @license
* Copyright 2025 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*
* Search tool call component - specialized for search operations
*/
import type { FC } from 'react';
import {
safeTitle,
groupContent,
mapToolStatusToContainerStatus,
ToolCallContainer,
} from './shared/index.js';
import type { BaseToolCallProps, ContainerStatus } from './shared/index.js';
import { FileLink } from '../layout/FileLink.js';
/**
* Row component for search card layout
*/
const SearchRow: FC<{ label: string; children: React.ReactNode }> = ({
label,
children,
}) => (
);
/**
* Card content wrapper for search results
*/
const SearchCardContent: FC<{ children: React.ReactNode }> = ({ children }) => (
);
/**
* Local locations list component
*/
const LocationsListLocal: FC<{
locations: Array<{ path: string; line?: number | null }>;
}> = ({ locations }) => (
{locations.map((loc, idx) => (
))}
);
/**
* Map tool call kind to appropriate display name
*/
const getDisplayLabel = (kind: string): string => {
const normalizedKind = kind.toLowerCase();
if (normalizedKind === 'grep' || normalizedKind === 'grep_search') {
return 'Grep';
} else if (normalizedKind === 'glob') {
return 'Glob';
} else if (normalizedKind === 'web_search') {
return 'WebSearch';
} else {
return 'Search';
}
};
/**
* Specialized component for Search tool calls
* Optimized for displaying search operations and results
*/
export const SearchToolCall: FC = ({
toolCall,
isFirst,
isLast,
}) => {
const { kind, title, content, locations } = toolCall;
const queryText = safeTitle(title);
const displayLabel = getDisplayLabel(kind);
const containerStatus: ContainerStatus = mapToolStatusToContainerStatus(
toolCall.status,
);
// Group content by type
const { errors, textOutputs } = groupContent(content);
// Error case: show search query + error in card layout
if (errors.length > 0) {
return (
{queryText}
{errors.join('\n')}
);
}
// Success case with results: show search query + file list
if (locations && locations.length > 0) {
// Multiple results use card layout
if (locations.length > 1) {
return (
{queryText}
);
}
// Single result - compact format
return (
);
}
// Show content text if available
if (textOutputs.length > 0) {
return (
{textOutputs.map((text: string, index: number) => (
⎿
{text}
))}
);
}
// No results - show query only
if (queryText) {
return (
);
}
return null;
};