import { c as _c } from "react/compiler-runtime"; import type { ToolResultBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'; import React from 'react'; import { CtrlOToExpand } from '../../components/CtrlOToExpand.js'; import { FallbackToolUseErrorMessage } from '../../components/FallbackToolUseErrorMessage.js'; import { MessageResponse } from '../../components/MessageResponse.js'; import { Box, Text } from '../../ink.js'; import { getDisplayPath } from '../../utils/file.js'; import { extractTag } from '../../utils/messages.js'; import type { Input, Output } from './LSPTool.js'; import { getSymbolAtPosition } from './symbolContext.js'; // 操作特定标签的查找映射表 const OPERATION_LABELS: Record = { goToDefinition: { singular: 'definition', plural: 'definitions' }, findReferences: { singular: 'reference', plural: 'references' }, documentSymbol: { singular: 'symbol', plural: 'symbols' }, workspaceSymbol: { singular: 'symbol', plural: 'symbols' }, hover: { singular: 'hover info', plural: 'hover info', special: 'available' }, goToImplementation: { singular: 'implementation', plural: 'implementations' }, prepareCallHierarchy: { singular: 'call item', plural: 'call items' }, incomingCalls: { singular: 'caller', plural: 'callers' }, outgoingCalls: { singular: 'callee', plural: 'callees' } }; /** * 用于 LSP 结果摘要的可复用组件,支持折叠/展开视图 */ function LSPResultSummary(t0) { const $ = _c(24); const { operation, resultCount, fileCount, content, verbose } = t0; let t1; if ($[0] !== operation) { t1 = OPERATION_LABELS[operation] || { singular: "result", plural: "results" }; $[0] = operation; $[1] = t1; } else { t1 = $[1]; } const labelConfig = t1; const countLabel = resultCount === 1 ? labelConfig.singular : labelConfig.plural; let t2; if ($[2] !== countLabel || $[3] !== labelConfig.special || $[4] !== operation || $[5] !== resultCount) { t2 = operation === "hover" && resultCount > 0 && labelConfig.special ? Hover info {labelConfig.special} : Found {resultCount} {countLabel}; $[2] = countLabel; $[3] = labelConfig.special; $[4] = operation; $[5] = resultCount; $[6] = t2; } else { t2 = $[6]; } const primaryText = t2; let t3; if ($[7] !== fileCount) { t3 = fileCount > 1 ? {" "}across {fileCount} files : null; $[7] = fileCount; $[8] = t3; } else { t3 = $[8]; } const secondaryText = t3; if (verbose) { let t4; if ($[9] === Symbol.for("react.memo_cache_sentinel")) { t4 = ; $[9] = t4; } else { t4 = $[9]; } let t5; if ($[10] !== primaryText || $[11] !== secondaryText) { t5 = {t4}{primaryText}{secondaryText}; $[10] = primaryText; $[11] = secondaryText; $[12] = t5; } else { t5 = $[12]; } let t6; if ($[13] !== content) { t6 = {content}; $[13] = content; $[14] = t6; } else { t6 = $[14]; } let t7; if ($[15] !== t5 || $[16] !== t6) { t7 = {t5}{t6}; $[15] = t5; $[16] = t6; $[17] = t7; } else { t7 = $[17]; } return t7; } let t4; if ($[18] !== resultCount) { t4 = resultCount > 0 && ; $[18] = resultCount; $[19] = t4; } else { t4 = $[19]; } let t5; if ($[20] !== primaryText || $[21] !== secondaryText || $[22] !== t4) { t5 = {primaryText}{secondaryText} {t4}; $[20] = primaryText; $[21] = secondaryText; $[22] = t4; $[23] = t5; } else { t5 = $[23]; } return t5; } export function userFacingName(): string { return 'LSP'; } export function renderToolUseMessage(input: Partial, { verbose }: { verbose: boolean; }): React.ReactNode { if (!input.operation) { return null; } const parts: string[] = []; // 对于基于位置的操作(goToDefinition、findReferences、hover、goToImplementation), // 显示该位置的符号以获得更好的上下文 if ((input.operation === 'goToDefinition' || input.operation === 'findReferences' || input.operation === 'hover' || input.operation === 'goToImplementation') && input.filePath && input.line !== undefined && input.character !== undefined) { // 从 1-based(用户输入)转换为 0-based(内部文件读取) const symbol = getSymbolAtPosition(input.filePath, input.line - 1, input.character - 1); const displayPath = verbose ? input.filePath : getDisplayPath(input.filePath); if (symbol) { parts.push(`operation: "${input.operation}"`); parts.push(`symbol: "${symbol}"`); parts.push(`in: "${displayPath}"`); } else { parts.push(`operation: "${input.operation}"`); parts.push(`file: "${displayPath}"`); parts.push(`position: ${input.line}:${input.character}`); } return parts.join(', '); } // 对于其他操作(documentSymbol、workspaceSymbol), // 显示操作和文件,但不显示位置详情 parts.push(`operation: "${input.operation}"`); if (input.filePath) { const displayPath = verbose ? input.filePath : getDisplayPath(input.filePath); parts.push(`file: "${displayPath}"`); } return parts.join(', '); } export function renderToolUseErrorMessage(result: ToolResultBlockParam['content'], { verbose }: { verbose: boolean; }): React.ReactNode { if (!verbose && typeof result === 'string' && extractTag(result, 'tool_use_error')) { return LSP operation failed ; } return ; } export function renderToolResultMessage(output: Output, _progressMessages: unknown[], { verbose }: { verbose: boolean; }): React.ReactNode { // 如果有计数信息,使用折叠/展开视图 if (output.resultCount !== undefined && output.fileCount !== undefined) { return ; } // 用于计数不可用时的错误情况的后备方案 //(例如 LSP 服务器初始化失败、请求错误) return {output.result} ; }