diff --git a/src/renderer/src/assets/styles/ant.css b/src/renderer/src/assets/styles/ant.css index 30005ff73..7d651a6a6 100644 --- a/src/renderer/src/assets/styles/ant.css +++ b/src/renderer/src/assets/styles/ant.css @@ -215,6 +215,10 @@ border-top: none !important; } +.ant-collapse-header-text { + overflow-x: hidden; +} + .ant-slider .ant-slider-handle::after { box-shadow: 0 1px 4px 0px rgb(128 128 128 / 50%) !important; } diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index 008f1721e..782340e01 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -280,6 +280,7 @@ "denied": "Tool request was denied.", "timeout": "Tool request timed out before receiving approval." }, + "toolPendingFallback": "Tool", "waiting": "Waiting for tool permission decision..." }, "type": { diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 60b478273..c1874f7fb 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -280,6 +280,7 @@ "denied": "工具请求已被拒绝。", "timeout": "工具请求在收到批准前超时。" }, + "toolPendingFallback": "工具", "waiting": "等待工具权限决定..." }, "type": { diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 8068b666f..db81e3000 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -280,6 +280,7 @@ "denied": "工具請求已被拒絕。", "timeout": "工具請求在收到核准前逾時。" }, + "toolPendingFallback": "工具", "waiting": "等待工具權限決定..." }, "type": { diff --git a/src/renderer/src/i18n/translate/de-de.json b/src/renderer/src/i18n/translate/de-de.json index 61446bc79..e7314482a 100644 --- a/src/renderer/src/i18n/translate/de-de.json +++ b/src/renderer/src/i18n/translate/de-de.json @@ -280,6 +280,7 @@ "denied": "Tool-Anfrage wurde abgelehnt.", "timeout": "Tool-Anfrage ist abgelaufen, bevor eine Genehmigung eingegangen ist." }, + "toolPendingFallback": "Werkzeug", "waiting": "Warten auf Entscheidung über Tool-Berechtigung..." }, "type": { diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json index 39830d9c5..bc825ec68 100644 --- a/src/renderer/src/i18n/translate/el-gr.json +++ b/src/renderer/src/i18n/translate/el-gr.json @@ -280,6 +280,7 @@ "denied": "Το αίτημα για εργαλείο απορρίφθηκε.", "timeout": "Το αίτημα για το εργαλείο έληξε πριν λάβει έγκριση." }, + "toolPendingFallback": "Εργαλείο", "waiting": "Αναμονή για απόφαση άδειας εργαλείου..." }, "type": { diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json index 857382452..2da83ad22 100644 --- a/src/renderer/src/i18n/translate/es-es.json +++ b/src/renderer/src/i18n/translate/es-es.json @@ -280,6 +280,7 @@ "denied": "La solicitud de herramienta fue denegada.", "timeout": "La solicitud de herramienta expiró antes de recibir la aprobación." }, + "toolPendingFallback": "Herramienta", "waiting": "Esperando la decisión de permiso de la herramienta..." }, "type": { diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json index 16b2da759..3f3e9108c 100644 --- a/src/renderer/src/i18n/translate/fr-fr.json +++ b/src/renderer/src/i18n/translate/fr-fr.json @@ -280,6 +280,7 @@ "denied": "La demande d'outil a été refusée.", "timeout": "La demande d'outil a expiré avant d'obtenir l'approbation." }, + "toolPendingFallback": "Outil", "waiting": "En attente de la décision d'autorisation de l'outil..." }, "type": { diff --git a/src/renderer/src/i18n/translate/ja-jp.json b/src/renderer/src/i18n/translate/ja-jp.json index 03a077a7b..e2591fb20 100644 --- a/src/renderer/src/i18n/translate/ja-jp.json +++ b/src/renderer/src/i18n/translate/ja-jp.json @@ -280,6 +280,7 @@ "denied": "ツールリクエストは拒否されました。", "timeout": "ツールリクエストは承認を受ける前にタイムアウトしました。" }, + "toolPendingFallback": "ツール", "waiting": "ツールの許可決定を待っています..." }, "type": { diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json index e8704d318..cae6ebd38 100644 --- a/src/renderer/src/i18n/translate/pt-pt.json +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -280,6 +280,7 @@ "denied": "Solicitação de ferramenta foi negada.", "timeout": "A solicitação da ferramenta expirou antes de receber aprovação." }, + "toolPendingFallback": "Ferramenta", "waiting": "Aguardando decisão de permissão da ferramenta..." }, "type": { diff --git a/src/renderer/src/i18n/translate/ru-ru.json b/src/renderer/src/i18n/translate/ru-ru.json index 1114ae954..fe5ebbcb2 100644 --- a/src/renderer/src/i18n/translate/ru-ru.json +++ b/src/renderer/src/i18n/translate/ru-ru.json @@ -280,6 +280,7 @@ "denied": "Запрос на инструмент был отклонён.", "timeout": "Запрос на инструмент превысил время ожидания до получения подтверждения." }, + "toolPendingFallback": "Инструмент", "waiting": "Ожидание решения о разрешении на использование инструмента..." }, "type": { diff --git a/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/BashTool.tsx b/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/BashTool.tsx index 7d627c345..798807d4d 100644 --- a/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/BashTool.tsx +++ b/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/BashTool.tsx @@ -5,8 +5,6 @@ import { Terminal } from 'lucide-react' import { ToolTitle } from './GenericTools' import type { BashToolInput as BashToolInputType, BashToolOutput as BashToolOutputType } from './types' -const MAX_TAG_LENGTH = 100 - export function BashTool({ input, output @@ -17,12 +15,10 @@ export function BashTool({ // 如果有输出,计算输出行数 const outputLines = output ? output.split('\n').length : 0 - // 处理命令字符串的截断,添加空值检查 + // 处理命令字符串,添加空值检查 const command = input?.command ?? '' - const needsTruncate = command.length > MAX_TAG_LENGTH - const displayCommand = needsTruncate ? `${command.slice(0, MAX_TAG_LENGTH)}...` : command - const tagContent = {displayCommand} + const tagContent = {command} return { key: 'tool', @@ -34,16 +30,12 @@ export function BashTool({ params={input?.description} stats={output ? `${outputLines} ${outputLines === 1 ? 'line' : 'lines'}` : undefined} /> -
- {needsTruncate ? ( - {command}
} - trigger="hover"> - {tagContent} - - ) : ( - tagContent - )} +
+ {command}
} + trigger="hover"> + {tagContent} + ), diff --git a/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/GenericTools.tsx b/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/GenericTools.tsx index 9eaaf76f2..2245730ce 100644 --- a/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/GenericTools.tsx +++ b/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/GenericTools.tsx @@ -18,9 +18,9 @@ export function ToolTitle({ }) { return (
- {icon} - {label && {label}} - {params && {params}} + {icon && {icon}} + {label && {label}} + {params && {params}} {stats && {stats}}
) diff --git a/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/index.tsx b/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/index.tsx index 42a1cf403..e52330527 100644 --- a/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/index.tsx +++ b/src/renderer/src/pages/home/Messages/Tools/MessageAgentTools/index.tsx @@ -1,7 +1,10 @@ import { loggerService } from '@logger' +import { useAppSelector } from '@renderer/store' +import { selectPendingPermission } from '@renderer/store/toolPermissions' import type { NormalToolResponse } from '@renderer/types' import type { CollapseProps } from 'antd' -import { Collapse } from 'antd' +import { Collapse, Spin } from 'antd' +import { useTranslation } from 'react-i18next' // 导出所有类型 export * from './types' @@ -83,17 +86,41 @@ function ToolContent({ toolName, input, output }: { toolName: AgentToolsType; in // 统一的组件渲染入口 export function MessageAgentTools({ toolResponse }: { toolResponse: NormalToolResponse }) { const { arguments: args, response, tool, status } = toolResponse - logger.info('Rendering agent tool response', { + logger.debug('Rendering agent tool response', { tool: tool, arguments: args, + status, response }) + const pendingPermission = useAppSelector((state) => + selectPendingPermission(state.toolPermissions, toolResponse.toolCallId) + ) + if (status === 'pending') { - return + if (pendingPermission) { + return + } + return } return ( ) } + +function ToolPendingIndicator({ toolName, description }: { toolName?: string; description?: string }) { + const { t } = useTranslation() + const label = toolName || t('agent.toolPermission.toolPendingFallback', 'Tool') + const detail = description?.trim() || t('agent.toolPermission.executing') + + return ( +
+ +
+ {label} + {detail} +
+
+ ) +}