mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-09 07:08:09 -05:00
feat(frontend): Add trigger agent banner for webhook-based flows (#11480)
This PR addresses the need for better user awareness when building trigger-based agents. When a user adds webhook/trigger nodes to their flow, a prominent banner now appears at the bottom of the builder informing them they're creating a "Trigger Agent" and providing a direct link to monitor its activity in the Agent Library. ### Changes 🏗️ - **Added TriggerAgentBanner component**: New banner that displays at the bottom of the builder when the flow contains webhook/trigger nodes - **Implemented webhook node detection**: Added `hasWebhookNodes` method to nodeStore that checks if any nodes are of type WEBHOOK or WEBHOOK_MANUAL - **Conditional banner display**: Builder now shows TriggerAgentBanner instead of BuilderActions when webhook nodes are present - **Dynamic library link**: Banner includes a link to the specific agent in the library (if found) or defaults to the general library page - **Integrated with existing flow context**: Uses the current flowID to fetch the corresponding library agent for proper linking ### 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] Add a webhook node to a flow and verify the banner appears - [x] Remove all webhook nodes and verify the banner disappears - [x] Test with both WEBHOOK and WEBHOOK_MANUAL node types - [x] Click the library link and verify it navigates to the correct agent page - [x] Test library link fallback when agent is not found in library - [x] Verify banner styling and positioning at bottom center of builder
This commit is contained in:
@@ -16,6 +16,7 @@ import { useCopyPaste } from "./useCopyPaste";
|
||||
import { FloatingReviewsPanel } from "@/components/organisms/FloatingReviewsPanel/FloatingReviewsPanel";
|
||||
import { parseAsString, useQueryStates } from "nuqs";
|
||||
import { CustomControls } from "./components/CustomControl";
|
||||
import { TriggerAgentBanner } from "./components/TriggerAgentBanner";
|
||||
|
||||
export const Flow = () => {
|
||||
const [{ flowExecutionID }] = useQueryStates({
|
||||
@@ -27,6 +28,9 @@ export const Flow = () => {
|
||||
const onNodesChange = useNodeStore(
|
||||
useShallow((state) => state.onNodesChange),
|
||||
);
|
||||
const hasWebhookNodes = useNodeStore(
|
||||
useShallow((state) => state.hasWebhookNodes()),
|
||||
);
|
||||
const nodeTypes = useMemo(() => ({ custom: CustomNode }), []);
|
||||
const edgeTypes = useMemo(() => ({ custom: CustomEdge }), []);
|
||||
const { edges, onConnect, onEdgesChange } = useCustomEdge();
|
||||
@@ -76,7 +80,7 @@ export const Flow = () => {
|
||||
<Background />
|
||||
<CustomControls setIsLocked={setIsLocked} isLocked={isLocked} />
|
||||
<NewControlPanel />
|
||||
<BuilderActions />
|
||||
{hasWebhookNodes ? <TriggerAgentBanner /> : <BuilderActions />}
|
||||
{<GraphLoadingBox flowContentLoading={isFlowContentLoading} />}
|
||||
{isGraphRunning && <RunningBackground />}
|
||||
</ReactFlow>
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
Alert,
|
||||
AlertDescription,
|
||||
AlertTitle,
|
||||
} from "@/components/molecules/Alert/Alert";
|
||||
import Link from "next/link";
|
||||
import { useGetV2GetLibraryAgentByGraphId } from "@/app/api/__generated__/endpoints/library/library";
|
||||
import { LibraryAgent } from "@/app/api/__generated__/models/libraryAgent";
|
||||
import { useQueryStates, parseAsString } from "nuqs";
|
||||
|
||||
export const TriggerAgentBanner = () => {
|
||||
const [{ flowID }] = useQueryStates({
|
||||
flowID: parseAsString,
|
||||
});
|
||||
|
||||
const { data: libraryAgent } = useGetV2GetLibraryAgentByGraphId(
|
||||
flowID ?? "",
|
||||
{},
|
||||
{
|
||||
query: {
|
||||
select: (x) => {
|
||||
return x.data as LibraryAgent;
|
||||
},
|
||||
enabled: !!flowID,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return (
|
||||
<Alert className="absolute bottom-4 left-1/2 z-20 w-auto -translate-x-1/2 select-none rounded-xlarge">
|
||||
<AlertTitle>You are building a Trigger Agent</AlertTitle>
|
||||
<AlertDescription>
|
||||
Your agent will listen for its trigger and will run when the time is
|
||||
right.
|
||||
<br />
|
||||
You can view its activity in your{" "}
|
||||
<Link
|
||||
href={
|
||||
libraryAgent ? `/library/agents/${libraryAgent.id}` : "/library"
|
||||
}
|
||||
className="underline"
|
||||
>
|
||||
Agent Library
|
||||
</Link>
|
||||
.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
);
|
||||
};
|
||||
@@ -44,6 +44,7 @@ type NodeStore = {
|
||||
) => void;
|
||||
getNodeExecutionResult: (nodeId: string) => NodeExecutionResult | undefined;
|
||||
getNodeBlockUIType: (nodeId: string) => BlockUIType;
|
||||
hasWebhookNodes: () => boolean;
|
||||
};
|
||||
|
||||
export const useNodeStore = create<NodeStore>((set, get) => ({
|
||||
@@ -204,4 +205,9 @@ export const useNodeStore = create<NodeStore>((set, get) => ({
|
||||
BlockUIType.STANDARD
|
||||
);
|
||||
},
|
||||
hasWebhookNodes: () => {
|
||||
return get().nodes.some((n) =>
|
||||
[BlockUIType.WEBHOOK, BlockUIType.WEBHOOK_MANUAL].includes(n.data.uiType),
|
||||
);
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user