diff --git a/autogpt_platform/backend/backend/server/v2/chat/response_model.py b/autogpt_platform/backend/backend/server/v2/chat/response_model.py index 7ca335ff85..2d38820bd5 100644 --- a/autogpt_platform/backend/backend/server/v2/chat/response_model.py +++ b/autogpt_platform/backend/backend/server/v2/chat/response_model.py @@ -39,6 +39,7 @@ class StreamToolCallStart(StreamBaseResponse): """Tool call started notification.""" type: ResponseType = ResponseType.TOOL_CALL_START + tool_name: str = Field(..., description="Name of the tool that was executed") tool_id: str = Field(..., description="Unique tool call ID") diff --git a/autogpt_platform/backend/backend/server/v2/chat/service.py b/autogpt_platform/backend/backend/server/v2/chat/service.py index 467be47e79..4328deb016 100644 --- a/autogpt_platform/backend/backend/server/v2/chat/service.py +++ b/autogpt_platform/backend/backend/server/v2/chat/service.py @@ -440,9 +440,11 @@ async def _stream_chat_chunks( if ( idx not in emitted_start_for_idx and tool_calls[idx]["id"] + and tool_calls[idx]["function"]["name"] ): yield StreamToolCallStart( tool_id=tool_calls[idx]["id"], + tool_name=tool_calls[idx]["function"]["name"], timestamp=datetime.now(UTC).isoformat(), ) emitted_start_for_idx.add(idx) diff --git a/autogpt_platform/backend/backend/server/v2/chat/tools/__init__.py b/autogpt_platform/backend/backend/server/v2/chat/tools/__init__.py index bdccb9c1dc..e0218bb7a2 100644 --- a/autogpt_platform/backend/backend/server/v2/chat/tools/__init__.py +++ b/autogpt_platform/backend/backend/server/v2/chat/tools/__init__.py @@ -43,7 +43,7 @@ async def execute_tool( "find_agent": find_agent_tool, "get_agent_details": get_agent_details_tool, "get_required_setup_info": get_required_setup_info_tool, - "setup_agent": setup_agent_tool, + "schedule_agent": setup_agent_tool, "run_agent": run_agent_tool, } if tool_name not in tool_map: diff --git a/autogpt_platform/backend/backend/server/v2/chat/tools/find_agent.py b/autogpt_platform/backend/backend/server/v2/chat/tools/find_agent.py index 40fc4ae28b..111041a8f4 100644 --- a/autogpt_platform/backend/backend/server/v2/chat/tools/find_agent.py +++ b/autogpt_platform/backend/backend/server/v2/chat/tools/find_agent.py @@ -120,7 +120,7 @@ class FindAgentTool(BaseTool): f"Found {len(agents)} agent{'s' if len(agents) != 1 else ''} for '{query}'" ) return AgentCarouselResponse( - message="Now you have found some options for the user to choose from. Please ask the user if they would like to use any of these agents. If they do, please call the get_agent_details tool for this agent.", + message="Now you have found some options for the user to choose from. You can add a link to a recommended agent at: /marketplace/agent/agent_id Please ask the user if they would like to use any of these agents. If they do, please call the get_agent_details tool for this agent.", title=title, agents=agents, count=len(agents), diff --git a/autogpt_platform/backend/backend/server/v2/chat/tools/get_agent_details.py b/autogpt_platform/backend/backend/server/v2/chat/tools/get_agent_details.py index 3f8e263ad8..8e8d42dbc9 100644 --- a/autogpt_platform/backend/backend/server/v2/chat/tools/get_agent_details.py +++ b/autogpt_platform/backend/backend/server/v2/chat/tools/get_agent_details.py @@ -204,7 +204,7 @@ class GetAgentDetailsTool(BaseTool): ) return AgentDetailsResponse( - message=f"Found agent '{agent_details.name}'. You do not need to run this tool again for this agent.", + message=f"Found agent '{agent_details.name}'. When presenting the agent you do not need to mention the required credentials. You do not need to run this tool again for this agent.", session_id=session_id, agent=agent_details, user_authenticated=user_id is not None, diff --git a/autogpt_platform/backend/backend/server/v2/chat/tools/models.py b/autogpt_platform/backend/backend/server/v2/chat/tools/models.py index e8c2ab0ff1..d18d2c2d23 100644 --- a/autogpt_platform/backend/backend/server/v2/chat/tools/models.py +++ b/autogpt_platform/backend/backend/server/v2/chat/tools/models.py @@ -66,6 +66,7 @@ class AgentCarouselResponse(ToolResponseBase): title: str = "Available Agents" agents: list[AgentInfo] count: int + name: str = "agent_carousel" class NoResultsResponse(ToolResponseBase): @@ -73,6 +74,7 @@ class NoResultsResponse(ToolResponseBase): type: ResponseType = ResponseType.NO_RESULTS suggestions: list[str] = [] + name: str = "no_results" # Agent details models diff --git a/autogpt_platform/backend/backend/server/v2/chat/tools/run_agent.py b/autogpt_platform/backend/backend/server/v2/chat/tools/run_agent.py index 25c7a90577..4b3754b322 100644 --- a/autogpt_platform/backend/backend/server/v2/chat/tools/run_agent.py +++ b/autogpt_platform/backend/backend/server/v2/chat/tools/run_agent.py @@ -248,7 +248,7 @@ class RunAgentTool(BaseTool): ) return ExecutionStartedResponse( - message="Agent execution successfully started. Do not run this tool again unless specifically asked to run the agent again.", + message=f"Agent execution successfully started. You can add a link to the agent at: /library/agents/{library_agent.id}. Do not run this tool again unless specifically asked to run the agent again.", session_id=session_id, execution_id=execution.id, graph_id=library_agent.graph_id, diff --git a/autogpt_platform/backend/backend/server/v2/chat/tools/setup_agent.py b/autogpt_platform/backend/backend/server/v2/chat/tools/setup_agent.py index e6e71e2aad..5a2ddb8fbe 100644 --- a/autogpt_platform/backend/backend/server/v2/chat/tools/setup_agent.py +++ b/autogpt_platform/backend/backend/server/v2/chat/tools/setup_agent.py @@ -273,7 +273,7 @@ class SetupAgentTool(BaseTool): ) return ExecutionStartedResponse( - message="Agent execution successfully scheduled. Do not run this tool again unless specifically asked to run the agent again.", + message=f"Agent execution successfully scheduled. You can add a link to the agent at: /library/agents/{library_agent.id}. Do not run this tool again unless specifically asked to run the agent again.", session_id=session_id, execution_id=result.id, graph_id=library_agent.graph_id, diff --git a/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatContainer/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatContainer/helpers.ts index e2b37dbb6d..0ef2ed81ab 100644 --- a/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatContainer/helpers.ts +++ b/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatContainer/helpers.ts @@ -145,6 +145,7 @@ export function parseToolResponse( if (isAgentArray(agentsData)) { return { type: "agent_carousel", + toolName: "agent_carousel", agents: agentsData, totalCount: parsedResult.total_count as number | undefined, timestamp: timestamp || new Date(), @@ -156,6 +157,7 @@ export function parseToolResponse( if (responseType === "execution_started") { return { type: "execution_started", + toolName: "execution_started", executionId: (parsedResult.execution_id as string) || "", agentName: parsedResult.agent_name as string | undefined, message: parsedResult.message as string | undefined, @@ -165,6 +167,7 @@ export function parseToolResponse( if (responseType === "need_login") { return { type: "login_needed", + toolName: "login_needed", message: (parsedResult.message as string) || "Please sign in to use chat and agent features", @@ -260,6 +263,7 @@ export function extractCredentialsNeeded( })); return { type: "credentials_needed", + toolName: "get_required_setup_info", credentials, message: `To run ${agentName}, you need to add ${credentials.length === 1 ? "credentials" : `${credentials.length} credentials`}.`, agentName, diff --git a/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatContainer/useChatContainer.handlers.ts b/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatContainer/useChatContainer.handlers.ts index e7cf030252..4cca79daca 100644 --- a/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatContainer/useChatContainer.handlers.ts +++ b/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatContainer/useChatContainer.handlers.ts @@ -141,6 +141,7 @@ export function handleLoginNeeded( ) { const loginNeededMessage: ChatMessageData = { type: "login_needed", + toolName: "login_needed", message: chunk.message || "Please sign in to use chat and agent features", sessionId: chunk.session_id || deps.sessionId, agentInfo: chunk.agent_info, diff --git a/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatMessage/ChatMessage.tsx b/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatMessage/ChatMessage.tsx index 1c302a1613..6d8fdacb9a 100644 --- a/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatMessage/ChatMessage.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatMessage/ChatMessage.tsx @@ -9,12 +9,9 @@ import { ToolCallMessage } from "@/app/(platform)/chat/components/ToolCallMessag import { ToolResponseMessage } from "@/app/(platform)/chat/components/ToolResponseMessage/ToolResponseMessage"; import { AuthPromptWidget } from "@/app/(platform)/chat/components/AuthPromptWidget/AuthPromptWidget"; import { ChatCredentialsSetup } from "@/app/(platform)/chat/components/ChatCredentialsSetup/ChatCredentialsSetup"; -import { NoResultsMessage } from "@/app/(platform)/chat/components/NoResultsMessage/NoResultsMessage"; -import { AgentCarouselMessage } from "@/app/(platform)/chat/components/AgentCarouselMessage/AgentCarouselMessage"; -import { ExecutionStartedMessage } from "@/app/(platform)/chat/components/ExecutionStartedMessage/ExecutionStartedMessage"; import { useSupabase } from "@/lib/supabase/hooks/useSupabase"; import { useChatMessage, type ChatMessageData } from "./useChatMessage"; - +import { getToolActionPhrase } from "@/app/(platform)/chat/helpers"; export interface ChatMessageProps { message: ChatMessageData; className?: string; @@ -38,9 +35,6 @@ export function ChatMessage({ isToolResponse, isLoginNeeded, isCredentialsNeeded, - isNoResults, - isAgentCarousel, - isExecutionStarted, } = useChatMessage(message); const handleAllCredentialsComplete = useCallback( @@ -129,63 +123,25 @@ export function ChatMessage({ if (isToolCall && message.type === "tool_call") { return (
- +
); } // Render tool response messages - if (isToolResponse && message.type === "tool_response") { + if ( + (isToolResponse && message.type === "tool_response") || + message.type === "no_results" || + message.type === "agent_carousel" || + message.type === "execution_started" + ) { return (
- +
); } - // Render no results messages - if (isNoResults && message.type === "no_results") { - return ( - - ); - } - - // Render agent carousel messages - if (isAgentCarousel && message.type === "agent_carousel") { - return ( - - ); - } - - // Render execution started messages - if (isExecutionStarted && message.type === "execution_started") { - return ( - - ); - } - // Render regular chat messages if (message.type === "message") { return ( diff --git a/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatMessage/useChatMessage.ts b/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatMessage/useChatMessage.ts index 3168df6921..983c166ecb 100644 --- a/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatMessage/useChatMessage.ts +++ b/autogpt_platform/frontend/src/app/(platform)/chat/components/ChatMessage/useChatMessage.ts @@ -25,6 +25,7 @@ export type ChatMessageData = } | { type: "login_needed"; + toolName: string; message: string; sessionId: string; agentInfo?: { @@ -36,6 +37,7 @@ export type ChatMessageData = } | { type: "credentials_needed"; + toolName: string; credentials: Array<{ provider: string; providerName: string; @@ -49,6 +51,7 @@ export type ChatMessageData = } | { type: "no_results"; + toolName: string; message: string; suggestions?: string[]; sessionId?: string; @@ -56,6 +59,7 @@ export type ChatMessageData = } | { type: "agent_carousel"; + toolName: string; agents: Array<{ id: string; name: string; @@ -67,6 +71,7 @@ export type ChatMessageData = } | { type: "execution_started"; + toolName: string; executionId: string; agentName?: string; message?: string; diff --git a/autogpt_platform/frontend/src/app/(platform)/chat/components/ToolCallMessage/ToolCallMessage.tsx b/autogpt_platform/frontend/src/app/(platform)/chat/components/ToolCallMessage/ToolCallMessage.tsx index ce8d0fb2d5..c1babc587c 100644 --- a/autogpt_platform/frontend/src/app/(platform)/chat/components/ToolCallMessage/ToolCallMessage.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/chat/components/ToolCallMessage/ToolCallMessage.tsx @@ -1,29 +1,18 @@ -import React, { useState } from "react"; -import { Text } from "@/components/atoms/Text/Text"; -import { Wrench, Spinner, CaretDown, CaretUp } from "@phosphor-icons/react"; +import React from "react"; +import { WrenchIcon } from "@phosphor-icons/react"; import { cn } from "@/lib/utils"; -import { getToolDisplayName } from "@/app/(platform)/chat/helpers"; -import type { ToolArguments } from "@/types/chat"; +import { getToolActionPhrase } from "@/app/(platform)/chat/helpers"; export interface ToolCallMessageProps { - toolId: string; toolName: string; - arguments?: ToolArguments; className?: string; } -export function ToolCallMessage({ - toolId, - toolName, - arguments: args, - className, -}: ToolCallMessageProps) { - const [isExpanded, setIsExpanded] = useState(false); - +export function ToolCallMessage({ toolName, className }: ToolCallMessageProps) { return (
-
- + - - {getToolDisplayName(toolName)} + + {getToolActionPhrase(toolName)}... + -
- - - Executing... - -
- -
- - {/* Expandable Content */} - {isExpanded && ( -
- {args && Object.keys(args).length > 0 && ( -
-
- Parameters: -
-
-
-                  {JSON.stringify(args, null, 2)}
-                
-
-
- )} - - - Tool ID: {toolId.slice(0, 8)}... - -
- )} ); } diff --git a/autogpt_platform/frontend/src/app/(platform)/chat/components/ToolResponseMessage/ToolResponseMessage.tsx b/autogpt_platform/frontend/src/app/(platform)/chat/components/ToolResponseMessage/ToolResponseMessage.tsx index c70c65b4a0..fe5d858461 100644 --- a/autogpt_platform/frontend/src/app/(platform)/chat/components/ToolResponseMessage/ToolResponseMessage.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/chat/components/ToolResponseMessage/ToolResponseMessage.tsx @@ -1,90 +1,23 @@ -import React, { useState } from "react"; -import { Text } from "@/components/atoms/Text/Text"; -import { - CheckCircle, - XCircle, - CaretDown, - CaretUp, - Wrench, -} from "@phosphor-icons/react"; +import React from "react"; +import { WrenchIcon } from "@phosphor-icons/react"; import { cn } from "@/lib/utils"; -import { getToolDisplayName } from "@/app/(platform)/chat/helpers"; -import type { ToolResult } from "@/types/chat"; +import { getToolActionPhrase } from "@/app/(platform)/chat/helpers"; export interface ToolResponseMessageProps { - toolId: string; toolName: string; - result: ToolResult; success?: boolean; className?: string; } -// Check if result should be hidden (special response types) -function shouldHideResult(result: ToolResult): boolean { - try { - const resultString = - typeof result === "string" ? result : JSON.stringify(result); - const parsed = JSON.parse(resultString); - - // Hide raw JSON for these special types - if (parsed.type === "agent_carousel") return true; - if (parsed.type === "execution_started") return true; - if (parsed.type === "setup_requirements") return true; - if (parsed.type === "no_results") return true; - - return false; - } catch { - return false; - } -} - -// Get a friendly summary for special response types -function getResultSummary(result: ToolResult): string | null { - try { - const resultString = - typeof result === "string" ? result : JSON.stringify(result); - const parsed = JSON.parse(resultString); - - if (parsed.type === "agent_carousel") { - return `Found ${parsed.agents?.length || parsed.count || 0} agents${parsed.query ? ` matching "${parsed.query}"` : ""}`; - } - if (parsed.type === "execution_started") { - return `Started execution${parsed.execution_id ? ` (ID: ${parsed.execution_id.slice(0, 8)}...)` : ""}`; - } - if (parsed.type === "setup_requirements") { - return "Retrieved setup requirements"; - } - if (parsed.type === "no_results") { - return parsed.message || "No results found"; - } - - return null; - } catch { - return null; - } -} - export function ToolResponseMessage({ - toolId, toolName, - result, success = true, className, }: ToolResponseMessageProps) { - const [isExpanded, setIsExpanded] = useState(false); - - const hideResult = shouldHideResult(result); - const resultSummary = getResultSummary(result); - const resultString = - typeof result === "object" - ? JSON.stringify(result, null, 2) - : String(result); - const shouldTruncate = resultString.length > 200; - return (
- - {getToolDisplayName(toolName)} + {getToolActionPhrase(toolName)}... -
- {success ? ( - - ) : ( - - )} - - {success ? "Completed" : "Error"} - -
- - {!hideResult && ( - - )}
- - {/* Expandable Content */} - {isExpanded && !hideResult && ( -
-
- Result: -
-
-
-              {shouldTruncate && !isExpanded
-                ? `${resultString.slice(0, 200)}...`
-                : resultString}
-            
-
- - - Tool ID: {toolId.slice(0, 8)}... - -
- )} - - {/* Summary for special response types */} - {hideResult && resultSummary && ( -
- - {resultSummary} - -
- )} ); } diff --git a/autogpt_platform/frontend/src/app/(platform)/chat/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/chat/helpers.ts index 8dd77ee298..5a1e5eb93f 100644 --- a/autogpt_platform/frontend/src/app/(platform)/chat/helpers.ts +++ b/autogpt_platform/frontend/src/app/(platform)/chat/helpers.ts @@ -1,5 +1,6 @@ /** * Maps internal tool names to user-friendly display names with emojis. + * @deprecated Use getToolActionPhrase or getToolCompletionPhrase for status messages * * @param toolName - The internal tool name from the backend * @returns A user-friendly display name with an emoji prefix @@ -16,6 +17,54 @@ export function getToolDisplayName(toolName: string): string { return toolDisplayNames[toolName] || toolName; } +/** + * Maps internal tool names to human-friendly action phrases (present continuous). + * Used for tool call messages to indicate what action is currently happening. + * + * @param toolName - The internal tool name from the backend + * @returns A human-friendly action phrase in present continuous tense + */ +export function getToolActionPhrase(toolName: string): string { + const toolActionPhrases: Record = { + find_agent: "Looking for agents in the marketplace", + agent_carousel: "Looking for agents in the marketplace", + get_agent_details: "Learning about the agent", + check_credentials: "Checking your credentials", + setup_agent: "Setting up the agent", + execution_started: "Running the agent", + run_agent: "Running the agent", + get_required_setup_info: "Getting setup requirements", + schedule_agent: "Scheduling the agent to run", + }; + + // Return mapped phrase or generate human-friendly fallback + return toolActionPhrases[toolName] || toolName; +} + +/** + * Maps internal tool names to human-friendly completion phrases (past tense). + * Used for tool response messages to indicate what action was completed. + * + * @param toolName - The internal tool name from the backend + * @returns A human-friendly completion phrase in past tense + */ +export function getToolCompletionPhrase(toolName: string): string { + const toolCompletionPhrases: Record = { + find_agent: "Finished searching the marketplace", + get_agent_details: "Got agent details", + check_credentials: "Checked credentials", + setup_agent: "Agent setup complete", + run_agent: "Agent execution started", + get_required_setup_info: "Got setup requirements", + }; + + // Return mapped phrase or generate human-friendly fallback + return ( + toolCompletionPhrases[toolName] || + `Finished ${toolName.replace(/_/g, " ").replace("...", "")}` + ); +} + /** Validate UUID v4 format */ export function isValidUUID(value: string): boolean { const uuidRegex = diff --git a/autogpt_platform/frontend/src/components/molecules/TallyPoup/TallyPopup.tsx b/autogpt_platform/frontend/src/components/molecules/TallyPoup/TallyPopup.tsx index 86d98812c9..15584e19e1 100644 --- a/autogpt_platform/frontend/src/components/molecules/TallyPoup/TallyPopup.tsx +++ b/autogpt_platform/frontend/src/components/molecules/TallyPoup/TallyPopup.tsx @@ -13,7 +13,7 @@ export function TallyPopupSimple() { } return ( -
+
{state.showTutorial && (