From c22c18374d323b285ea720e53f1a459006d45238 Mon Sep 17 00:00:00 2001 From: Swifty Date: Thu, 5 Feb 2026 15:37:31 +0100 Subject: [PATCH] feat(frontend): Add ready-to-test prompt after agent creation [SECRT-1882] (#11975) ## Summary - Add special UI prompt when agent is successfully created in chat - Show "Agent Created Successfully" with agent name - Provide two action buttons: - **Run with example values**: Sends chat message asking AI to run with placeholders - **Run with my inputs**: Opens RunAgentModal for custom input configuration - After run/schedule, automatically send chat message with execution details for AI monitoring https://github.com/user-attachments/assets/b11e118c-de59-4b79-a629-8bd0d52d9161 ## Test plan - [x] Create an agent through chat - [x] Verify "Agent Created Successfully" prompt appears - [x] Click "Run with example values" - verify chat message is sent - [x] Click "Run with my inputs" - verify RunAgentModal opens - [x] Fill inputs and run - verify chat message with execution ID is sent - [x] Fill inputs and schedule - verify chat message with schedule details is sent --------- Co-authored-by: Otto --- .../components/ChatMessage/ChatMessage.tsx | 1 + .../components/MessageList/MessageList.tsx | 1 + .../LastToolResponse/LastToolResponse.tsx | 3 + .../AgentCreatedPrompt.tsx | 128 ++++++++++++++++++ .../ToolResponseMessage.tsx | 16 +++ .../components/ToolResponseMessage/helpers.ts | 37 +++++ 6 files changed, 186 insertions(+) create mode 100644 autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/AgentCreatedPrompt.tsx diff --git a/autogpt_platform/frontend/src/components/contextual/Chat/components/ChatMessage/ChatMessage.tsx b/autogpt_platform/frontend/src/components/contextual/Chat/components/ChatMessage/ChatMessage.tsx index 2ac433a272..851c3b33e8 100644 --- a/autogpt_platform/frontend/src/components/contextual/Chat/components/ChatMessage/ChatMessage.tsx +++ b/autogpt_platform/frontend/src/components/contextual/Chat/components/ChatMessage/ChatMessage.tsx @@ -346,6 +346,7 @@ export function ChatMessage({ toolId={message.toolId} toolName={message.toolName} result={message.result} + onSendMessage={onSendMessage} /> ); diff --git a/autogpt_platform/frontend/src/components/contextual/Chat/components/MessageList/MessageList.tsx b/autogpt_platform/frontend/src/components/contextual/Chat/components/MessageList/MessageList.tsx index 01d107c64e..d8478f1e82 100644 --- a/autogpt_platform/frontend/src/components/contextual/Chat/components/MessageList/MessageList.tsx +++ b/autogpt_platform/frontend/src/components/contextual/Chat/components/MessageList/MessageList.tsx @@ -73,6 +73,7 @@ export function MessageList({ key={index} message={message} prevMessage={messages[index - 1]} + onSendMessage={onSendMessage} /> ); } diff --git a/autogpt_platform/frontend/src/components/contextual/Chat/components/MessageList/components/LastToolResponse/LastToolResponse.tsx b/autogpt_platform/frontend/src/components/contextual/Chat/components/MessageList/components/LastToolResponse/LastToolResponse.tsx index 15b10e5715..7c5a75bec5 100644 --- a/autogpt_platform/frontend/src/components/contextual/Chat/components/MessageList/components/LastToolResponse/LastToolResponse.tsx +++ b/autogpt_platform/frontend/src/components/contextual/Chat/components/MessageList/components/LastToolResponse/LastToolResponse.tsx @@ -5,11 +5,13 @@ import { shouldSkipAgentOutput } from "../../helpers"; export interface LastToolResponseProps { message: ChatMessageData; prevMessage: ChatMessageData | undefined; + onSendMessage?: (content: string) => void; } export function LastToolResponse({ message, prevMessage, + onSendMessage, }: LastToolResponseProps) { if (message.type !== "tool_response") return null; @@ -21,6 +23,7 @@ export function LastToolResponse({ toolId={message.toolId} toolName={message.toolName} result={message.result} + onSendMessage={onSendMessage} /> ); diff --git a/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/AgentCreatedPrompt.tsx b/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/AgentCreatedPrompt.tsx new file mode 100644 index 0000000000..8494452eea --- /dev/null +++ b/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/AgentCreatedPrompt.tsx @@ -0,0 +1,128 @@ +"use client"; + +import { useGetV2GetLibraryAgent } from "@/app/api/__generated__/endpoints/library/library"; +import { GraphExecutionJobInfo } from "@/app/api/__generated__/models/graphExecutionJobInfo"; +import { GraphExecutionMeta } from "@/app/api/__generated__/models/graphExecutionMeta"; +import { RunAgentModal } from "@/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/RunAgentModal"; +import { Button } from "@/components/atoms/Button/Button"; +import { Text } from "@/components/atoms/Text/Text"; +import { + CheckCircleIcon, + PencilLineIcon, + PlayIcon, +} from "@phosphor-icons/react"; +import { AIChatBubble } from "../AIChatBubble/AIChatBubble"; + +interface Props { + agentName: string; + libraryAgentId: string; + onSendMessage?: (content: string) => void; +} + +export function AgentCreatedPrompt({ + agentName, + libraryAgentId, + onSendMessage, +}: Props) { + // Fetch library agent eagerly so modal is ready when user clicks + const { data: libraryAgentResponse, isLoading } = useGetV2GetLibraryAgent( + libraryAgentId, + { + query: { + enabled: !!libraryAgentId, + }, + }, + ); + + const libraryAgent = + libraryAgentResponse?.status === 200 ? libraryAgentResponse.data : null; + + function handleRunWithPlaceholders() { + onSendMessage?.( + `Run the agent "${agentName}" with placeholder/example values so I can test it.`, + ); + } + + function handleRunCreated(execution: GraphExecutionMeta) { + onSendMessage?.( + `I've started the agent "${agentName}". The execution ID is ${execution.id}. Please monitor its progress and let me know when it completes.`, + ); + } + + function handleScheduleCreated(schedule: GraphExecutionJobInfo) { + const scheduleInfo = schedule.cron + ? `with cron schedule "${schedule.cron}"` + : "to run on the specified schedule"; + onSendMessage?.( + `I've scheduled the agent "${agentName}" ${scheduleInfo}. The schedule ID is ${schedule.id}.`, + ); + } + + return ( + +
+
+
+ +
+
+ + Agent Created Successfully + + + "{agentName}" is ready to test + +
+
+ +
+ + Ready to test? + +
+ + {libraryAgent ? ( + + + Run with my inputs + + } + agent={libraryAgent} + onRunCreated={handleRunCreated} + onScheduleCreated={handleScheduleCreated} + /> + ) : ( + + )} +
+ + or just ask me + +
+
+
+ ); +} diff --git a/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/ToolResponseMessage.tsx b/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/ToolResponseMessage.tsx index 27da02beb8..53d5f1ef96 100644 --- a/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/ToolResponseMessage.tsx +++ b/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/ToolResponseMessage.tsx @@ -2,11 +2,13 @@ import { Text } from "@/components/atoms/Text/Text"; import { cn } from "@/lib/utils"; import type { ToolResult } from "@/types/chat"; import { WarningCircleIcon } from "@phosphor-icons/react"; +import { AgentCreatedPrompt } from "./AgentCreatedPrompt"; import { AIChatBubble } from "../AIChatBubble/AIChatBubble"; import { MarkdownContent } from "../MarkdownContent/MarkdownContent"; import { formatToolResponse, getErrorMessage, + isAgentSavedResponse, isErrorResponse, } from "./helpers"; @@ -16,6 +18,7 @@ export interface ToolResponseMessageProps { result?: ToolResult; success?: boolean; className?: string; + onSendMessage?: (content: string) => void; } export function ToolResponseMessage({ @@ -24,6 +27,7 @@ export function ToolResponseMessage({ result, success: _success, className, + onSendMessage, }: ToolResponseMessageProps) { if (isErrorResponse(result)) { const errorMessage = getErrorMessage(result); @@ -43,6 +47,18 @@ export function ToolResponseMessage({ ); } + // Check for agent_saved response - show special prompt + const agentSavedData = isAgentSavedResponse(result); + if (agentSavedData.isSaved) { + return ( + + ); + } + const formattedText = formatToolResponse(result, toolName); return ( diff --git a/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/helpers.ts b/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/helpers.ts index 2397176603..9ed4e3973b 100644 --- a/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/helpers.ts +++ b/autogpt_platform/frontend/src/components/contextual/Chat/components/ToolResponseMessage/helpers.ts @@ -6,6 +6,43 @@ function stripInternalReasoning(content: string): string { .trim(); } +export interface AgentSavedData { + isSaved: boolean; + agentName: string; + agentId: string; + libraryAgentId: string; + libraryAgentLink: string; +} + +export function isAgentSavedResponse(result: unknown): AgentSavedData { + if (typeof result !== "object" || result === null) { + return { + isSaved: false, + agentName: "", + agentId: "", + libraryAgentId: "", + libraryAgentLink: "", + }; + } + const response = result as Record; + if (response.type === "agent_saved") { + return { + isSaved: true, + agentName: (response.agent_name as string) || "Agent", + agentId: (response.agent_id as string) || "", + libraryAgentId: (response.library_agent_id as string) || "", + libraryAgentLink: (response.library_agent_link as string) || "", + }; + } + return { + isSaved: false, + agentName: "", + agentId: "", + libraryAgentId: "", + libraryAgentLink: "", + }; +} + export function isErrorResponse(result: unknown): boolean { if (typeof result === "string") { const lower = result.toLowerCase();