fix(platform): Make LibraryAgent image as initial StoreListing image (#9610)

### Changes 🏗️

We've been auto-generating the thumbnail image for the agent in the
library, this PR is propagating that image as an initial image for the
store listing. This PR also removes the fetch all query for getting the
count for paginating library agent.

### 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] Create an library agent and try to create a store listing.

<img width="1409" alt="image"
src="https://github.com/user-attachments/assets/dc86dc97-a33f-4336-ab90-19a53c6f7e0f"
/>
This commit is contained in:
Zamil Majdy
2025-03-12 12:17:38 +07:00
committed by GitHub
parent f37d4c2659
commit af65058bb7
7 changed files with 30 additions and 37 deletions

View File

@@ -1,4 +1,3 @@
import asyncio
import logging
from typing import Optional
@@ -186,12 +185,7 @@ async def add_generated_agent_image(
try:
if not (image_url := await store_media.check_media_exists(user_id, filename)):
# Generate agent image as JPEG
if config.use_agent_image_generation_v2:
image = await asyncio.to_thread(
store_image_gen.generate_agent_image_v2, graph=graph
)
else:
image = await store_image_gen.generate_agent_image(agent=graph)
image = await store_image_gen.generate_agent_image(graph)
# Create UploadFile with the correct filename and content_type
image_file = fastapi.UploadFile(file=image, filename=filename)

View File

@@ -706,36 +706,24 @@ async def get_my_agents(
logger.debug(f"Getting my agents for user {user_id}, page={page}")
try:
agents_with_max_version = await prisma.models.AgentGraph.prisma().find_many(
where=prisma.types.AgentGraphWhereInput(
userId=user_id, StoreListing={"none": {"isDeleted": False}}
),
order=[{"version": "desc"}],
distinct=["id"],
search_filter = prisma.types.LibraryAgentWhereInput(
userId=user_id,
Agent={"is": {"StoreListing": {"none": {"isDeleted": False}}}},
isArchived=False,
isDeleted=False,
)
library_agents = await prisma.models.LibraryAgent.prisma().find_many(
where=search_filter,
order=[{"agentVersion": "desc"}],
skip=(page - 1) * page_size,
take=page_size,
include={"Agent": True},
)
# store_listings = await prisma.models.StoreListing.prisma().find_many(
# where=prisma.types.StoreListingWhereInput(
# isDeleted=False,
# ),
# )
total = len(
await prisma.models.AgentGraph.prisma().find_many(
where=prisma.types.AgentGraphWhereInput(
userId=user_id, StoreListing={"none": {"isDeleted": False}}
),
order=[{"version": "desc"}],
distinct=["id"],
)
)
total = await prisma.models.LibraryAgent.prisma().count(where=search_filter)
total_pages = (total + page_size - 1) // page_size
agents = agents_with_max_version
my_agents = [
backend.server.v2.store.model.MyAgent(
agent_id=agent.id,
@@ -743,8 +731,10 @@ async def get_my_agents(
agent_name=agent.name or "",
last_edited=agent.updatedAt or agent.createdAt,
description=agent.description or "",
agent_image=entry.imageUrl,
)
for agent in agents
for entry in library_agents
if (agent := entry.Agent)
]
return backend.server.v2.store.model.MyAgentsResponse(

View File

@@ -1,3 +1,4 @@
import asyncio
import io
import logging
from enum import Enum
@@ -34,6 +35,13 @@ class ImageStyle(str, Enum):
DIGITAL_ART = "digital art"
async def generate_agent_image(agent: Graph | AgentGraph) -> io.BytesIO:
if settings.config.use_agent_image_generation_v2:
return await asyncio.to_thread(generate_agent_image_v2, graph=agent)
else:
return await generate_agent_image_v1(agent=agent)
def generate_agent_image_v2(graph: Graph | AgentGraph) -> io.BytesIO:
"""
Generate an image for an agent using Ideogram model.
@@ -91,7 +99,7 @@ def generate_agent_image_v2(graph: Graph | AgentGraph) -> io.BytesIO:
return io.BytesIO(requests.get(url).content)
async def generate_agent_image(agent: Graph | AgentGraph) -> io.BytesIO:
async def generate_agent_image_v1(agent: Graph | AgentGraph) -> io.BytesIO:
"""
Generate an image for an agent using Flux model via Replicate API.

View File

@@ -24,6 +24,7 @@ class MyAgent(pydantic.BaseModel):
agent_id: str
agent_version: int
agent_name: str
agent_image: str | None = None
description: str
last_edited: datetime.datetime

View File

@@ -30,7 +30,6 @@ export const PublishAgentSelect: React.FC<PublishAgentSelectProps> = ({
onClose,
onOpenBuilder,
}) => {
const [selectedAgent, setSelectedAgent] = React.useState<string | null>(null);
const [selectedAgentId, setSelectedAgentId] = React.useState<string | null>(
null,
);
@@ -43,7 +42,6 @@ export const PublishAgentSelect: React.FC<PublishAgentSelectProps> = ({
agentId: string,
agentVersion: number,
) => {
setSelectedAgent(agentName);
setSelectedAgentId(agentId);
setSelectedAgentVersion(agentVersion);
onSelect(agentId, agentVersion);

View File

@@ -130,7 +130,7 @@ export const PublishAgentPopout: React.FC<PublishAgentPopoutProps> = ({
title: name,
subheader: "",
description: description,
thumbnailSrc: "",
thumbnailSrc: selectedAgentData?.agent_image || "",
youtubeLink: "",
category: "",
slug: name.replace(/ /g, "-"),
@@ -222,7 +222,8 @@ export const PublishAgentPopout: React.FC<PublishAgentPopoutProps> = ({
id: agent.agent_id,
version: agent.agent_version,
lastEdited: agent.last_edited,
imageSrc: "https://picsum.photos/300/200", // Fallback image if none provided
imageSrc:
agent.agent_image || "https://picsum.photos/300/200",
})) || []
}
onSelect={handleAgentSelect}

View File

@@ -649,6 +649,7 @@ export type MyAgent = {
agent_id: GraphID;
agent_version: number;
agent_name: string;
agent_image: string | null;
last_edited: string;
description: string;
};