mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-14 09:38:00 -05:00
Compare commits
43 Commits
fix/creden
...
swiftyos/o
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9cf61aa2d | ||
|
|
0e4d0ce108 | ||
|
|
2f11e9601e | ||
|
|
539d3e0791 | ||
|
|
7a14e5dd66 | ||
|
|
e711c1db4e | ||
|
|
c282d2d912 | ||
|
|
582097221f | ||
|
|
8dacdd16f2 | ||
|
|
04d7feea28 | ||
|
|
3bcd6df193 | ||
|
|
f3c524a74a | ||
|
|
1a08922ccf | ||
|
|
195261835d | ||
|
|
2c473146dd | ||
|
|
311100d26f | ||
|
|
f3319f23ba | ||
|
|
644cff8155 | ||
|
|
d0c4a1f14a | ||
|
|
4d20e419e1 | ||
|
|
6007def168 | ||
|
|
1f82cebb05 | ||
|
|
bc8043b862 | ||
|
|
2a86f22eb4 | ||
|
|
fa5f24eb12 | ||
|
|
37c59990f5 | ||
|
|
783ca12927 | ||
|
|
52598759df | ||
|
|
37e8b51821 | ||
|
|
f051266a33 | ||
|
|
0c4888f15f | ||
|
|
bb8e5622b3 | ||
|
|
46d573c472 | ||
|
|
c027080607 | ||
|
|
9750b79ced | ||
|
|
797f9eda5c | ||
|
|
4f861e3823 | ||
|
|
69747cc891 | ||
|
|
c6daeefa06 | ||
|
|
a7e0af0551 | ||
|
|
6df94aac44 | ||
|
|
6b9580b666 | ||
|
|
44659948e5 |
@@ -1,5 +1,6 @@
|
||||
import logging
|
||||
|
||||
import fastapi
|
||||
import prisma.errors
|
||||
import prisma.fields
|
||||
import prisma.models
|
||||
@@ -8,6 +9,8 @@ import prisma.types
|
||||
import backend.server.model
|
||||
import backend.server.v2.library.model as library_model
|
||||
import backend.server.v2.store.exceptions as store_exceptions
|
||||
import backend.server.v2.store.image_gen as store_image_gen
|
||||
import backend.server.v2.store.media as store_media
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -51,9 +54,11 @@ async def get_library_agents(
|
||||
include={
|
||||
"Agent": {
|
||||
"include": {
|
||||
"AgentNodes": {"include": {"Input": True, "Output": True}}
|
||||
"AgentNodes": {"include": {"Input": True, "Output": True}},
|
||||
"AgentGraphExecution": {"where": {"userId": user_id}},
|
||||
}
|
||||
}
|
||||
},
|
||||
"Creator": True,
|
||||
},
|
||||
order=[{"updatedAt": "desc"}],
|
||||
)
|
||||
@@ -61,7 +66,7 @@ async def get_library_agents(
|
||||
return [library_model.LibraryAgent.from_db(agent) for agent in library_agents]
|
||||
except prisma.errors.PrismaError as e:
|
||||
logger.error(f"Database error fetching library agents: {e}")
|
||||
raise store_exceptions.DatabaseError("Unable to fetch library agents.")
|
||||
raise store_exceptions.DatabaseError("Failed to fetch library agents") from e
|
||||
|
||||
|
||||
async def create_library_agent(
|
||||
@@ -72,6 +77,39 @@ async def create_library_agent(
|
||||
"""
|
||||
|
||||
try:
|
||||
agent = await prisma.models.AgentGraph.prisma().find_unique(
|
||||
where={"id": agent_id, "version": agent_version}
|
||||
)
|
||||
|
||||
if not agent:
|
||||
raise store_exceptions.AgentNotFoundError(
|
||||
f"Agent {agent_id} version {agent_version} not found"
|
||||
)
|
||||
try:
|
||||
# Use .jpeg here since we are generating JPEG images
|
||||
filename = f"agent_{agent_id}.jpeg"
|
||||
|
||||
image_url = await store_media.check_media_exists(user_id, filename)
|
||||
|
||||
if not image_url:
|
||||
# Generate agent image as JPEG
|
||||
image = await store_image_gen.generate_agent_image(agent=agent)
|
||||
|
||||
# Create UploadFile with the correct filename and content_type
|
||||
image_file = fastapi.UploadFile(
|
||||
file=image,
|
||||
filename=filename,
|
||||
)
|
||||
|
||||
image_url = await store_media.upload_media(
|
||||
user_id=user_id, file=image_file, use_file_name=True
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating agent image: {e}")
|
||||
raise store_exceptions.DatabaseError(
|
||||
"Failed to generate agent image"
|
||||
) from e
|
||||
|
||||
return await prisma.models.LibraryAgent.prisma().create(
|
||||
data={
|
||||
"userId": user_id,
|
||||
@@ -79,11 +117,12 @@ async def create_library_agent(
|
||||
"agentVersion": agent_version,
|
||||
"isCreatedByUser": False,
|
||||
"useGraphIsActiveVersion": True,
|
||||
"Creator": {"connect": {"id": agent.userId}},
|
||||
}
|
||||
)
|
||||
except prisma.errors.PrismaError as e:
|
||||
logger.error(f"Database error creating agent to library: {str(e)}")
|
||||
raise store_exceptions.DatabaseError("Failed to create agent to library") from e
|
||||
logger.error(f"Database error creating agent in library: {str(e)}")
|
||||
raise store_exceptions.DatabaseError("Failed to create agent in library") from e
|
||||
|
||||
|
||||
async def update_agent_version_in_library(
|
||||
@@ -164,7 +203,8 @@ async def add_store_agent_to_library(
|
||||
if they don't already have it
|
||||
"""
|
||||
logger.debug(
|
||||
f"Adding agent from store listing version {store_listing_version_id} to library for user {user_id}"
|
||||
f"Adding agent from store listing version #{store_listing_version_id} "
|
||||
f"to library for user #{user_id}"
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -183,11 +223,13 @@ async def add_store_agent_to_library(
|
||||
f"Store listing version {store_listing_version_id} not found"
|
||||
)
|
||||
|
||||
# We need the agent object to be able to check if
|
||||
# the user_id is the same as the agent's user_id
|
||||
agent = store_listing_version.Agent
|
||||
|
||||
if agent.userId == user_id:
|
||||
logger.warning(
|
||||
f"User {user_id} cannot add their own agent to their library"
|
||||
f"User #{user_id} cannot add their own agent to their library"
|
||||
)
|
||||
raise store_exceptions.DatabaseError("Cannot add own agent to library")
|
||||
|
||||
@@ -202,7 +244,7 @@ async def add_store_agent_to_library(
|
||||
|
||||
if existing_user_agent:
|
||||
logger.debug(
|
||||
f"User {user_id} already has agent {agent.id} in their library"
|
||||
f"User #{user_id} already has agent #{agent.id} in their library"
|
||||
)
|
||||
return
|
||||
|
||||
@@ -215,7 +257,7 @@ async def add_store_agent_to_library(
|
||||
"isCreatedByUser": False,
|
||||
}
|
||||
)
|
||||
logger.debug(f"Added agent {agent.id} to library for user {user_id}")
|
||||
logger.debug(f"Added agent #{agent.id} to library for user #{user_id}")
|
||||
|
||||
except store_exceptions.AgentNotFoundError:
|
||||
raise
|
||||
|
||||
@@ -5,7 +5,6 @@ import prisma.models
|
||||
import pytest
|
||||
from prisma import Prisma
|
||||
|
||||
import backend.data.includes
|
||||
import backend.server.v2.library.db as db
|
||||
import backend.server.v2.store.exceptions
|
||||
|
||||
@@ -81,12 +80,10 @@ async def test_get_library_agents(mocker):
|
||||
assert result[0].id == "ua1"
|
||||
assert result[0].name == "Test Agent 2"
|
||||
assert result[0].description == "Test Description 2"
|
||||
assert result[0].is_created_by_user is False
|
||||
assert result[0].is_latest_version is True
|
||||
assert result[0].is_favorite is False
|
||||
assert result[0].agent_id == "agent2"
|
||||
assert result[0].agent_version == 1
|
||||
assert result[0].preset_id is None
|
||||
assert result[0].can_access_graph is False
|
||||
assert result[0].is_latest_version is True
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import datetime
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
|
||||
import prisma.enums
|
||||
import prisma.models
|
||||
import pydantic
|
||||
|
||||
@@ -9,25 +11,40 @@ import backend.data.graph as graph_model
|
||||
import backend.server.model as server_model
|
||||
|
||||
|
||||
class AgentStatus(str, Enum):
|
||||
# The agent has completed all runs
|
||||
COMPLETED = "COMPLETED"
|
||||
# An agent is running, but not all runs have completed
|
||||
HEALTHY = "HEALTHY"
|
||||
# An agent is waiting to start or waiting for another reason
|
||||
WAITING = "WAITING"
|
||||
# An agent is in an error state
|
||||
ERROR = "ERROR"
|
||||
|
||||
|
||||
class LibraryAgent(pydantic.BaseModel):
|
||||
id: str # Changed from agent_id to match GraphMeta
|
||||
|
||||
agent_id: str
|
||||
agent_version: int # Changed from agent_version to match GraphMeta
|
||||
|
||||
preset_id: str | None
|
||||
image_url: str
|
||||
|
||||
creator_name: str # from profile
|
||||
creator_image_url: str # from profile
|
||||
|
||||
status: AgentStatus
|
||||
|
||||
updated_at: datetime.datetime
|
||||
|
||||
name: str
|
||||
description: str
|
||||
name: str # from graph
|
||||
description: str # from graph
|
||||
|
||||
# Made input_schema and output_schema match GraphMeta's type
|
||||
input_schema: dict[str, Any] # Should be BlockIOObjectSubSchema in frontend
|
||||
output_schema: dict[str, Any] # Should be BlockIOObjectSubSchema in frontend
|
||||
|
||||
is_favorite: bool
|
||||
is_created_by_user: bool
|
||||
new_output: bool
|
||||
can_access_graph: bool
|
||||
|
||||
is_latest_version: bool
|
||||
|
||||
@@ -41,6 +58,18 @@ class LibraryAgent(pydantic.BaseModel):
|
||||
agent_updated_at = agent.Agent.updatedAt
|
||||
lib_agent_updated_at = agent.updatedAt
|
||||
|
||||
name = graph.name
|
||||
description = graph.description
|
||||
image_url = agent.image_url if agent.image_url else ""
|
||||
if agent.Creator:
|
||||
creator_name = agent.Creator.name
|
||||
creator_image_url = (
|
||||
agent.Creator.avatarUrl if agent.Creator.avatarUrl else ""
|
||||
)
|
||||
else:
|
||||
creator_name = "Unknown"
|
||||
creator_image_url = ""
|
||||
|
||||
# Take the latest updated_at timestamp either when the graph was updated or the library agent was updated
|
||||
updated_at = (
|
||||
max(agent_updated_at, lib_agent_updated_at)
|
||||
@@ -48,22 +77,56 @@ class LibraryAgent(pydantic.BaseModel):
|
||||
else lib_agent_updated_at
|
||||
)
|
||||
|
||||
# Getting counts as expecting more refined logic for determining status
|
||||
status_counts = {status: 0 for status in prisma.enums.AgentExecutionStatus}
|
||||
new_output = False
|
||||
|
||||
runs_since = datetime.datetime.now(datetime.UTC) - datetime.timedelta(days=7)
|
||||
if not agent.Agent.AgentGraphExecution:
|
||||
status = AgentStatus.COMPLETED
|
||||
else:
|
||||
for execution in agent.Agent.AgentGraphExecution:
|
||||
if runs_since > execution.createdAt:
|
||||
if (
|
||||
execution.executionStatus
|
||||
== prisma.enums.AgentExecutionStatus.COMPLETED
|
||||
):
|
||||
new_output = True
|
||||
status_counts[execution.executionStatus] += 1
|
||||
|
||||
if status_counts[prisma.enums.AgentExecutionStatus.FAILED] > 0:
|
||||
status = AgentStatus.ERROR
|
||||
elif status_counts[prisma.enums.AgentExecutionStatus.QUEUED] > 0:
|
||||
status = AgentStatus.WAITING
|
||||
elif status_counts[prisma.enums.AgentExecutionStatus.RUNNING] > 0:
|
||||
status = AgentStatus.HEALTHY
|
||||
else:
|
||||
status = AgentStatus.COMPLETED
|
||||
|
||||
return LibraryAgent(
|
||||
id=agent.id,
|
||||
agent_id=agent.agentId,
|
||||
agent_version=agent.agentVersion,
|
||||
image_url=image_url,
|
||||
creator_name=creator_name,
|
||||
creator_image_url=creator_image_url,
|
||||
name=name,
|
||||
description=description,
|
||||
status=status,
|
||||
updated_at=updated_at,
|
||||
name=graph.name,
|
||||
description=graph.description,
|
||||
input_schema=graph.input_schema,
|
||||
output_schema=graph.output_schema,
|
||||
is_favorite=agent.isFavorite,
|
||||
is_created_by_user=agent.isCreatedByUser,
|
||||
is_latest_version=graph.is_active,
|
||||
preset_id=agent.AgentPreset.id if agent.AgentPreset else None,
|
||||
new_output=new_output,
|
||||
can_access_graph=agent.Agent.userId == agent.userId,
|
||||
# TODO: work out how to calculate this efficiently
|
||||
is_latest_version=True,
|
||||
)
|
||||
|
||||
|
||||
class LibraryAgentResponse:
|
||||
agents: list[LibraryAgent]
|
||||
pagination: server_model.Pagination
|
||||
|
||||
|
||||
class LibraryAgentPreset(pydantic.BaseModel):
|
||||
id: str
|
||||
updated_at: datetime.datetime
|
||||
|
||||
@@ -3,147 +3,10 @@ import datetime
|
||||
import prisma.fields
|
||||
import prisma.models
|
||||
|
||||
import backend.data.block
|
||||
import backend.server.model
|
||||
import backend.server.v2.library.model
|
||||
import backend.server.v2.library.model as library_model
|
||||
|
||||
|
||||
def test_library_agent():
|
||||
agent = backend.server.v2.library.model.LibraryAgent(
|
||||
id="test-agent-123",
|
||||
agent_id="agent-123",
|
||||
agent_version=1,
|
||||
preset_id=None,
|
||||
updated_at=datetime.datetime.now(),
|
||||
name="Test Agent",
|
||||
description="Test description",
|
||||
input_schema={"type": "object", "properties": {}},
|
||||
output_schema={"type": "object", "properties": {}},
|
||||
is_favorite=False,
|
||||
is_created_by_user=False,
|
||||
is_latest_version=True,
|
||||
)
|
||||
assert agent.id == "test-agent-123"
|
||||
assert agent.agent_id == "agent-123"
|
||||
assert agent.agent_version == 1
|
||||
assert agent.name == "Test Agent"
|
||||
assert agent.description == "Test description"
|
||||
assert agent.is_favorite is False
|
||||
assert agent.is_created_by_user is False
|
||||
assert agent.is_latest_version is True
|
||||
assert agent.input_schema == {"type": "object", "properties": {}}
|
||||
assert agent.output_schema == {"type": "object", "properties": {}}
|
||||
|
||||
|
||||
def test_library_agent_with_user_created():
|
||||
agent = backend.server.v2.library.model.LibraryAgent(
|
||||
id="user-agent-456",
|
||||
agent_id="agent-456",
|
||||
agent_version=2,
|
||||
preset_id=None,
|
||||
updated_at=datetime.datetime.now(),
|
||||
name="User Created Agent",
|
||||
description="An agent created by the user",
|
||||
input_schema={"type": "object", "properties": {}},
|
||||
output_schema={"type": "object", "properties": {}},
|
||||
is_favorite=False,
|
||||
is_created_by_user=True,
|
||||
is_latest_version=True,
|
||||
)
|
||||
assert agent.id == "user-agent-456"
|
||||
assert agent.agent_id == "agent-456"
|
||||
assert agent.agent_version == 2
|
||||
assert agent.name == "User Created Agent"
|
||||
assert agent.description == "An agent created by the user"
|
||||
assert agent.is_favorite is False
|
||||
assert agent.is_created_by_user is True
|
||||
assert agent.is_latest_version is True
|
||||
assert agent.input_schema == {"type": "object", "properties": {}}
|
||||
assert agent.output_schema == {"type": "object", "properties": {}}
|
||||
|
||||
|
||||
def test_library_agent_preset():
|
||||
preset = backend.server.v2.library.model.LibraryAgentPreset(
|
||||
id="preset-123",
|
||||
name="Test Preset",
|
||||
description="Test preset description",
|
||||
agent_id="test-agent-123",
|
||||
agent_version=1,
|
||||
is_active=True,
|
||||
inputs={
|
||||
"dictionary": {"key1": "Hello", "key2": "World"},
|
||||
"selected_value": "key2",
|
||||
},
|
||||
updated_at=datetime.datetime.now(),
|
||||
)
|
||||
assert preset.id == "preset-123"
|
||||
assert preset.name == "Test Preset"
|
||||
assert preset.description == "Test preset description"
|
||||
assert preset.agent_id == "test-agent-123"
|
||||
assert preset.agent_version == 1
|
||||
assert preset.is_active is True
|
||||
assert preset.inputs == {
|
||||
"dictionary": {"key1": "Hello", "key2": "World"},
|
||||
"selected_value": "key2",
|
||||
}
|
||||
|
||||
|
||||
def test_library_agent_preset_response():
|
||||
preset = backend.server.v2.library.model.LibraryAgentPreset(
|
||||
id="preset-123",
|
||||
name="Test Preset",
|
||||
description="Test preset description",
|
||||
agent_id="test-agent-123",
|
||||
agent_version=1,
|
||||
is_active=True,
|
||||
inputs={
|
||||
"dictionary": {"key1": "Hello", "key2": "World"},
|
||||
"selected_value": "key2",
|
||||
},
|
||||
updated_at=datetime.datetime.now(),
|
||||
)
|
||||
|
||||
pagination = backend.server.model.Pagination(
|
||||
total_items=1, total_pages=1, current_page=1, page_size=10
|
||||
)
|
||||
|
||||
response = backend.server.v2.library.model.LibraryAgentPresetResponse(
|
||||
presets=[preset], pagination=pagination
|
||||
)
|
||||
|
||||
assert len(response.presets) == 1
|
||||
assert response.presets[0].id == "preset-123"
|
||||
assert response.pagination.total_items == 1
|
||||
assert response.pagination.total_pages == 1
|
||||
assert response.pagination.current_page == 1
|
||||
assert response.pagination.page_size == 10
|
||||
|
||||
|
||||
def test_create_library_agent_preset_request():
|
||||
request = backend.server.v2.library.model.CreateLibraryAgentPresetRequest(
|
||||
name="New Preset",
|
||||
description="New preset description",
|
||||
agent_id="agent-123",
|
||||
agent_version=1,
|
||||
is_active=True,
|
||||
inputs={
|
||||
"dictionary": {"key1": "Hello", "key2": "World"},
|
||||
"selected_value": "key2",
|
||||
},
|
||||
)
|
||||
|
||||
assert request.name == "New Preset"
|
||||
assert request.description == "New preset description"
|
||||
assert request.agent_id == "agent-123"
|
||||
assert request.agent_version == 1
|
||||
assert request.is_active is True
|
||||
assert request.inputs == {
|
||||
"dictionary": {"key1": "Hello", "key2": "World"},
|
||||
"selected_value": "key2",
|
||||
}
|
||||
|
||||
|
||||
def test_library_agent_from_db():
|
||||
def test_agent_preset_from_db():
|
||||
# Create mock DB agent
|
||||
db_agent = prisma.models.AgentPreset(
|
||||
id="test-agent-123",
|
||||
@@ -167,7 +30,7 @@ def test_library_agent_from_db():
|
||||
)
|
||||
|
||||
# Convert to LibraryAgentPreset
|
||||
agent = backend.server.v2.library.model.LibraryAgentPreset.from_db(db_agent)
|
||||
agent = library_model.LibraryAgentPreset.from_db(db_agent)
|
||||
|
||||
assert agent.id == "test-agent-123"
|
||||
assert agent.agent_version == 1
|
||||
|
||||
@@ -109,8 +109,6 @@ async def execute_preset(
|
||||
if not preset:
|
||||
raise fastapi.HTTPException(status_code=404, detail="Preset not found")
|
||||
|
||||
logger.debug(f"Preset inputs: {preset.inputs}")
|
||||
|
||||
# Merge input overrides with preset inputs
|
||||
merged_node_input = preset.inputs | node_input
|
||||
|
||||
|
||||
@@ -35,29 +35,33 @@ def test_get_library_agents_success(mocker: pytest_mock.MockFixture):
|
||||
id="test-agent-1",
|
||||
agent_id="test-agent-1",
|
||||
agent_version=1,
|
||||
preset_id="preset-1",
|
||||
updated_at=datetime.datetime(2023, 1, 1, 0, 0, 0),
|
||||
is_favorite=False,
|
||||
is_created_by_user=True,
|
||||
is_latest_version=True,
|
||||
name="Test Agent 1",
|
||||
description="Test Description 1",
|
||||
image_url="",
|
||||
creator_name="Test Creator",
|
||||
creator_image_url="",
|
||||
input_schema={"type": "object", "properties": {}},
|
||||
output_schema={"type": "object", "properties": {}},
|
||||
status=library_model.AgentStatus.COMPLETED,
|
||||
new_output=False,
|
||||
can_access_graph=True,
|
||||
is_latest_version=True,
|
||||
updated_at=datetime.datetime(2023, 1, 1, 0, 0, 0),
|
||||
),
|
||||
library_model.LibraryAgent(
|
||||
id="test-agent-2",
|
||||
agent_id="test-agent-2",
|
||||
agent_version=1,
|
||||
preset_id="preset-2",
|
||||
updated_at=datetime.datetime(2023, 1, 1, 0, 0, 0),
|
||||
is_favorite=False,
|
||||
is_created_by_user=False,
|
||||
is_latest_version=True,
|
||||
name="Test Agent 2",
|
||||
description="Test Description 2",
|
||||
image_url="",
|
||||
creator_name="Test Creator",
|
||||
creator_image_url="",
|
||||
input_schema={"type": "object", "properties": {}},
|
||||
output_schema={"type": "object", "properties": {}},
|
||||
status=library_model.AgentStatus.COMPLETED,
|
||||
new_output=False,
|
||||
can_access_graph=False,
|
||||
is_latest_version=True,
|
||||
updated_at=datetime.datetime(2023, 1, 1, 0, 0, 0),
|
||||
),
|
||||
]
|
||||
mock_db_call = mocker.patch("backend.server.v2.library.db.get_library_agents")
|
||||
@@ -71,9 +75,9 @@ def test_get_library_agents_success(mocker: pytest_mock.MockFixture):
|
||||
]
|
||||
assert len(data) == 2
|
||||
assert data[0].agent_id == "test-agent-1"
|
||||
assert data[0].is_created_by_user is True
|
||||
assert data[0].can_access_graph is True
|
||||
assert data[1].agent_id == "test-agent-2"
|
||||
assert data[1].is_created_by_user is False
|
||||
assert data[1].can_access_graph is False
|
||||
mock_db_call.assert_called_once_with("test-user-id")
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ from enum import Enum
|
||||
import replicate
|
||||
import replicate.exceptions
|
||||
import requests
|
||||
from prisma.models import AgentGraph
|
||||
from replicate.helpers import FileOutput
|
||||
|
||||
from backend.data.graph import Graph
|
||||
@@ -21,7 +22,7 @@ class ImageStyle(str, Enum):
|
||||
DIGITAL_ART = "digital art"
|
||||
|
||||
|
||||
async def generate_agent_image(agent: Graph) -> io.BytesIO:
|
||||
async def generate_agent_image(agent: Graph | AgentGraph) -> io.BytesIO:
|
||||
"""
|
||||
Generate an image for an agent using Flux model via Replicate API.
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE "LibraryAgent" ADD COLUMN "creatorId" TEXT,
|
||||
ADD COLUMN "image_url" TEXT;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "LibraryAgent" ADD CONSTRAINT "LibraryAgent_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "Profile"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -65,6 +65,7 @@ model AgentGraph {
|
||||
|
||||
name String?
|
||||
description String?
|
||||
|
||||
isActive Boolean @default(true)
|
||||
isTemplate Boolean @default(false)
|
||||
|
||||
@@ -173,6 +174,8 @@ model LibraryAgent {
|
||||
userId String
|
||||
User User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
|
||||
image_url String?
|
||||
|
||||
agentId String
|
||||
agentVersion Int
|
||||
Agent AgentGraph @relation(fields: [agentId, agentVersion], references: [id, version])
|
||||
@@ -180,6 +183,9 @@ model LibraryAgent {
|
||||
agentPresetId String?
|
||||
AgentPreset AgentPreset? @relation(fields: [agentPresetId], references: [id])
|
||||
|
||||
creatorId String?
|
||||
Creator Profile? @relation(fields: [creatorId], references: [id])
|
||||
|
||||
useGraphIsActiveVersion Boolean @default(false)
|
||||
|
||||
isFavorite Boolean @default(false)
|
||||
@@ -477,6 +483,8 @@ model Profile {
|
||||
|
||||
isFeatured Boolean @default(false)
|
||||
|
||||
LibraryAgent LibraryAgent[]
|
||||
|
||||
@@index([username])
|
||||
@@index([userId])
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ async def test_execute_preset_with_clash(server: SpinTestServer):
|
||||
)
|
||||
|
||||
# Verify execution
|
||||
assert result is not None
|
||||
assert result is not None, "Result must not be None"
|
||||
graph_exec_id = result["id"]
|
||||
|
||||
# Wait for execution to complete
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export default function Page() {
|
||||
// Redirects to marketplace
|
||||
redirect("/marketplace");
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@ import {
|
||||
TransactionHistory,
|
||||
User,
|
||||
UserPasswordCredentials,
|
||||
LibraryAgentResponse,
|
||||
LibraryAgentPresetResponse,
|
||||
CreateLibraryAgentPresetRequest,
|
||||
LibraryAgent,
|
||||
LibraryAgentPreset,
|
||||
AgentStatus,
|
||||
} from "./types";
|
||||
import { createBrowserClient } from "@supabase/ssr";
|
||||
import getServerSupabase from "../supabase/getServerSupabase";
|
||||
@@ -443,7 +449,7 @@ export default class BackendAPI {
|
||||
/////////// V2 LIBRARY API //////////////
|
||||
/////////////////////////////////////////
|
||||
|
||||
async listLibraryAgents(): Promise<GraphMeta[]> {
|
||||
async listLibraryAgents(): Promise<LibraryAgentResponse> {
|
||||
return this._get("/library/agents");
|
||||
}
|
||||
|
||||
@@ -451,6 +457,59 @@ export default class BackendAPI {
|
||||
await this._request("POST", `/library/agents/${storeListingVersionId}`);
|
||||
}
|
||||
|
||||
async updateLibraryAgent(
|
||||
libraryAgentId: string,
|
||||
params: {
|
||||
auto_update_version?: boolean;
|
||||
is_favorite?: boolean;
|
||||
is_archived?: boolean;
|
||||
is_deleted?: boolean;
|
||||
},
|
||||
): Promise<void> {
|
||||
await this._request("PUT", `/library/agents/${libraryAgentId}`, params);
|
||||
}
|
||||
|
||||
async listLibraryAgentPresets(params?: {
|
||||
page?: number;
|
||||
page_size?: number;
|
||||
}): Promise<LibraryAgentPresetResponse> {
|
||||
return this._get("/library/presets", params);
|
||||
}
|
||||
|
||||
async getLibraryAgentPreset(presetId: string): Promise<LibraryAgentPreset> {
|
||||
return this._get(`/library/presets/${presetId}`);
|
||||
}
|
||||
|
||||
async createLibraryAgentPreset(
|
||||
preset: CreateLibraryAgentPresetRequest,
|
||||
): Promise<LibraryAgentPreset> {
|
||||
return this._request("POST", "/library/presets", preset);
|
||||
}
|
||||
|
||||
async updateLibraryAgentPreset(
|
||||
presetId: string,
|
||||
preset: CreateLibraryAgentPresetRequest,
|
||||
): Promise<LibraryAgentPreset> {
|
||||
return this._request("PUT", `/library/presets/${presetId}`, preset);
|
||||
}
|
||||
|
||||
async deleteLibraryAgentPreset(presetId: string): Promise<void> {
|
||||
await this._request("DELETE", `/library/presets/${presetId}`);
|
||||
}
|
||||
|
||||
async executeLibraryAgentPreset(
|
||||
presetId: string,
|
||||
graphId: string,
|
||||
graphVersion: number,
|
||||
nodeInput: { [key: string]: any },
|
||||
): Promise<{ id: string }> {
|
||||
return this._request("POST", `/library/presets/${presetId}/execute`, {
|
||||
graph_id: graphId,
|
||||
graph_version: graphVersion,
|
||||
node_input: nodeInput,
|
||||
});
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
/////////// INTERNAL FUNCTIONS ////////////
|
||||
//////////////////////////////??///////////
|
||||
|
||||
@@ -589,3 +589,65 @@ export interface TransactionHistory {
|
||||
transactions: CreditTransaction[];
|
||||
next_transaction_time: Date | null;
|
||||
}
|
||||
|
||||
export enum AgentStatus {
|
||||
COMPLETED = "COMPLETED",
|
||||
HEALTHY = "HEALTHY",
|
||||
WAITING = "WAITING",
|
||||
ERROR = "ERROR",
|
||||
}
|
||||
|
||||
export interface LibraryAgent {
|
||||
id: string;
|
||||
agent_id: string;
|
||||
agent_version: number;
|
||||
image_url: string;
|
||||
creator_name: string;
|
||||
creator_image_url: string;
|
||||
status: AgentStatus;
|
||||
updated_at: Date;
|
||||
name: string;
|
||||
description: string;
|
||||
input_schema: { [key: string]: any };
|
||||
new_output: boolean;
|
||||
can_access_graph: boolean;
|
||||
is_latest_version: boolean;
|
||||
}
|
||||
|
||||
export interface LibraryAgentResponse {
|
||||
agents: LibraryAgent[];
|
||||
pagination: {
|
||||
total: number;
|
||||
page: number;
|
||||
size: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface LibraryAgentPreset {
|
||||
id: string;
|
||||
updated_at: Date;
|
||||
agent_id: string;
|
||||
agent_version: number;
|
||||
name: string;
|
||||
description: string;
|
||||
is_active: boolean;
|
||||
inputs: { [key: string]: any };
|
||||
}
|
||||
|
||||
export interface LibraryAgentPresetResponse {
|
||||
presets: LibraryAgentPreset[];
|
||||
pagination: {
|
||||
total: number;
|
||||
page: number;
|
||||
size: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface CreateLibraryAgentPresetRequest {
|
||||
name: string;
|
||||
description: string;
|
||||
inputs: { [key: string]: any };
|
||||
agent_id: string;
|
||||
agent_version: number;
|
||||
is_active: boolean;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user