diff --git a/client/src/components/Chat/Messages/Content/Parts/ReadFileCall.tsx b/client/src/components/Chat/Messages/Content/Parts/ReadFileCall.tsx index bcb5b4d11a..27a114b030 100644 --- a/client/src/components/Chat/Messages/Content/Parts/ReadFileCall.tsx +++ b/client/src/components/Chat/Messages/Content/Parts/ReadFileCall.tsx @@ -2,6 +2,7 @@ import { useMemo } from 'react'; import { FileText } from 'lucide-react'; import type { TAttachment, PartMetadata } from 'librechat-data-provider'; import ProgressText from '~/components/Chat/Messages/Content/ProgressText'; +import { toolPanelSpacingClassName } from '../disclosure'; import useToolCallState from './useToolCallState'; import useLazyHighlight from './useLazyHighlight'; import CodeWindowHeader from './CodeWindowHeader'; @@ -85,7 +86,10 @@ export default function ReadFileCall({ onExpand?: () => void; }) { const localize = useLocalize(); - const filePath = useMemo(() => parseJsonField(args, 'file_path'), [args]); + const filePath = useMemo( + () => parseJsonField(args, 'path') || parseJsonField(args, 'file_path'), + [args], + ); const intent = useToolCallIntent(args); const fileName = filePath.split('/').pop() || filePath; const lang = useMemo(() => langFromPath(filePath), [filePath]); @@ -130,7 +134,12 @@ export default function ReadFileCall({
{hasOutput && ( -
+
                 
diff --git a/client/src/components/Chat/Messages/Content/Parts/SkillCall.tsx b/client/src/components/Chat/Messages/Content/Parts/SkillCall.tsx
index 859605a33a..8a58ad08dc 100644
--- a/client/src/components/Chat/Messages/Content/Parts/SkillCall.tsx
+++ b/client/src/components/Chat/Messages/Content/Parts/SkillCall.tsx
@@ -2,6 +2,7 @@ import { useMemo } from 'react';
 import { ScrollText } from 'lucide-react';
 import type { TAttachment, PartMetadata } from 'librechat-data-provider';
 import ProgressText from '~/components/Chat/Messages/Content/ProgressText';
+import { toolPanelSpacingClassName } from '../disclosure';
 import useToolCallState from './useToolCallState';
 import { AttachmentGroup } from './Attachment';
 import parseJsonField from './parseJsonField';
@@ -33,14 +34,15 @@ export default function SkillCall({
   onExpand?: () => void;
 }) {
   const localize = useLocalize();
-  const skillName = useMemo(() => parseJsonField(args, 'skillName'), [args]);
+  const parsedSkillName = useMemo(() => parseJsonField(args, 'skillName'), [args]);
+  const skillName = parsedSkillName || localize('com_ui_skill').toLowerCase();
   const intent = useToolCallIntent(args);
 
   const { showCode, toggleCode, expandStyle, expandRef, phase, hasOutput } = useToolCallState({
     initialProgress,
     isSubmitting,
     output,
-    hasInput: !!skillName,
+    hasInput: !!parsedSkillName,
     onExpand,
     runStepStatus,
   });
@@ -67,14 +69,19 @@ export default function SkillCall({
               aria-hidden="true"
             />
           }
-          hasInput={!!skillName || hasOutput}
+          hasInput={!!parsedSkillName || hasOutput}
           isExpanded={showCode}
         />
       
{hasOutput && ( -
+
{localize('com_ui_output')} diff --git a/client/src/components/Chat/Messages/Content/ToolOutput/ToolIcon.tsx b/client/src/components/Chat/Messages/Content/ToolOutput/ToolIcon.tsx index 0c13b73f37..21ec24fdfc 100644 --- a/client/src/components/Chat/Messages/Content/ToolOutput/ToolIcon.tsx +++ b/client/src/components/Chat/Messages/Content/ToolOutput/ToolIcon.tsx @@ -8,6 +8,7 @@ import { FileText, MessageCircleQuestion, ScrollText, + Brain, Zap, Wrench, } from 'lucide-react'; @@ -30,6 +31,7 @@ export type ToolIconType = | 'read_file' | 'bash_tool' | 'ask_user_question' + | 'memory' | 'action' | 'generic'; @@ -44,6 +46,7 @@ const ICON_MAP: Record read_file: FileText, bash_tool: BashIcon, ask_user_question: MessageCircleQuestion, + memory: Brain, action: Zap, generic: Wrench, }; @@ -82,6 +85,9 @@ export function getToolIconType(name: string): ToolIconType { if (name === 'ask_user_question') { return 'ask_user_question'; } + if (name === 'set_memory' || name === 'delete_memory') { + return 'memory'; + } if (name.startsWith(Constants.LC_TRANSFER_TO_)) { return 'agent_handoff'; } diff --git a/client/src/locales/en/translation.json b/client/src/locales/en/translation.json index 9ae259db4a..6cfeb6cad5 100644 --- a/client/src/locales/en/translation.json +++ b/client/src/locales/en/translation.json @@ -1621,8 +1621,10 @@ "com_ui_more_options": "More options", "com_ui_my_prompts": "My Prompts", "com_ui_my_skills": "My Skills", + "com_ui_n_actions_failed": "{{0}} failed", "com_ui_n_files": "{{0}} files", "com_ui_n_files_changed": "{{0}} files changed", + "com_ui_n_searches": "{{0}} searches", "com_ui_name": "Name", "com_ui_name_sort": "Sort by Name", "com_ui_navigate_results": "Navigate results", @@ -1689,6 +1691,7 @@ "com_ui_omitted": "Omitted", "com_ui_on": "On", "com_ui_one_file_changed": "1 file changed", + "com_ui_one_action_failed": "1 failed", "com_ui_open_archived_chat_new_tab_title": "{{title}} (opens in new tab)", "com_ui_open_artifact": "Open artifact", "com_ui_open_as_artifact": "Open as artifact", @@ -1807,6 +1810,7 @@ "com_ui_queued_turn_reconciliation_required": "Awaiting reconciliation", "com_ui_quote_selections": "{{0}} selections", "com_ui_quotes_queued": "Quotes added for your next message", + "com_ui_ran_n_actions": "Ran {{0}} actions", "com_ui_ran_n_agents": "Ran {{0}} agents", "com_ui_read_aloud": "Read aloud", "com_ui_read_file": "Read {{0}}", @@ -1893,6 +1897,7 @@ "com_ui_run_code_error": "There was an error running the code", "com_ui_running": "Running...", "com_ui_running_command": "Running command", + "com_ui_running_n_actions": "Running {{0}} actions", "com_ui_running_n_agents": "Running {{0}} agents", "com_ui_sandbox_starting": "Starting sandbox environment", "com_ui_save": "Save", @@ -1981,7 +1986,9 @@ "com_ui_search_skills": "Search skills...", "com_ui_search_table": "Search table", "com_ui_search_table_description": "Type to filter results", + "com_ui_searched_web_and_files": "Searched web and files", "com_ui_searching_files": "Searching your files", + "com_ui_searching_web_and_files": "Searching web and files", "com_ui_seconds": "seconds", "com_ui_secret_key": "Secret Key", "com_ui_select": "Select", @@ -2393,9 +2400,14 @@ "com_ui_tool_name_ask_user_question": "Question", "com_ui_tool_name_code": "Code", "com_ui_tool_name_code_analysis": "Code Analysis", + "com_ui_tool_name_create_file": "Create File", + "com_ui_tool_name_delete_memory": "Delete Memory", + "com_ui_tool_name_edit_file": "Edit File", "com_ui_tool_name_file_search": "File Search", "com_ui_tool_name_image_edit": "Image Edit", + "com_ui_tool_name_read_file": "Read File", "com_ui_tool_name_image_gen": "Image Generation", + "com_ui_tool_name_set_memory": "Save Memory", "com_ui_tool_name_web_search": "Web Search", "com_ui_tool_response_placeholder": "Type a substitute result to return to the agent", "com_ui_tools": "Tools", diff --git a/client/src/utils/__tests__/toolLabels.test.ts b/client/src/utils/__tests__/toolLabels.test.ts index b22413395e..e0d1f9ee44 100644 --- a/client/src/utils/__tests__/toolLabels.test.ts +++ b/client/src/utils/__tests__/toolLabels.test.ts @@ -74,6 +74,10 @@ describe('getToolDisplayLabel', () => { ); }); + it.each(['set_memory', 'delete_memory'])('returns a friendly memory label for %s', (toolName) => { + expect(getToolDisplayLabel(toolName, identityLocalize)).toBe(TOOL_FRIENDLY_NAME_KEYS[toolName]); + }); + it('returns the raw name for an unknown native tool', () => { expect(getToolDisplayLabel('custom_tool', identityLocalize)).toBe('custom_tool'); }); diff --git a/client/src/utils/toolLabels.ts b/client/src/utils/toolLabels.ts index 58757b9ce8..d0dbe41c2a 100644 --- a/client/src/utils/toolLabels.ts +++ b/client/src/utils/toolLabels.ts @@ -22,6 +22,12 @@ export const TOOL_FRIENDLY_NAME_KEYS: Record = { code_interpreter: 'com_ui_tool_name_code_analysis', retrieval: 'com_ui_tool_name_file_search', ask_user_question: 'com_ui_tool_name_ask_user_question', + create_file: 'com_ui_tool_name_create_file', + set_memory: 'com_ui_tool_name_set_memory', + edit_file: 'com_ui_tool_name_edit_file', + delete_memory: 'com_ui_tool_name_delete_memory', + skill: 'com_ui_skill', + read_file: 'com_ui_tool_name_read_file', }; export interface ParsedToolName {