From 117bb0543897fa360f5f0511e7d442145198b64a Mon Sep 17 00:00:00 2001 From: Reinier van der Leer Date: Wed, 10 Dec 2025 16:52:02 +0100 Subject: [PATCH] fix(frontend/library): Fix trigger UX flows in v3 library (#11589) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Resolves #11586 - Follow-up to #11580 ### Changes 🏗️ - Fix logic to include manual triggers as a possibility - Fix input render logic to use trigger setup schema if applicable - Fix rendering payload input for externally triggered runs - Amend `RunAgentModal` to load preset inputs+credentials if selected - Amend `SelectedTemplateView` to use modified input for run (if applicable) - Hide non-applicable buttons in `SelectedRunView` for externally triggered runs - Implement auto-navigation to `SelectedTriggerView` on trigger setup ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Can set up manual triggers - [x] Navigates to trigger view after setup - [x] Can set up automatic triggers - [x] Can create templates from runs - [x] Can run templates - [x] Can run templates with modified input --- .../NewAgentLibraryView.tsx | 32 ++++++-- .../AgentInputsReadOnly.tsx | 35 +++++--- .../modals/AgentInputsReadOnly/helpers.ts | 3 +- .../modals/RunAgentModal/RunAgentModal.tsx | 12 ++- .../ModalRunSection/ModalRunSection.tsx | 3 +- .../components/RunActions/RunActions.tsx | 3 +- .../modals/RunAgentModal/useAgentRunModal.tsx | 43 ++++++---- .../components/other/EmptyTasks.tsx | 6 +- .../SelectedRunView/SelectedRunView.tsx | 4 +- .../SelectedRunActions/SelectedRunActions.tsx | 80 ++++++++++--------- .../useSelectedRunActions.ts | 56 +++++++------ .../SelectedTemplateView.tsx | 7 +- .../useSelectedTemplateView.ts | 14 +++- .../useNewAgentLibraryView.ts | 34 ++++++-- 14 files changed, 216 insertions(+), 116 deletions(-) diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/NewAgentLibraryView.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/NewAgentLibraryView.tsx index f951c09522..8ee76ce37a 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/NewAgentLibraryView.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/NewAgentLibraryView.tsx @@ -1,5 +1,6 @@ "use client"; +import { LibraryAgentPreset } from "@/app/api/__generated__/models/libraryAgentPreset"; import { Button } from "@/components/atoms/Button/Button"; import { Breadcrumbs } from "@/components/molecules/Breadcrumbs/Breadcrumbs"; import { ErrorCard } from "@/components/molecules/ErrorCard/ErrorCard"; @@ -24,11 +25,13 @@ import { useNewAgentLibraryView } from "./useNewAgentLibraryView"; export function NewAgentLibraryView() { const { - agent, - hasAnyItems, - ready, - error, agentId, + agent, + ready, + activeTemplate, + isTemplateLoading, + error, + hasAnyItems, activeItem, sidebarLoading, activeTab, @@ -38,6 +41,12 @@ export function NewAgentLibraryView() { handleClearSelectedRun, } = useNewAgentLibraryView(); + function onTriggerSetup(newTrigger: LibraryAgentPreset) { + if (!agent) return; + + handleSelectRun(newTrigger.id, "triggers"); + } + if (error) { return (
- +
); @@ -82,16 +91,23 @@ export function NewAgentLibraryView() { > + } agent={agent} - agentId={agent.id.toString()} onRunCreated={(execution) => handleSelectRun(execution.id, "runs")} onScheduleCreated={(schedule) => handleSelectRun(schedule.id, "scheduled") } + onTriggerSetup={onTriggerSetup} + initialInputValues={activeTemplate?.inputs} + initialInputCredentials={activeTemplate?.credentials} /> @@ -151,7 +167,7 @@ export function NewAgentLibraryView() { ) : ( - + )} diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/AgentInputsReadOnly/AgentInputsReadOnly.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/AgentInputsReadOnly/AgentInputsReadOnly.tsx index d46a6bfc9e..a11e88f29a 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/AgentInputsReadOnly/AgentInputsReadOnly.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/AgentInputsReadOnly/AgentInputsReadOnly.tsx @@ -1,7 +1,10 @@ "use client"; import type { LibraryAgent } from "@/app/api/__generated__/models/libraryAgent"; -import type { CredentialsMetaInput } from "@/lib/autogpt-server-api/types"; +import type { + BlockIOSubSchema, + CredentialsMetaInput, +} from "@/lib/autogpt-server-api/types"; import { CredentialsInput } from "../CredentialsInputs/CredentialsInputs"; import { getAgentCredentialsFields, @@ -20,13 +23,21 @@ export function AgentInputsReadOnly({ inputs, credentialInputs, }: Props) { - const fields = getAgentInputFields(agent); - const credentialFields = getAgentCredentialsFields(agent); - const inputEntries = Object.entries(fields); - const credentialEntries = Object.entries(credentialFields); + const inputFields = getAgentInputFields(agent); + const credentialFieldEntries = Object.entries( + getAgentCredentialsFields(agent), + ); - const hasInputs = inputs && inputEntries.length > 0; - const hasCredentials = credentialInputs && credentialEntries.length > 0; + // Take actual input entries as leading; augment with schema from input fields. + // TODO: ensure consistent ordering. + const inputEntries = + inputs && + Object.entries(inputs).map<[string, [BlockIOSubSchema | undefined, any]]>( + ([k, v]) => [k, [inputFields[k], v]], + ); + + const hasInputs = inputEntries && inputEntries.length > 0; + const hasCredentials = credentialInputs && credentialFieldEntries.length > 0; if (!hasInputs && !hasCredentials) { return
No input for this run.
; @@ -37,11 +48,13 @@ export function AgentInputsReadOnly({ {/* Regular inputs */} {hasInputs && (
- {inputEntries.map(([key, sub]) => ( + {inputEntries.map(([key, [schema, value]]) => (
- +

- {renderValue((inputs as Record)[key])} + {renderValue(value)}

))} @@ -52,7 +65,7 @@ export function AgentInputsReadOnly({ {hasCredentials && (
{hasInputs &&
} - {credentialEntries.map(([key, inputSubSchema]) => { + {credentialFieldEntries.map(([key, inputSubSchema]) => { const credential = credentialInputs![key]; if (!credential) return null; diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/AgentInputsReadOnly/helpers.ts b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/AgentInputsReadOnly/helpers.ts index 5fd8ff4fe7..95069b1d30 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/AgentInputsReadOnly/helpers.ts +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/AgentInputsReadOnly/helpers.ts @@ -13,7 +13,8 @@ export function getCredentialTypeDisplayName(type: string): string { } export function getAgentInputFields(agent: LibraryAgent): Record { - const schema = agent.input_schema as unknown as { + const schema = (agent.trigger_setup_info?.config_schema ?? + agent.input_schema) as unknown as { properties?: Record; } | null; if (!schema || !schema.properties) return {}; diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/RunAgentModal.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/RunAgentModal.tsx index 94849b5828..e53f31a349 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/RunAgentModal.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/RunAgentModal.tsx @@ -3,6 +3,7 @@ import { GraphExecutionJobInfo } from "@/app/api/__generated__/models/graphExecutionJobInfo"; import { GraphExecutionMeta } from "@/app/api/__generated__/models/graphExecutionMeta"; import { LibraryAgent } from "@/app/api/__generated__/models/libraryAgent"; +import { LibraryAgentPreset } from "@/app/api/__generated__/models/libraryAgentPreset"; import { Button } from "@/components/atoms/Button/Button"; import { Tooltip, @@ -22,16 +23,20 @@ import { useAgentRunModal } from "./useAgentRunModal"; interface Props { triggerSlot: React.ReactNode; agent: LibraryAgent; - agentId: string; - agentVersion?: number; + initialInputValues?: Record; + initialInputCredentials?: Record; onRunCreated?: (execution: GraphExecutionMeta) => void; + onTriggerSetup?: (preset: LibraryAgentPreset) => void; onScheduleCreated?: (schedule: GraphExecutionJobInfo) => void; } export function RunAgentModal({ triggerSlot, agent, + initialInputValues, + initialInputCredentials, onRunCreated, + onTriggerSetup, onScheduleCreated, }: Props) { const { @@ -71,6 +76,9 @@ export function RunAgentModal({ handleRun, } = useAgentRunModal(agent, { onRun: onRunCreated, + onSetupTrigger: onTriggerSetup, + initialInputValues, + initialInputCredentials, }); const [isScheduleModalOpen, setIsScheduleModalOpen] = useState(false); diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/components/ModalRunSection/ModalRunSection.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/components/ModalRunSection/ModalRunSection.tsx index c2528ccdc9..d8c4ecb730 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/components/ModalRunSection/ModalRunSection.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/components/ModalRunSection/ModalRunSection.tsx @@ -26,7 +26,8 @@ export function ModalRunSection() { return (
- {defaultRunType === "automatic-trigger" ? ( + {defaultRunType === "automatic-trigger" || + defaultRunType === "manual-trigger" ? ( - {defaultRunType === "automatic-trigger" + {defaultRunType === "automatic-trigger" || + defaultRunType === "manual-trigger" ? "Set up Trigger" : "Start Task"} diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/useAgentRunModal.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/useAgentRunModal.tsx index 2d3da4bdc7..fcd3a7b87a 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/useAgentRunModal.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/modals/RunAgentModal/useAgentRunModal.tsx @@ -6,7 +6,6 @@ import { getGetV2ListPresetsQueryKey, usePostV2SetupTrigger, } from "@/app/api/__generated__/endpoints/presets/presets"; -import { GraphExecutionJobInfo } from "@/app/api/__generated__/models/graphExecutionJobInfo"; import { GraphExecutionMeta } from "@/app/api/__generated__/models/graphExecutionMeta"; import { LibraryAgent } from "@/app/api/__generated__/models/libraryAgent"; import { LibraryAgentPreset } from "@/app/api/__generated__/models/libraryAgentPreset"; @@ -14,7 +13,7 @@ import { useToast } from "@/components/molecules/Toast/use-toast"; import { isEmpty } from "@/lib/utils"; import { analytics } from "@/services/analytics"; import { useQueryClient } from "@tanstack/react-query"; -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { showExecutionErrorToast } from "./errorHelpers"; export type RunVariant = @@ -25,8 +24,9 @@ export type RunVariant = interface UseAgentRunModalCallbacks { onRun?: (execution: GraphExecutionMeta) => void; - onCreateSchedule?: (schedule: GraphExecutionJobInfo) => void; onSetupTrigger?: (preset: LibraryAgentPreset) => void; + initialInputValues?: Record; + initialInputCredentials?: Record; } export function useAgentRunModal( @@ -36,18 +36,28 @@ export function useAgentRunModal( const { toast } = useToast(); const queryClient = useQueryClient(); const [isOpen, setIsOpen] = useState(false); - const [inputValues, setInputValues] = useState>({}); + const [inputValues, setInputValues] = useState>( + callbacks?.initialInputValues || {}, + ); const [inputCredentials, setInputCredentials] = useState>( - {}, + callbacks?.initialInputCredentials || {}, ); const [presetName, setPresetName] = useState(""); const [presetDescription, setPresetDescription] = useState(""); // Determine the default run type based on agent capabilities - const defaultRunType: RunVariant = agent.has_external_trigger - ? "automatic-trigger" + const defaultRunType: RunVariant = agent.trigger_setup_info + ? agent.trigger_setup_info.credentials_input_name + ? "automatic-trigger" + : "manual-trigger" : "manual"; + // Update input values/credentials if template is selected/unselected + useEffect(() => { + setInputValues(callbacks?.initialInputValues || {}); + setInputCredentials(callbacks?.initialInputCredentials || {}); + }, [callbacks?.initialInputValues, callbacks?.initialInputCredentials]); + // API mutations const executeGraphMutation = usePostV1ExecuteGraphAgent({ mutation: { @@ -105,11 +115,13 @@ export function useAgentRunModal( }, }); - // Input schema validation - const agentInputSchema = useMemo( - () => agent.input_schema || { properties: {}, required: [] }, - [agent.input_schema], - ); + // Input schema validation (use trigger schema for triggered agents) + const agentInputSchema = useMemo(() => { + if (agent.trigger_setup_info?.config_schema) { + return agent.trigger_setup_info.config_schema; + } + return agent.input_schema || { properties: {}, required: [] }; + }, [agent.input_schema, agent.trigger_setup_info]); const agentInputFields = useMemo(() => { if ( @@ -205,7 +217,10 @@ export function useAgentRunModal( return; } - if (defaultRunType === "automatic-trigger") { + if ( + defaultRunType === "automatic-trigger" || + defaultRunType === "manual-trigger" + ) { // Setup trigger if (!presetName.trim()) { toast({ @@ -262,7 +277,7 @@ export function useAgentRunModal( setIsOpen, // Run mode - defaultRunType, + defaultRunType: defaultRunType as RunVariant, // Form: regular inputs inputValues, diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/other/EmptyTasks.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/other/EmptyTasks.tsx index 62a75e4993..26bfbde882 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/other/EmptyTasks.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/other/EmptyTasks.tsx @@ -2,6 +2,7 @@ import { getV1GetGraphVersion } from "@/app/api/__generated__/endpoints/graphs/graphs"; import { LibraryAgent } from "@/app/api/__generated__/models/libraryAgent"; +import { LibraryAgentPreset } from "@/app/api/__generated__/models/libraryAgentPreset"; import { Button } from "@/components/atoms/Button/Button"; import { Text } from "@/components/atoms/Text/Text"; import { ShowMoreText } from "@/components/molecules/ShowMoreText/ShowMoreText"; @@ -15,9 +16,10 @@ import { EmptyTasksIllustration } from "./EmptyTasksIllustration"; type Props = { agent: LibraryAgent; + onTriggerSetup?: (preset: LibraryAgentPreset) => void; }; -export function EmptyTasks({ agent }: Props) { +export function EmptyTasks({ agent, onTriggerSetup }: Props) { const { toast } = useToast(); async function handleExport() { @@ -75,7 +77,7 @@ export function EmptyTasks({ agent }: Props) { } agent={agent} - agentId={agent.id.toString()} + onTriggerSetup={onTriggerSetup} />
diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/SelectedRunView.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/SelectedRunView.tsx index 97292b85ce..cc5872097e 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/SelectedRunView.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/SelectedRunView.tsx @@ -198,8 +198,8 @@ export function SelectedRunView({
diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/components/SelectedRunActions/SelectedRunActions.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/components/SelectedRunActions/SelectedRunActions.tsx index 7533577bf5..92db3e0b37 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/components/SelectedRunActions/SelectedRunActions.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/components/SelectedRunActions/SelectedRunActions.tsx @@ -20,13 +20,18 @@ import { useSelectedRunActions } from "./useSelectedRunActions"; type Props = { agent: LibraryAgent; run: GraphExecution | undefined; - scheduleRecurrence?: string; onSelectRun?: (id: string) => void; onClearSelectedRun?: () => void; }; -export function SelectedRunActions(props: Props) { +export function SelectedRunActions({ + agent, + run, + onSelectRun, + onClearSelectedRun, +}: Props) { const { + canRunManually, handleRunAgain, handleStopRun, isRunningAgain, @@ -37,21 +42,20 @@ export function SelectedRunActions(props: Props) { isCreateTemplateModalOpen, setIsCreateTemplateModalOpen, } = useSelectedRunActions({ - agentGraphId: props.agent.graph_id, - run: props.run, - agent: props.agent, - onSelectRun: props.onSelectRun, - onClearSelectedRun: props.onClearSelectedRun, + agentGraphId: agent.graph_id, + run: run, + agent: agent, + onSelectRun: onSelectRun, }); const shareExecutionResultsEnabled = useGetFlag(Flag.SHARE_EXECUTION_RESULTS); - const isRunning = props.run?.status === "RUNNING"; + const isRunning = run?.status === "RUNNING"; - if (!props.run || !props.agent) return null; + if (!run || !agent) return null; return ( - {!isRunning ? ( + {canRunManually && !isRunning ? ( + + {canRunManually && ( + <> + + setIsCreateTemplateModalOpen(false)} + onCreate={handleCreateTemplate} + run={run} + /> + + )} - setIsCreateTemplateModalOpen(false)} - onCreate={handleCreateTemplate} - run={props.run} + agent={agent} + run={run} + agentGraphId={agent.graph_id} + onClearSelectedRun={onClearSelectedRun} /> ); diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/components/SelectedRunActions/useSelectedRunActions.ts b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/components/SelectedRunActions/useSelectedRunActions.ts index 462490b6da..03fc0b4ae8 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/components/SelectedRunActions/useSelectedRunActions.ts +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedRunView/components/SelectedRunActions/useSelectedRunActions.ts @@ -15,15 +15,19 @@ import { useToast } from "@/components/molecules/Toast/use-toast"; import { useQueryClient } from "@tanstack/react-query"; import { useState } from "react"; -interface Args { +interface Params { agentGraphId: string; run?: GraphExecution; agent?: LibraryAgent; onSelectRun?: (id: string) => void; - onClearSelectedRun?: () => void; } -export function useSelectedRunActions(args: Args) { +export function useSelectedRunActions({ + agentGraphId, + run, + agent, + onSelectRun, +}: Params) { const queryClient = useQueryClient(); const { toast } = useToast(); @@ -31,8 +35,9 @@ export function useSelectedRunActions(args: Args) { const [isCreateTemplateModalOpen, setIsCreateTemplateModalOpen] = useState(false); - const canStop = - args.run?.status === "RUNNING" || args.run?.status === "QUEUED"; + const canStop = run?.status === "RUNNING" || run?.status === "QUEUED"; + + const canRunManually = !agent?.trigger_setup_info; const { mutateAsync: stopRun, isPending: isStopping } = usePostV1StopGraphExecution(); @@ -46,16 +51,16 @@ export function useSelectedRunActions(args: Args) { async function handleStopRun() { try { await stopRun({ - graphId: args.run?.graph_id ?? "", - graphExecId: args.run?.id ?? "", + graphId: run?.graph_id ?? "", + graphExecId: run?.id ?? "", }); toast({ title: "Run stopped" }); await queryClient.invalidateQueries({ - queryKey: getGetV1ListGraphExecutionsInfiniteQueryOptions( - args.agentGraphId, - ).queryKey, + queryKey: + getGetV1ListGraphExecutionsInfiniteQueryOptions(agentGraphId) + .queryKey, }); } catch (error: unknown) { toast({ @@ -70,7 +75,7 @@ export function useSelectedRunActions(args: Args) { } async function handleRunAgain() { - if (!args.run) { + if (!run) { toast({ title: "Run not found", description: "Run not found", @@ -83,11 +88,11 @@ export function useSelectedRunActions(args: Args) { toast({ title: "Run started" }); const res = await executeRun({ - graphId: args.run.graph_id, - graphVersion: args.run.graph_version, + graphId: run.graph_id, + graphVersion: run.graph_version, data: { - inputs: args.run.inputs || {}, - credentials_inputs: args.run.credential_inputs || {}, + inputs: run.inputs || {}, + credentials_inputs: run.credential_inputs || {}, source: "library", }, }); @@ -95,12 +100,12 @@ export function useSelectedRunActions(args: Args) { const newRunId = res?.status === 200 ? (res?.data?.id ?? "") : ""; await queryClient.invalidateQueries({ - queryKey: getGetV1ListGraphExecutionsInfiniteQueryOptions( - args.agentGraphId, - ).queryKey, + queryKey: + getGetV1ListGraphExecutionsInfiniteQueryOptions(agentGraphId) + .queryKey, }); - if (newRunId && args.onSelectRun) args.onSelectRun(newRunId); + if (newRunId && onSelectRun) onSelectRun(newRunId); } catch (error: unknown) { toast({ title: "Failed to start run", @@ -118,7 +123,7 @@ export function useSelectedRunActions(args: Args) { } async function handleCreateTemplate(name: string, description: string) { - if (!args.run) { + if (!run) { toast({ title: "Run not found", description: "Cannot create template from missing run", @@ -132,7 +137,7 @@ export function useSelectedRunActions(args: Args) { data: { name, description, - graph_execution_id: args.run.id, + graph_execution_id: run.id, }, }); @@ -141,10 +146,10 @@ export function useSelectedRunActions(args: Args) { title: "Template created", }); - if (args.agent) { + if (agent) { queryClient.invalidateQueries({ queryKey: getGetV2ListPresetsQueryKey({ - graph_id: args.agent.graph_id, + graph_id: agent.graph_id, }), }); } @@ -164,8 +169,8 @@ export function useSelectedRunActions(args: Args) { } // Open in builder URL helper - const openInBuilderHref = args.run - ? `/build?flowID=${args.run.graph_id}&flowVersion=${args.run.graph_version}&flowExecutionID=${args.run.id}` + const openInBuilderHref = run + ? `/build?flowID=${run.graph_id}&flowVersion=${run.graph_version}&flowExecutionID=${run.id}` : undefined; return { @@ -173,6 +178,7 @@ export function useSelectedRunActions(args: Args) { showDeleteDialog, canStop, isStopping, + canRunManually, isRunningAgain, handleShowDeleteDialog, handleStopRun, diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedTemplateView/SelectedTemplateView.tsx b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedTemplateView/SelectedTemplateView.tsx index b1c89c1945..8f64417f77 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedTemplateView/SelectedTemplateView.tsx +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedTemplateView/SelectedTemplateView.tsx @@ -95,6 +95,7 @@ export function SelectedTemplateView({ return null; } + const templateOrTrigger = agent.trigger_setup_info ? "Trigger" : "Template"; const hasWebhook = !!template.webhook_id && template.webhook; return ( @@ -111,14 +112,14 @@ export function SelectedTemplateView({ /> )} - +
setName(e.target.value)} - placeholder="Enter template name" + placeholder={`Enter ${templateOrTrigger.toLowerCase()} name`} /> setDescription(e.target.value)} - placeholder="Enter template description" + placeholder={`Enter ${templateOrTrigger.toLowerCase()} description`} />
diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedTemplateView/useSelectedTemplateView.ts b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedTemplateView/useSelectedTemplateView.ts index 58483fdc74..a0f34f54a2 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedTemplateView/useSelectedTemplateView.ts +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/components/selected-views/SelectedTemplateView/useSelectedTemplateView.ts @@ -138,11 +138,21 @@ export function useSelectedTemplateView({ } function handleStartTask() { + if (!query.data) return; + + const inputsChanged = + JSON.stringify(inputs) !== JSON.stringify(query.data.inputs || {}); + + const credentialsChanged = + JSON.stringify(credentials) !== + JSON.stringify(query.data.credentials || {}); + + // Use changed unpersisted inputs if applicable executeMutation.mutate({ presetId: templateId, data: { - inputs: {}, - credential_inputs: {}, + inputs: inputsChanged ? inputs : undefined, + credential_inputs: credentialsChanged ? credentials : undefined, }, }); } diff --git a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/useNewAgentLibraryView.ts b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/useNewAgentLibraryView.ts index b7b6301ad6..c016a27722 100644 --- a/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/useNewAgentLibraryView.ts +++ b/autogpt_platform/frontend/src/app/(platform)/library/agents/[id]/components/NewAgentLibraryView/useNewAgentLibraryView.ts @@ -1,5 +1,7 @@ import { useGetV2GetLibraryAgent } from "@/app/api/__generated__/endpoints/library/library"; +import { useGetV2GetASpecificPreset } from "@/app/api/__generated__/endpoints/presets/presets"; import { LibraryAgent } from "@/app/api/__generated__/models/libraryAgent"; +import { LibraryAgentPreset } from "@/app/api/__generated__/models/libraryAgentPreset"; import { okData } from "@/app/api/helpers"; import { useParams } from "next/navigation"; import { parseAsString, useQueryStates } from "nuqs"; @@ -24,7 +26,7 @@ export function useNewAgentLibraryView() { const agentId = id as string; const { - data: response, + data: agent, isSuccess, error, } = useGetV2GetLibraryAgent(agentId, { @@ -41,6 +43,24 @@ export function useNewAgentLibraryView() { const activeTab = useMemo(() => parseTab(activeTabRaw), [activeTabRaw]); + const { + data: _template, + isSuccess: isTemplateLoaded, + isLoading: isTemplateLoading, + error: templateError, + } = useGetV2GetASpecificPreset(activeItem ?? "", { + query: { + enabled: Boolean(activeTab === "templates" && activeItem), + select: okData, + }, + }); + const activeTemplate = + isTemplateLoaded && + activeTab === "templates" && + _template?.id === activeItem + ? _template + : null; + useEffect(() => { if (!activeTabRaw && !activeItem) { setQueryStates({ @@ -71,10 +91,10 @@ export function useNewAgentLibraryView() { const showSidebarLayout = sidebarLoading || hasAnyItems; useEffect(() => { - if (response) { - document.title = `${response.name} - Library - AutoGPT Platform`; + if (agent) { + document.title = `${agent.name} - Library - AutoGPT Platform`; } - }, [response]); + }, [agent]); useEffect(() => { if ( @@ -135,9 +155,11 @@ export function useNewAgentLibraryView() { return { agentId: id, + agent, ready: isSuccess, - error, - agent: response, + activeTemplate, + isTemplateLoading, + error: error || templateError, hasAnyItems, showSidebarLayout, activeItem,