fix(frontend/library): Fix trigger UX flows in v3 library (#11589)

- 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
This commit is contained in:
Reinier van der Leer
2025-12-10 16:52:02 +01:00
committed by GitHub
parent 979d7c3b74
commit 117bb05438
14 changed files with 216 additions and 116 deletions

View File

@@ -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 (
<ErrorCard
@@ -65,7 +74,7 @@ export function NewAgentLibraryView() {
/>
</div>
<div className="flex min-h-0 flex-1">
<EmptyTasks agent={agent} />
<EmptyTasks agent={agent} onTriggerSetup={onTriggerSetup} />
</div>
</div>
);
@@ -82,16 +91,23 @@ export function NewAgentLibraryView() {
>
<RunAgentModal
triggerSlot={
<Button variant="primary" size="large" className="w-full">
<Button
variant="primary"
size="large"
className="w-full"
disabled={isTemplateLoading && activeTab === "templates"}
>
<PlusIcon size={20} /> New task
</Button>
}
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}
/>
</div>
@@ -151,7 +167,7 @@ export function NewAgentLibraryView() {
</SelectedViewLayout>
) : (
<SelectedViewLayout agentName={agent.name} agentId={agent.id}>
<EmptyTasks agent={agent} />
<EmptyTasks agent={agent} onTriggerSetup={onTriggerSetup} />
</SelectedViewLayout>
)}
</div>

View File

@@ -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 <div className="text-neutral-600">No input for this run.</div>;
@@ -37,11 +48,13 @@ export function AgentInputsReadOnly({
{/* Regular inputs */}
{hasInputs && (
<div className="flex flex-col gap-4">
{inputEntries.map(([key, sub]) => (
{inputEntries.map(([key, [schema, value]]) => (
<div key={key} className="flex flex-col gap-1.5">
<label className="text-sm font-medium">{sub?.title || key}</label>
<label className="text-sm font-medium">
{schema?.title || key}
</label>
<p className="whitespace-pre-wrap break-words text-sm text-neutral-700">
{renderValue((inputs as Record<string, any>)[key])}
{renderValue(value)}
</p>
</div>
))}
@@ -52,7 +65,7 @@ export function AgentInputsReadOnly({
{hasCredentials && (
<div className="flex flex-col gap-6">
{hasInputs && <div className="border-t border-neutral-200 pt-4" />}
{credentialEntries.map(([key, inputSubSchema]) => {
{credentialFieldEntries.map(([key, inputSubSchema]) => {
const credential = credentialInputs![key];
if (!credential) return null;

View File

@@ -13,7 +13,8 @@ export function getCredentialTypeDisplayName(type: string): string {
}
export function getAgentInputFields(agent: LibraryAgent): Record<string, any> {
const schema = agent.input_schema as unknown as {
const schema = (agent.trigger_setup_info?.config_schema ??
agent.input_schema) as unknown as {
properties?: Record<string, any>;
} | null;
if (!schema || !schema.properties) return {};

View File

@@ -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<string, any>;
initialInputCredentials?: Record<string, any>;
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);

View File

@@ -26,7 +26,8 @@ export function ModalRunSection() {
return (
<div className="flex flex-col gap-4">
{defaultRunType === "automatic-trigger" ? (
{defaultRunType === "automatic-trigger" ||
defaultRunType === "manual-trigger" ? (
<ModalSection
title="Task Trigger"
subtitle="Set up a trigger for the agent to run this task automatically"

View File

@@ -24,7 +24,8 @@ export function RunActions({
disabled={!isRunReady || isExecuting || isSettingUpTrigger}
loading={isExecuting || isSettingUpTrigger}
>
{defaultRunType === "automatic-trigger"
{defaultRunType === "automatic-trigger" ||
defaultRunType === "manual-trigger"
? "Set up Trigger"
: "Start Task"}
</Button>

View File

@@ -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<string, any>;
initialInputCredentials?: Record<string, any>;
}
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<Record<string, any>>({});
const [inputValues, setInputValues] = useState<Record<string, any>>(
callbacks?.initialInputValues || {},
);
const [inputCredentials, setInputCredentials] = useState<Record<string, any>>(
{},
callbacks?.initialInputCredentials || {},
);
const [presetName, setPresetName] = useState<string>("");
const [presetDescription, setPresetDescription] = useState<string>("");
// 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,

View File

@@ -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) {
</Button>
}
agent={agent}
agentId={agent.id.toString()}
onTriggerSetup={onTriggerSetup}
/>
</div>
</div>

View File

@@ -198,8 +198,8 @@ export function SelectedRunView({
<RunDetailCard title="Your input">
<AgentInputsReadOnly
agent={agent}
inputs={(run as any)?.inputs}
credentialInputs={(run as any)?.credential_inputs}
inputs={run?.inputs}
credentialInputs={run?.credential_inputs}
/>
</RunDetailCard>
</div>

View File

@@ -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 (
<SelectedActionsWrap>
{!isRunning ? (
{canRunManually && !isRunning ? (
<Button
variant="icon"
size="icon"
@@ -103,37 +107,37 @@ export function SelectedRunActions(props: Props) {
) : null}
{shareExecutionResultsEnabled && (
<ShareRunButton
graphId={props.agent.graph_id}
executionId={props.run.id}
isShared={props.run.is_shared}
shareToken={props.run.share_token}
graphId={agent.graph_id}
executionId={run.id}
isShared={run.is_shared}
shareToken={run.share_token}
/>
)}
<FloatingSafeModeToggle
graph={props.agent}
variant="white"
fullWidth={false}
/>
<Button
variant="icon"
size="icon"
aria-label="Save task as template"
onClick={() => setIsCreateTemplateModalOpen(true)}
title="Create template"
>
<CardsThreeIcon weight="bold" size={18} className="text-zinc-700" />
</Button>
<FloatingSafeModeToggle graph={agent} variant="white" fullWidth={false} />
{canRunManually && (
<>
<Button
variant="icon"
size="icon"
aria-label="Save task as template"
onClick={() => setIsCreateTemplateModalOpen(true)}
title="Create template"
>
<CardsThreeIcon weight="bold" size={18} className="text-zinc-700" />
</Button>
<CreateTemplateModal
isOpen={isCreateTemplateModalOpen}
onClose={() => setIsCreateTemplateModalOpen(false)}
onCreate={handleCreateTemplate}
run={run}
/>
</>
)}
<AgentActionsDropdown
agent={props.agent}
run={props.run}
agentGraphId={props.agent.graph_id}
onClearSelectedRun={props.onClearSelectedRun}
/>
<CreateTemplateModal
isOpen={isCreateTemplateModalOpen}
onClose={() => setIsCreateTemplateModalOpen(false)}
onCreate={handleCreateTemplate}
run={props.run}
agent={agent}
run={run}
agentGraphId={agent.graph_id}
onClearSelectedRun={onClearSelectedRun}
/>
</SelectedActionsWrap>
);

View File

@@ -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,

View File

@@ -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({
/>
)}
<RunDetailCard title="Template Details">
<RunDetailCard title={`${templateOrTrigger} Details`}>
<div className="flex flex-col gap-2">
<Input
id="template-name"
label="Name"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Enter template name"
placeholder={`Enter ${templateOrTrigger.toLowerCase()} name`}
/>
<Input
@@ -128,7 +129,7 @@ export function SelectedTemplateView({
rows={3}
value={description}
onChange={(e) => setDescription(e.target.value)}
placeholder="Enter template description"
placeholder={`Enter ${templateOrTrigger.toLowerCase()} description`}
/>
</div>
</RunDetailCard>

View File

@@ -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,
},
});
}

View File

@@ -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<LibraryAgentPreset>,
},
});
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,