Skip to content

Commit

Permalink
Add listing and descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
homanp committed Aug 6, 2023
1 parent 46c5dec commit 85d1da7
Show file tree
Hide file tree
Showing 11 changed files with 217 additions and 107 deletions.
31 changes: 27 additions & 4 deletions app/api/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ async def create_agent(body: Agent, token=Depends(JWTBearer())):
agent = prisma.agent.create(
{
"name": body.name,
"description": body.description,
"avatarUrl": body.avatarUrl,
"type": body.type,
"llm": json.dumps(body.llm),
Expand Down Expand Up @@ -57,11 +58,33 @@ async def read_agents(token=Depends(JWTBearer())):
},
order={"createdAt": "desc"},
)
return {"success": True, "data": agents}

if agents or agents == []:
return {"success": True, "data": agents}
else:
raise Exception("Couldn't fetch agents from prisma")
except Exception as e:
logger.error(e)

raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="No agents found",
)


@router.get(
"/agents/library",
name="List library agents",
description="List all library agents",
)
async def read_library_agents(token=Depends(JWTBearer())):
"""Library agentsendpoint"""
try:
agents = prisma.agent.find_many(
where={"isListed": True},
include={
"user": True,
},
order={"createdAt": "desc"},
)
return {"success": True, "data": agents}
except Exception as e:
logger.error(e)

Expand Down
7 changes: 3 additions & 4 deletions app/api/api_tokens.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ async def read_api_tokens(token=Depends(JWTBearer())):
api_tokens = prisma.apitoken.find_many(
where={"userId": token["userId"]}, include={"user": True}
)
if api_tokens:
return {"success": True, "data": api_tokens}
return {"success": True, "data": api_tokens}

except Exception as e:
logger.error("Error finding api tokens for user {userId}", exc_info=e)

Expand All @@ -68,8 +68,7 @@ async def read_api_token(tokenId: str, token=Depends(JWTBearer())):
api_token = prisma.apitoken.find_unique(
where={"id": tokenId}, include={"user": True}
)
if api_token:
return {"success": True, "data": api_token}
return {"success": True, "data": api_token}
except Exception as e:
logger.error("Cannot find api token {tokenId}", exc_info=e)

Expand Down
1 change: 1 addition & 0 deletions app/lib/models/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
class Agent(BaseModel):
name: str
type: str
description: str = None
avatarUrl: str = None
llm: dict = None
hasMemory: bool = False
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "Agent" ADD COLUMN "description" TEXT;
1 change: 1 addition & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ model Document {

model Agent {
id String @id @default(cuid()) @db.VarChar(255)
description String? @db.Text()
avatarUrl String? @db.Text()
userId String @db.VarChar(255)
user User @relation(fields: [userId], references: [id])
Expand Down
33 changes: 13 additions & 20 deletions ui/app/agents/_components/card.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,7 @@ import relativeTime from "dayjs/plugin/relativeTime";

dayjs.extend(relativeTime);

export default function AgentCard({
id,
name,
description,
createdAt,
onDelete,
}) {
export default function AgentCard({ id, name, createdAt, onDelete }) {
const toast = useToast();

const copyToClipboard = () => {
Expand All @@ -50,21 +44,20 @@ export default function AgentCard({
);

return (
<Stack borderWidth="1px" borderRadius="md" padding={4}>
<HStack justifyContent="space-between" flex={1}>
<Text noOfLines={1} as="b" flex={1}>
{name}
</Text>
<Stack borderWidth="1px" borderRadius="md" padding={4} spacing={4}>
<Stack>
<HStack justifyContent="space-between" flex={1}>
<Text noOfLines={1} as="b" flex={1}>
{name}
</Text>
<Text fontSize="sm" color="gray.500">
{dayjs(createdAt).fromNow()}
</Text>
</HStack>
<Text fontSize="sm" color="gray.500">
{dayjs(createdAt).fromNow()}
{`Id: ${id}`}
</Text>
</HStack>
<Text fontSize="sm" color="gray.500">
{`Id: ${id}`}
</Text>
<Text noOfLines={1} color="gray.500">
{description}
</Text>
</Stack>
<HStack justifyContent="space-between">
<NextLink passHref href={`/agents/${id}`}>
<Button
Expand Down
5 changes: 3 additions & 2 deletions ui/app/agents/new/client-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export default function NewAgentClientPage({ session }) {
has_memory: false,
});

const createAgent = async ({ name, avatarUrl }) => {
const createAgent = async ({ name, description, avatarUrl }) => {
let promptId;
const { type, prompt, llm, has_memory, documents, tools } = data;

Expand All @@ -44,6 +44,7 @@ export default function NewAgentClientPage({ session }) {

const agent = await api.createAgent({
avatarUrl,
description,
name,
type,
llm,
Expand Down Expand Up @@ -158,7 +159,7 @@ export default function NewAgentClientPage({ session }) {
{activeStep === "INFO" && (
<AgentStoreInfo
onSubmit={async ({ name, avatarUrl, description }) => {
await createAgent({ name, avatarUrl });
await createAgent({ name, avatarUrl, description });
}}
/>
)}
Expand Down
206 changes: 136 additions & 70 deletions ui/app/client-page.js
Original file line number Diff line number Diff line change
@@ -1,85 +1,151 @@
"use client";
import { useState } from "react";
import NextLink from "next/link";
import {
Alert,
Container,
HStack,
Button,
Heading,
Link,
Icon,
Stack,
Tag,
Text,
useColorModeValue,
HStack,
SimpleGrid,
Avatar,
} from "@chakra-ui/react";
import dayjs from "dayjs";
import { TbPlayerPlay } from "react-icons/tb";
import relativeTime from "dayjs/plugin/relativeTime";
import SearchBar from "./_components/search-bar";

dayjs.extend(relativeTime);

export default function HomeClientPage() {
function LibraryCard({ id, name, description, createdAt, avatarUrl }) {
return (
<Container maxWidth="3xl" minHeight="100vh">
<Stack
paddingX={[4, 12]}
paddingY={[6, 12]}
spacing={12}
flex={1}
height="100vh"
justifyContent={["flex-start", "center"]}
>
<Alert
variant="outline"
borderColor="orange.500"
borderWidth="1px"
borderRadius="md"
>
Superagent is in public beta, expect rapid updates. All feedback
appreciated.
</Alert>
<Stack>
<HStack>
<Heading as="h1" fontSize="2xl">
Superagent
</Heading>
<Tag size="sm">Beta</Tag>
<Stack borderWidth="1px" borderRadius="md" padding={4} spacing={4}>
<Stack>
<HStack justifyContent="space-between" flex={1}>
<HStack spacing={4}>
<Avatar size="sm" src={avatarUrl || "./logo.png"} />
<Text noOfLines={1} as="b" flex={1}>
{name}
</Text>
</HStack>
<Text>
Superagent is a platform that enables you to create, manage and run
AI Agents in seconds. We are currently in open beta so bare with us.
Make sure the read the documentation on how to integrate Superagent
with your app.
<Text fontSize="sm" color="gray.500">
{dayjs(createdAt).fromNow()}
</Text>
</Stack>
<NextLink passHref href="https://docs.superagent.sh">
<Stack
minHeight="200px"
bgGradient={useColorModeValue(
"linear(to-l, gray.50, gray.200)",
"linear(to-l, gray.600, gray.700)"
)}
justifyContent="flex-end"
padding={8}
borderRadius="lg"
transition="0.2s all"
_hover={{ transform: "scale(1.03)" }}
>
<Stack maxWidth={["full", "60%"]}>
<Heading as="h1" fontSize="2xl">
Documentation
</Heading>
<Text>
Read more on how to get started with integrating Superagent in
your apps here.
</Text>
</Stack>
</Stack>
</NextLink>
<Text>
Contribute on{" "}
<Link
textDecoration="underline"
href="https://github.com/homanp/superagent"
>
Github
</Link>
</HStack>
<Text fontSize="sm" noOfLines={2} color="gray.500">
{description || "No description"}
</Text>
</Stack>
</Container>
<HStack justifyContent="space-between">
<NextLink passHref href={`/agents/${id}`}>
<Button
color="green.500"
fontFamily="mono"
size="sm"
leftIcon={<Icon as={TbPlayerPlay} />}
>
RUN
</Button>
</NextLink>
</HStack>
</Stack>
);
}

export default function HomeClientPage({ data }) {
const [filteredData, setData] = useState();

const handleSearch = ({ searchTerm }) => {
if (!searchTerm) {
setData(data);
}

const keysToFilter = ["name"];
const filteredItems = data.filter((item) =>
keysToFilter.some((key) =>
item[key].toString().toLowerCase().includes(searchTerm.toLowerCase())
)
);

setData(filteredItems);
};

return (
<Stack
paddingX={[6, 12]}
paddingY={12}
spacing={6}
flex={1}
overflow="auto"
>
<HStack justifyContent="space-between">
<Stack>
<Heading as="h1" fontSize="2xl">
Library
</Heading>
<Text color="gray.400" display={["none", "block"]}>
Browse agents made by others
</Text>
</Stack>
</HStack>
<SearchBar
onSearch={(values) => handleSearch(values)}
onReset={() => setData(data)}
/>
<SimpleGrid columns={[1, 2, 2, 4]} gap={6}>
{filteredData
? filteredData?.map(
({
id,
avatarUrl,
description,
llm,
createdAt,
hasMemory,
name,
type,
}) => (
<LibraryCard
avatarUrl={avatarUrl}
key={id}
createdAt={createdAt}
description={description}
id={id}
name={name}
llm={llm}
type={type}
hasMemory={hasMemory}
onDelete={(id) => handleDelete(id)}
/>
)
)
: data?.map(
({
id,
avatarUrl,
description,
llm,
createdAt,
hasMemory,
name,
type,
}) => (
<LibraryCard
avatarUrl={avatarUrl}
key={id}
createdAt={createdAt}
description={description}
id={id}
name={name}
llm={llm}
type={type}
hasMemory={hasMemory}
onDelete={(id) => handleDelete(id)}
/>
)
)}
</SimpleGrid>
</Stack>
);
}
Loading

0 comments on commit 85d1da7

Please sign in to comment.