Skip to content

Commit

Permalink
Added featured agents funcitonality
Browse files Browse the repository at this point in the history
  • Loading branch information
Swiftyos committed Aug 2, 2024
1 parent 5c31ae4 commit 5865700
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 2 deletions.
2 changes: 1 addition & 1 deletion rnd/autogpt_builder/src/lib/marketplace-api/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class MarketplaceAPI {
pageSize: number = 10
): Promise<AgentListResponse> {
return this._get(
`/agents/top-downloads/agents?page=${page}&page_size=${pageSize}`
`/agents/featured/agents?page=${page}&page_size=${pageSize}`
);
}

Expand Down
2 changes: 1 addition & 1 deletion rnd/market/market/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
import fastapi.middleware.cors
import fastapi.middleware.gzip
import prisma
import prometheus_fastapi_instrumentator
import sentry_sdk
import sentry_sdk.integrations.asyncio
import sentry_sdk.integrations.fastapi
import sentry_sdk.integrations.starlette
import prometheus_fastapi_instrumentator

import market.routes.admin
import market.routes.agents
Expand Down
103 changes: 103 additions & 0 deletions rnd/market/market/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ class TopAgentsDBResponse(pydantic.BaseModel):
total_pages: int


class FeaturedAgentResponse(pydantic.BaseModel):
"""
Represents a response containing a list of featured agents.
Attributes:
featured_agents (list[FeaturedAgent]): The list of featured agents.
total_count (int): The total count of featured agents.
page (int): The current page number.
page_size (int): The number of agents per page.
total_pages (int): The total number of pages.
"""

featured_agents: list[prisma.models.FeaturedAgent]
total_count: int
page: int
page_size: int
total_pages: int


async def create_agent_entry(
name: str,
description: str,
Expand Down Expand Up @@ -335,3 +354,87 @@ async def get_top_agents_by_downloads(
except Exception as e:
# Catch any other unexpected exceptions
raise AgentQueryError(f"Unexpected error occurred: {str(e)}") from e


async def set_agent_featured(
agent_id: str, is_featured: bool = True, category: str = "featured"
):
"""Set an agent as featured in the database.
Args:
agent_id (str): The ID of the agent.
category (str, optional): The category to set the agent as featured. Defaults to "featured".
Raises:
AgentQueryError: If there is an error setting the agent as featured.
"""
try:
agent = await prisma.models.Agents.prisma().find_unique(where={"id": agent_id})
if not agent:
raise AgentQueryError(f"Agent with ID {agent_id} not found.")

await prisma.models.FeaturedAgent.prisma().upsert(
where={"agentId": agent_id},
data={
"update": {"category": category, "is_featured": is_featured},
"create": {
"category": category,
"is_featured": is_featured,
"agent": {"connect": {"id": agent_id}},
},
},
)

except prisma.errors.PrismaError as e:
raise AgentQueryError(f"Database query failed: {str(e)}")
except Exception as e:
raise AgentQueryError(f"Unexpected error occurred: {str(e)}")


async def get_featured_agents(
category: str = "featured", page: int = 1, page_size: int = 10
) -> FeaturedAgentResponse:
"""Retrieve a list of featured agents from the database based on the provided category.
Args:
category (str, optional): The category of featured agents to retrieve. Defaults to "featured".
page (int, optional): The page number to retrieve. Defaults to 1.
page_size (int, optional): The number of agents per page. Defaults to 10.
Returns:
dict: A dictionary containing the list of featured agents, total count, current page number, page size, and total number of pages.
"""
try:
# Calculate pagination
skip = (page - 1) * page_size

# Execute the query
try:
featured_agents = await prisma.models.FeaturedAgent.prisma().find_many(
where={"category": category, "is_featured": True},
include={"agent": {"include": {"AnalyticsTracker": True}}},
skip=skip,
take=page_size,
)
except prisma.errors.PrismaError as e:
raise AgentQueryError(f"Database query failed: {str(e)}")

# Get total count for pagination info
total_count = len(featured_agents)

return FeaturedAgentResponse(
featured_agents=featured_agents,
total_count=total_count,
page=page,
page_size=page_size,
total_pages=(total_count + page_size - 1) // page_size,
)

except AgentQueryError as e:
# Log the error or handle it as needed
raise e from e
except ValueError as e:
raise AgentQueryError(f"Invalid input parameter: {str(e)}") from e
except Exception as e:
# Catch any other unexpected exceptions
raise AgentQueryError(f"Unexpected error occurred: {str(e)}") from e
32 changes: 32 additions & 0 deletions rnd/market/market/routes/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,35 @@ async def create_agent_entry(request: market.model.AddAgentRequest):
raise fastapi.HTTPException(status_code=500, detail=str(e))
except Exception as e:
raise fastapi.HTTPException(status_code=500, detail=str(e))


@router.post("/agent/featured/{agent_id}")
async def set_agent_featured(agent_id: str, category: str = "featured"):
"""
A basic endpoint to set an agent as featured in the database.
"""
try:
await market.db.set_agent_featured(
agent_id, is_featured=True, category=category
)
return fastapi.responses.Response(status_code=200)
except market.db.AgentQueryError as e:
raise fastapi.HTTPException(status_code=500, detail=str(e))
except Exception as e:
raise fastapi.HTTPException(status_code=500, detail=str(e))


@router.delete("/agent/featured/{agent_id}")
async def unset_agent_featured(agent_id: str, category: str = "featured"):
"""
A basic endpoint to unset an agent as featured in the database.
"""
try:
await market.db.set_agent_featured(
agent_id, is_featured=False, category=category
)
return fastapi.responses.Response(status_code=200)
except market.db.AgentQueryError as e:
raise fastapi.HTTPException(status_code=500, detail=str(e))
except Exception as e:
raise fastapi.HTTPException(status_code=500, detail=str(e))
75 changes: 75 additions & 0 deletions rnd/market/market/routes/agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,78 @@ async def top_agents_by_downloads(
raise fastapi.HTTPException(
status_code=500, detail=f"An unexpected error occurred: {e}"
) from e


@router.get("/featured/agents", response_model=market.model.AgentListResponse)
async def get_featured_agents(
category: str = fastapi.Query(
"featured", description="Category of featured agents"
),
page: int = fastapi.Query(1, ge=1, description="Page number"),
page_size: int = fastapi.Query(
10, ge=1, le=100, description="Number of items per page"
),
):
"""
Retrieve a list of featured agents based on the provided category.
Args:
category (str): Category of featured agents (default: "featured").
page (int): Page number (default: 1).
page_size (int): Number of items per page (default: 10, min: 1, max: 100).
Returns:
market.model.AgentListResponse: A response containing the list of featured agents and pagination information.
Raises:
HTTPException: If there is a client error (status code 400) or an unexpected error (status code 500).
"""
try:
result = await market.db.get_featured_agents(
category=category,
page=page,
page_size=page_size,
)

ret = market.model.AgentListResponse(
total_count=result.total_count,
page=result.page,
page_size=result.page_size,
total_pages=result.total_pages,
agents=[
market.model.AgentResponse(
id=item.agent.id,
name=item.agent.name,
description=item.agent.description,
author=item.agent.author,
keywords=item.agent.keywords,
categories=item.agent.categories,
version=item.agent.version,
createdAt=item.agent.createdAt,
updatedAt=item.agent.updatedAt,
views=(
item.agent.AnalyticsTracker[0].views
if item.agent.AnalyticsTracker
and len(item.agent.AnalyticsTracker) > 0
else 0
),
downloads=(
item.agent.AnalyticsTracker[0].downloads
if item.agent.AnalyticsTracker
and len(item.agent.AnalyticsTracker) > 0
else 0
),
)
for item in result.featured_agents
if item.agent is not None
],
)

return ret

except market.db.AgentQueryError as e:
raise fastapi.HTTPException(status_code=400, detail=str(e)) from e
except Exception as e:
raise fastapi.HTTPException(
status_code=500, detail=f"An unexpected error occurred: {e}"
) from e
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-- CreateTable
CREATE TABLE "FeaturedAgent" (
"id" UUID NOT NULL DEFAULT gen_random_uuid(),
"agentId" UUID NOT NULL,
"is_featured" BOOLEAN NOT NULL,
"category" TEXT NOT NULL DEFAULT 'featured',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,

CONSTRAINT "FeaturedAgent_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "FeaturedAgent_id_key" ON "FeaturedAgent"("id");

-- CreateIndex
CREATE UNIQUE INDEX "FeaturedAgent_agentId_key" ON "FeaturedAgent"("agentId");

-- AddForeignKey
ALTER TABLE "FeaturedAgent" ADD CONSTRAINT "FeaturedAgent_agentId_fkey" FOREIGN KEY ("agentId") REFERENCES "Agents"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
12 changes: 12 additions & 0 deletions rnd/market/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ model Agents {
graph Json
AnalyticsTracker AnalyticsTracker[]
FeaturedAgent FeaturedAgent?
@@id(name: "graphVersionId", [id, version])
}
Expand All @@ -39,3 +40,14 @@ model AnalyticsTracker {
views Int
downloads Int
}

model FeaturedAgent {
id String @id @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid
agentId String @unique @db.Uuid
agent Agents @relation(fields: [agentId], references: [id])
is_featured Boolean
category String @default("featured")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

0 comments on commit 5865700

Please sign in to comment.