Skip to content

Commit

Permalink
Merge pull request #1994 from Agenta-AI/feature/age-540-endpoint-for-…
Browse files Browse the repository at this point in the history
…app-type

[Enhancement]:  Add 'app_type' column for AppDB model with updated API responses
  • Loading branch information
jp-agenta authored Nov 22, 2024
2 parents 910c0d0 + 9d303da commit 3a40c8b
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session

from agenta_backend.models.deprecated_models import ProjectScopedAppDB as AppDB
from agenta_backend.models.db_models import (
ProjectDB,
AppDB,
AppVariantDB,
AppVariantRevisionsDB,
VariantBaseDB,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""Added the 'app_type' column to the 'app_db' table
Revision ID: 0f086ebc2f82
Revises: 78cde3fc549c
Create Date: 2024-09-09 10:11:05.429116
"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision: str = "0f086ebc2f82"
down_revision: Union[str, None] = "847972cfa14a"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###

# Create the enum type first
app_enumtype = sa.Enum(
"CHAT_TEMPLATE",
"COMPLETION_TEMPLATE",
"CUSTOM",
name="app_enumtype",
)
app_enumtype.create(op.get_bind(), checkfirst=True)

# Then add the column using the enum type
op.add_column(
"app_db",
sa.Column(
"app_type",
app_enumtype,
nullable=True,
),
)
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###

# Drop the column first
op.drop_column("app_db", "app_type")

# Then drop the enum type
app_enumtype = sa.Enum(
"CHAT_TEMPLATE",
"COMPLETION_TEMPLATE",
"CUSTOM",
name="app_enumtype",
)
app_enumtype.drop(op.get_bind(), checkfirst=True)
# ### end Alembic commands ###
1 change: 1 addition & 0 deletions agenta-backend/agenta_backend/models/api/api_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ class URI(BaseModel):
class App(BaseModel):
app_id: str
app_name: str
app_type: Optional[str] = None
updated_at: str


Expand Down
4 changes: 2 additions & 2 deletions agenta-backend/agenta_backend/models/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@
"""

import uuid
import json
import logging
from typing import List, Tuple, Any

from agenta_backend.services import db_manager
from agenta_backend.utils.common import isCloudEE
from agenta_backend.models.api.user_models import User
from agenta_backend.models.shared_models import ConfigDB
from agenta_backend.models.shared_models import ConfigDB, AppType
from agenta_backend.models.api.evaluation_model import (
CorrectAnswer,
Evaluation,
Expand Down Expand Up @@ -433,6 +432,7 @@ def app_db_to_pydantic(app_db: AppDB) -> App:
return App(
app_name=app_db.app_name,
app_id=str(app_db.id),
app_type=AppType.friendly_tag(app_db.app_type),
updated_at=str(app_db.updated_at),
)

Expand Down
3 changes: 2 additions & 1 deletion agenta-backend/agenta_backend/models/db_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from sqlalchemy.dialects.postgresql import UUID, JSONB

from agenta_backend.dbs.postgres.shared.base import Base
from agenta_backend.models.shared_models import TemplateType
from agenta_backend.models.shared_models import TemplateType, AppType


CASCADE_ALL_DELETE = "all, delete-orphan"
Expand Down Expand Up @@ -106,6 +106,7 @@ class AppDB(Base):
nullable=False,
)
app_name = Column(String)
app_type = Column(Enum(AppType, name="app_enumtype"), nullable=True)
project_id = Column(
UUID(as_uuid=True), ForeignKey("projects.id", ondelete="CASCADE")
)
Expand Down
17 changes: 17 additions & 0 deletions agenta-backend/agenta_backend/models/deprecated_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@
DeprecatedBase = declarative_base()


class ProjectScopedAppDB(DeprecatedBase):
__tablename__ = "app_db"
__table_args__ = {"extend_existing": True}

id = Column(
UUID(as_uuid=True),
primary_key=True,
default=uuid.uuid7,
unique=True,
nullable=False,
)
app_name = Column(String)
project_id = Column(
UUID(as_uuid=True), ForeignKey("projects.id", ondelete="CASCADE")
)


class DeprecatedAppDB(DeprecatedBase):
__tablename__ = "app_db"
__table_args__ = {"extend_existing": True}
Expand Down
15 changes: 15 additions & 0 deletions agenta-backend/agenta_backend/models/shared_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,18 @@ class HumanEvaluationScenarioOutput(BaseModel):
class TemplateType(enum.Enum):
IMAGE = "image"
ZIP = "zip"


class AppType(str, enum.Enum):
CHAT_TEMPLATE = "TEMPLATE:simple_chat"
COMPLETION_TEMPLATE = "TEMPLATE:simple_completion"
CUSTOM = "CUSTOM"

@classmethod
def friendly_tag(cls, app_type: str):
mappings = {
cls.CHAT_TEMPLATE: "chat",
cls.COMPLETION_TEMPLATE: "completion",
cls.CUSTOM: "custom",
}
return mappings.get(app_type, None)
25 changes: 13 additions & 12 deletions agenta-backend/agenta_backend/routers/app_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,31 +527,32 @@ async def create_app_and_variant_from_template(
)

logger.debug(
"Step 5: Creating new app and initializing environments"
"Step 5: Retrieve template from db"
if isCloudEE()
else "Step 2: Creating new app and initializing environments"
else "Step 2: Retrieve template from db"
)
template_db = await db_manager.get_template(payload.template_id)

logger.debug(
"Step 6: Creating new app and initializing environments"
if isCloudEE()
else "Step 3: Creating new app and initializing environments"
)
if app is None:
app = await db_manager.create_app_and_envs(
app_name,
app_name=app_name,
template_id=str(template_db.id),
project_id=payload.project_id or request.state.project_id,
workspace_id=payload.workspace_id,
)

logger.debug(
"Step 6: Retrieve template from db"
if isCloudEE()
else "Step 3: Retrieve template from db"
)
template_db = await db_manager.get_template(payload.template_id)
repo_name = os.environ.get("AGENTA_TEMPLATE_REPO", "agentaai/templates_v2")
image_name = f"{repo_name}:{template_db.name}"

logger.debug(
"Step 7: Creating image instance and adding variant based on image"
if isCloudEE()
else "Step 4: Creating image instance and adding variant based on image"
)
repo_name = os.environ.get("AGENTA_TEMPLATE_REPO", "agentaai/templates_v2")
image_name = f"{repo_name}:{template_db.name}"
app_variant_db = await app_manager.add_variant_based_on_image(
app=app,
project_id=str(app.project_id),
Expand Down
34 changes: 32 additions & 2 deletions agenta-backend/agenta_backend/services/db_manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import uuid
import logging
from enum import Enum
from pathlib import Path
from urllib.parse import urlparse
from typing import Any, Dict, List, Optional, Tuple
Expand Down Expand Up @@ -77,6 +78,7 @@

from agenta_backend.models.shared_models import (
Result,
AppType,
ConfigDB,
TemplateType,
CorrectAnswer,
Expand Down Expand Up @@ -703,14 +705,39 @@ async def create_deployment(
raise Exception(f"Error while creating deployment: {e}")


async def get_app_type_from_template_by_id(template_id: Optional[str]) -> str:
"""Get the application type from the specified template.
Args:
template_id (Optional[str]): The ID of the template
Returns:
AppType (str): The determined application type. Defaults to AppType.CUSTOM.
"""

if template_id is None:
return AppType.CUSTOM

template_db = await get_template(template_id=template_id)
if "Completion Prompt" in template_db.title:
return AppType.COMPLETION_TEMPLATE
elif "Chat Prompt" in template_db.title:
return AppType.CHAT_TEMPLATE
return AppType.CUSTOM


async def create_app_and_envs(
app_name: str, project_id: Optional[str] = None, workspace_id: Optional[str] = None
app_name: str,
template_id: Optional[str] = None,
project_id: Optional[str] = None,
workspace_id: Optional[str] = None,
) -> AppDB:
"""
Create a new app with the given name and organization ID.
Args:
app_name (str): The name of the app to create.
template_id (str): The ID of the template.
project_id (str): The ID of the project.
Returns:
Expand All @@ -730,8 +757,11 @@ async def create_app_and_envs(
if app is not None:
raise ValueError("App with the same name already exists")

app_type = await get_app_type_from_template_by_id(template_id=template_id)
async with engine.session() as session:
app = AppDB(app_name=app_name, project_id=uuid.UUID(project_id))
app = AppDB(
app_name=app_name, project_id=uuid.UUID(project_id), app_type=app_type
)

session.add(app)
await session.commit()
Expand Down
2 changes: 1 addition & 1 deletion agenta-cli/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "agenta"
version = "0.27.7a0"
version = "0.27.7a1"
description = "The SDK for agenta is an open-source LLMOps platform."
readme = "README.md"
authors = ["Mahmoud Mabrouk <mahmoud@agenta.ai>"]
Expand Down
2 changes: 1 addition & 1 deletion agenta-web/src/components/AppSelector/AppCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const AppCard: React.FC<{
<div data-cy="app-card-link" className={classes.app_card_link}>
<div>
<Text>Type</Text>
<Tag className="mr-0">Template</Tag>
<Tag className="mr-0">{app.app_type}</Tag>
</div>
<div>
<Text>Last modified:</Text>
Expand Down
1 change: 1 addition & 0 deletions agenta-web/src/lib/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type TestsetCreationMode = "create" | "clone" | "rename"
export interface ListAppsItem {
app_id: string
app_name: string
app_type?: string
updated_at: string
}

Expand Down

0 comments on commit 3a40c8b

Please sign in to comment.