mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
Add Marketplace Agents to builder
Adds functionality to add Marketplace agents to the user's library and then to builder. Includes a loading indicator while the agent is being added. Refactors agent-to-block conversion into a utility function.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { ExternalLink, Plus } from "lucide-react";
|
||||
import { ExternalLink, Loader2, Plus } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import React, { ButtonHTMLAttributes } from "react";
|
||||
import { highlightText } from "./IntegrationBlock";
|
||||
@@ -14,6 +14,7 @@ interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
image_url?: string;
|
||||
highlightedText?: string;
|
||||
slug: string;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
interface MarketplaceAgentBlockComponent extends React.FC<Props> {
|
||||
@@ -26,6 +27,7 @@ const MarketplaceAgentBlock: MarketplaceAgentBlockComponent = ({
|
||||
creator_name,
|
||||
number_of_runs,
|
||||
className,
|
||||
loading,
|
||||
highlightedText,
|
||||
slug,
|
||||
...rest
|
||||
@@ -90,10 +92,14 @@ const MarketplaceAgentBlock: MarketplaceAgentBlockComponent = ({
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
"flex h-7 w-7 items-center justify-center rounded-[0.5rem] bg-zinc-700 group-disabled:bg-zinc-400",
|
||||
"flex h-7 min-w-7 items-center justify-center rounded-[0.5rem] bg-zinc-700 group-disabled:bg-zinc-400",
|
||||
)}
|
||||
>
|
||||
<Plus className="h-5 w-5 text-zinc-50" strokeWidth={2} />
|
||||
{!loading ? (
|
||||
<Plus className="h-5 w-5 text-zinc-50" strokeWidth={2} />
|
||||
) : (
|
||||
<Loader2 className="h-5 w-5 animate-spin" />
|
||||
)}
|
||||
</div>
|
||||
</Button>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import MarketplaceAgentBlock from "../MarketplaceAgentBlock";
|
||||
import { usePagination } from "@/hooks/usePagination";
|
||||
import ErrorState from "../ErrorState";
|
||||
import { useBackendAPI } from "@/lib/autogpt-server-api/context";
|
||||
import { convertLibraryAgentIntoBlock } from "@/lib/utils";
|
||||
import { useBlockMenuContext } from "../block-menu-provider";
|
||||
|
||||
const MarketplaceAgentsContent: React.FC = () => {
|
||||
const {
|
||||
@@ -16,6 +19,40 @@ const MarketplaceAgentsContent: React.FC = () => {
|
||||
request: { apiType: "store-agents" },
|
||||
pageSize: 10,
|
||||
});
|
||||
const api = useBackendAPI();
|
||||
const { addNode } = useBlockMenuContext();
|
||||
const [loadingSlug, setLoadingSlug] = useState<string | null>(null);
|
||||
|
||||
const handleAddStoreAgent = async ({
|
||||
creator_name,
|
||||
slug,
|
||||
}: {
|
||||
creator_name: string;
|
||||
slug: string;
|
||||
}) => {
|
||||
try {
|
||||
setLoadingSlug(slug);
|
||||
const details = await api.getStoreAgent(creator_name, slug);
|
||||
|
||||
if (!details.active_version_id) {
|
||||
console.error(
|
||||
"Cannot add store agent to library: active version ID is missing or undefined",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const libraryAgent = await api.addMarketplaceAgentToLibrary(
|
||||
details.active_version_id,
|
||||
);
|
||||
|
||||
const block = convertLibraryAgentIntoBlock(libraryAgent);
|
||||
addNode(block);
|
||||
} catch (error) {
|
||||
console.error("Failed to add store agent:", error);
|
||||
} finally {
|
||||
setLoadingSlug(null);
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
@@ -58,6 +95,13 @@ const MarketplaceAgentsContent: React.FC = () => {
|
||||
image_url={agent.agent_image}
|
||||
creator_name={agent.creator}
|
||||
number_of_runs={agent.runs}
|
||||
loading={loadingSlug === agent.slug}
|
||||
onClick={() =>
|
||||
handleAddStoreAgent({
|
||||
creator_name: agent.creator,
|
||||
slug: agent.slug,
|
||||
})
|
||||
}
|
||||
/>
|
||||
))}
|
||||
{loadingMore && hasMore && (
|
||||
|
||||
@@ -2,13 +2,8 @@ import React from "react";
|
||||
import UGCAgentBlock from "../UGCAgentBlock";
|
||||
import { usePagination } from "@/hooks/usePagination";
|
||||
import ErrorState from "../ErrorState";
|
||||
import {
|
||||
Block,
|
||||
BlockUIType,
|
||||
LibraryAgent,
|
||||
SpecialBlockID,
|
||||
} from "@/lib/autogpt-server-api";
|
||||
import { useBlockMenuContext } from "../block-menu-provider";
|
||||
import { convertLibraryAgentIntoBlock } from "@/lib/utils";
|
||||
|
||||
const MyAgentsContent: React.FC = () => {
|
||||
const {
|
||||
@@ -25,31 +20,6 @@ const MyAgentsContent: React.FC = () => {
|
||||
});
|
||||
const { addNode } = useBlockMenuContext();
|
||||
|
||||
const handleAddAgent = (agent: LibraryAgent) => {
|
||||
const block = {
|
||||
id: SpecialBlockID.AGENT,
|
||||
name: agent.name,
|
||||
description:
|
||||
`Ver.${agent.graph_version}` +
|
||||
(agent.description ? ` | ${agent.description}` : ""),
|
||||
categories: [{ category: "AGENT", description: "" }],
|
||||
inputSchema: agent.input_schema,
|
||||
outputSchema: agent.output_schema,
|
||||
staticOutput: false,
|
||||
uiType: BlockUIType.AGENT,
|
||||
uiKey: agent.id,
|
||||
costs: [],
|
||||
hardcodedValues: {
|
||||
graph_id: agent.graph_id,
|
||||
graph_version: agent.graph_version,
|
||||
input_schema: agent.input_schema,
|
||||
output_schema: agent.output_schema,
|
||||
},
|
||||
} as Block;
|
||||
|
||||
addNode(block);
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div
|
||||
@@ -90,7 +60,10 @@ const MyAgentsContent: React.FC = () => {
|
||||
edited_time={agent.updated_at}
|
||||
version={agent.graph_version}
|
||||
image_url={agent.image_url}
|
||||
onClick={() => handleAddAgent(agent)}
|
||||
onClick={() => {
|
||||
const block = convertLibraryAgentIntoBlock(agent);
|
||||
addNode(block);
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{loadingMore && hasMore && (
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { type ClassValue, clsx } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { Category, Graph } from "@/lib/autogpt-server-api/types";
|
||||
import {
|
||||
Block,
|
||||
BlockUIType,
|
||||
Category,
|
||||
Graph,
|
||||
LibraryAgent,
|
||||
SpecialBlockID,
|
||||
} from "@/lib/autogpt-server-api/types";
|
||||
import { NodeDimension } from "@/components/Flow";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
@@ -396,3 +403,28 @@ export function getValue(key: string, value: any) {
|
||||
export function isEmptyOrWhitespace(str: string | undefined | null): boolean {
|
||||
return !str || str.trim().length === 0;
|
||||
}
|
||||
|
||||
export const convertLibraryAgentIntoBlock = (agent: LibraryAgent) => {
|
||||
const block = {
|
||||
id: SpecialBlockID.AGENT,
|
||||
name: agent.name,
|
||||
description:
|
||||
`Ver.${agent.graph_version}` +
|
||||
(agent.description ? ` | ${agent.description}` : ""),
|
||||
categories: [{ category: "AGENT", description: "" }],
|
||||
inputSchema: agent.input_schema,
|
||||
outputSchema: agent.output_schema,
|
||||
staticOutput: false,
|
||||
uiType: BlockUIType.AGENT,
|
||||
uiKey: agent.id,
|
||||
costs: [],
|
||||
hardcodedValues: {
|
||||
graph_id: agent.graph_id,
|
||||
graph_version: agent.graph_version,
|
||||
input_schema: agent.input_schema,
|
||||
output_schema: agent.output_schema,
|
||||
},
|
||||
} as Block;
|
||||
|
||||
return block;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user