Skip to content

Commit

Permalink
v2.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ashpreetbedi committed Jan 17, 2024
1 parent 4e9ccae commit 5ef08a6
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 61 deletions.
2 changes: 1 addition & 1 deletion phi/assistant/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from phi.assistant.assistant import Assistant, AssistantRow, AssistantMemory, AssistantStorage, KnowledgeBase
from phi.assistant.assistant import Assistant, AssistantRun, AssistantMemory, AssistantStorage, KnowledgeBase
72 changes: 36 additions & 36 deletions phi/assistant/assistant.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from pydantic import BaseModel, ConfigDict, field_validator, Field, ValidationError

from phi.assistant.row import AssistantRow
from phi.assistant.run import AssistantRun
from phi.knowledge.base import KnowledgeBase
from phi.llm.base import LLM
from phi.llm.openai import OpenAIChat
Expand Down Expand Up @@ -57,8 +57,8 @@ class Assistant(BaseModel):

# -*- Assistant Storage
storage: Optional[AssistantStorage] = None
# AssistantRow from the database: DO NOT SET MANUALLY
row: Optional[AssistantRow] = None
# AssistantRun from the database: DO NOT SET MANUALLY
db_row: Optional[AssistantRun] = None

# -*- Assistant Knowledge Base
knowledge_base: Optional[KnowledgeBase] = None
Expand Down Expand Up @@ -209,10 +209,10 @@ def llm_task(self) -> LLMTask:
)
return _llm_task

def to_database_row(self) -> AssistantRow:
"""Create a AssistantRow for the current Assistant (to save to the database)"""
def to_database_row(self) -> AssistantRun:
"""Create a AssistantRun for the current Assistant (to save to the database)"""

return AssistantRow(
return AssistantRun(
name=self.name,
run_id=self.run_id,
run_name=self.run_name,
Expand All @@ -225,8 +225,8 @@ def to_database_row(self) -> AssistantRow:
task_data=self.task_data,
)

def from_database_row(self, row: AssistantRow):
"""Load the existing Assistant from an AssistantRow (from the database)"""
def from_database_row(self, row: AssistantRun):
"""Load the existing Assistant from an AssistantRun (from the database)"""

# Values that are overwritten from the database if they are not set in the assistant
if self.name is None and row.name is not None:
Expand All @@ -238,7 +238,7 @@ def from_database_row(self, row: AssistantRow):
if self.user_id is None and row.user_id is not None:
self.user_id = row.user_id

# Update llm data from the AssistantRow
# Update llm data from the AssistantRun
if row.llm is not None:
# Update llm metrics from the database
llm_metrics_from_db = row.llm.get("metrics")
Expand All @@ -248,7 +248,7 @@ def from_database_row(self, row: AssistantRow):
except Exception as e:
logger.warning(f"Failed to load llm metrics: {e}")

# Update assistant memory from the AssistantRow
# Update assistant memory from the AssistantRun
if row.memory is not None:
try:
self.memory = self.memory.__class__.model_validate(row.memory)
Expand All @@ -260,7 +260,7 @@ def from_database_row(self, row: AssistantRow):
# If assistant_data is set in the assistant, merge it with the database assistant_data.
# The assistant assistant_data takes precedence
if self.assistant_data is not None and row.assistant_data is not None:
# Updates row.assistant_data with self.assistant_data
# Updates db_row.assistant_data with self.assistant_data
merge_dictionaries(row.assistant_data, self.assistant_data)
self.assistant_data = row.assistant_data
# If assistant_data is not set in the assistant, use the database assistant_data
Expand All @@ -272,7 +272,7 @@ def from_database_row(self, row: AssistantRow):
# If run_data is set in the assistant, merge it with the database run_data.
# The assistant run_data takes precedence
if self.run_data is not None and row.run_data is not None:
# Updates row.run_data with self.run_data
# Updates db_row.run_data with self.run_data
merge_dictionaries(row.run_data, self.run_data)
self.run_data = row.run_data
# If run_data is not set in the assistant, use the database run_data
Expand All @@ -284,7 +284,7 @@ def from_database_row(self, row: AssistantRow):
# If user_data is set in the assistant, merge it with the database user_data.
# The assistant user_data takes precedence
if self.user_data is not None and row.user_data is not None:
# Updates row.user_data with self.user_data
# Updates db_row.user_data with self.user_data
merge_dictionaries(row.user_data, self.user_data)
self.user_data = row.user_data
# If user_data is not set in the assistant, use the database user_data
Expand All @@ -296,33 +296,33 @@ def from_database_row(self, row: AssistantRow):
# If task_data is set in the assistant, merge it with the database task_data.
# The assistant task_data takes precedence
if self.task_data is not None and row.task_data is not None:
# Updates row.task_data with self.task_data
# Updates db_row.task_data with self.task_data
merge_dictionaries(row.task_data, self.task_data)
self.task_data = row.task_data
# If task_data is not set in the assistant, use the database task_data
if self.task_data is None and row.task_data is not None:
self.task_data = row.task_data

def read_from_storage(self) -> Optional[AssistantRow]:
"""Load the AssistantRow from storage"""
def read_from_storage(self) -> Optional[AssistantRun]:
"""Load the AssistantRun from storage"""

if self.storage is not None and self.run_id is not None:
self.row = self.storage.read(run_id=self.run_id)
if self.user_id is not None and self.row is not None and self.row.user_id != self.user_id:
logger.error(f"SECURITY ERROR: User id mismatch: {self.user_id} != {self.row.user_id}")
self.db_row = self.storage.read(run_id=self.run_id)
if self.user_id is not None and self.db_row is not None and self.db_row.user_id != self.user_id:
logger.error(f"SECURITY ERROR: User id mismatch: {self.user_id} != {self.db_row.user_id}")
return None
if self.row is not None:
logger.debug(f"-*- Loading run: {self.row.run_id}")
self.from_database_row(row=self.row)
if self.db_row is not None:
logger.debug(f"-*- Loading run: {self.db_row.run_id}")
self.from_database_row(row=self.db_row)
logger.debug(f"-*- Loaded run: {self.run_id}")
return self.row
return self.db_row

def write_to_storage(self) -> Optional[AssistantRow]:
"""Save the AssistantRow to the storage"""
def write_to_storage(self) -> Optional[AssistantRun]:
"""Save the AssistantRun to the storage"""

if self.storage is not None:
self.row = self.storage.upsert(row=self.to_database_row())
return self.row
self.db_row = self.storage.upsert(row=self.to_database_row())
return self.db_row

def add_introduction(self, introduction: str) -> None:
"""Add assistant introduction to the chat history"""
Expand All @@ -339,8 +339,8 @@ def create_run(self) -> Optional[str]:
"""

# If a database_row exists, return the id from the database_row
if self.row is not None:
return self.row.run_id
if self.db_row is not None:
return self.db_row.run_id

# Create a new run or load an existing run
if self.storage is not None:
Expand All @@ -349,15 +349,15 @@ def create_run(self) -> Optional[str]:
self.read_from_storage()

# Create a new run
if self.row is None:
if self.db_row is None:
logger.debug("-*- Creating new assistant run")
if self.introduction:
self.add_introduction(self.introduction)
self.row = self.write_to_storage()
if self.row is None:
self.db_row = self.write_to_storage()
if self.db_row is None:
raise Exception("Failed to create new assistant run in storage")
logger.debug(f"-*- Created assistant run: {self.row.run_id}")
self.from_database_row(row=self.row)
logger.debug(f"-*- Created assistant run: {self.db_row.run_id}")
self.from_database_row(row=self.db_row)
self._api_log_assistant_run()
return self.run_id

Expand Down Expand Up @@ -647,7 +647,7 @@ def _api_log_assistant_run(self):
from phi.api.assistant import create_assistant_run, AssistantRunCreate

try:
database_row: AssistantRow = self.row or self.to_database_row()
database_row: AssistantRun = self.db_row or self.to_database_row()
create_assistant_run(
run=AssistantRunCreate(
run_id=database_row.run_id,
Expand All @@ -664,7 +664,7 @@ def _api_log_assistant_event(self, event_type: str = "run", event_data: Optional
from phi.api.assistant import create_assistant_event, AssistantEventCreate

try:
database_row: AssistantRow = self.row or self.to_database_row()
database_row: AssistantRun = self.db_row or self.to_database_row()
create_assistant_event(
event=AssistantEventCreate(
run_id=database_row.run_id,
Expand Down
4 changes: 2 additions & 2 deletions phi/assistant/row.py → phi/assistant/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from pydantic import BaseModel, ConfigDict


class AssistantRow(BaseModel):
"""Interface between Assistant class and the database"""
class AssistantRun(BaseModel):
"""Assistant Run that is stored in the database"""

# Assistant name
name: Optional[str] = None
Expand Down
8 changes: 4 additions & 4 deletions phi/storage/assistant/base.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from abc import ABC, abstractmethod
from typing import Optional, List

from phi.assistant.row import AssistantRow
from phi.assistant.run import AssistantRun


class AssistantStorage(ABC):
Expand All @@ -10,19 +10,19 @@ def create(self) -> None:
raise NotImplementedError

@abstractmethod
def read(self, run_id: str) -> Optional[AssistantRow]:
def read(self, run_id: str) -> Optional[AssistantRun]:
raise NotImplementedError

@abstractmethod
def get_all_run_ids(self, user_id: Optional[str] = None) -> List[str]:
raise NotImplementedError

@abstractmethod
def get_all_runs(self, user_id: Optional[str] = None) -> List[AssistantRow]:
def get_all_runs(self, user_id: Optional[str] = None) -> List[AssistantRun]:
raise NotImplementedError

@abstractmethod
def upsert(self, row: AssistantRow) -> Optional[AssistantRow]:
def upsert(self, row: AssistantRun) -> Optional[AssistantRun]:
raise NotImplementedError

@abstractmethod
Expand Down
14 changes: 7 additions & 7 deletions phi/storage/assistant/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
except ImportError:
raise ImportError("`sqlalchemy` not installed")

from phi.assistant.row import AssistantRow
from phi.assistant.run import AssistantRun
from phi.storage.assistant.base import AssistantStorage
from phi.utils.log import logger

Expand Down Expand Up @@ -114,10 +114,10 @@ def _read(self, session: Session, run_id: str) -> Optional[Row[Any]]:
self.create()
return None

def read(self, run_id: str) -> Optional[AssistantRow]:
def read(self, run_id: str) -> Optional[AssistantRun]:
with self.Session() as sess, sess.begin():
existing_row: Optional[Row[Any]] = self._read(session=sess, run_id=run_id)
return AssistantRow.model_validate(existing_row) if existing_row is not None else None
return AssistantRun.model_validate(existing_row) if existing_row is not None else None

def get_all_run_ids(self, user_id: Optional[str] = None) -> List[str]:
run_ids: List[str] = []
Expand All @@ -138,8 +138,8 @@ def get_all_run_ids(self, user_id: Optional[str] = None) -> List[str]:
logger.debug(f"Table does not exist: {self.table.name}")
return run_ids

def get_all_runs(self, user_id: Optional[str] = None) -> List[AssistantRow]:
runs: List[AssistantRow] = []
def get_all_runs(self, user_id: Optional[str] = None) -> List[AssistantRun]:
runs: List[AssistantRun] = []
try:
with self.Session() as sess, sess.begin():
# get all runs for this user
Expand All @@ -152,12 +152,12 @@ def get_all_runs(self, user_id: Optional[str] = None) -> List[AssistantRow]:
rows = sess.execute(stmt).fetchall()
for row in rows:
if row.run_id is not None:
runs.append(AssistantRow.model_validate(row))
runs.append(AssistantRun.model_validate(row))
except Exception:
logger.debug(f"Table does not exist: {self.table.name}")
return runs

def upsert(self, row: AssistantRow) -> Optional[AssistantRow]:
def upsert(self, row: AssistantRun) -> Optional[AssistantRun]:
"""
Create a new assistant run if it does not exist, otherwise update the existing assistant.
"""
Expand Down
14 changes: 7 additions & 7 deletions phi/storage/assistant/sqllite.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from sqlite3 import OperationalError

from phi.assistant.row import AssistantRow
from phi.assistant.run import AssistantRun
from phi.storage.assistant.base import AssistantStorage
from phi.utils.dttm import current_datetime
from phi.utils.log import logger
Expand Down Expand Up @@ -121,10 +121,10 @@ def _read(self, session: Session, run_id: str) -> Optional[Row[Any]]:
logger.warning(e)
return None

def read(self, run_id: str) -> Optional[AssistantRow]:
def read(self, run_id: str) -> Optional[AssistantRun]:
with self.Session() as sess:
existing_row: Optional[Row[Any]] = self._read(session=sess, run_id=run_id)
return AssistantRow.model_validate(existing_row) if existing_row is not None else None
return AssistantRun.model_validate(existing_row) if existing_row is not None else None

def get_all_run_ids(self, user_id: Optional[str] = None) -> List[str]:
run_ids: List[str] = []
Expand All @@ -146,8 +146,8 @@ def get_all_run_ids(self, user_id: Optional[str] = None) -> List[str]:
pass
return run_ids

def get_all_runs(self, user_id: Optional[str] = None) -> List[AssistantRow]:
conversations: List[AssistantRow] = []
def get_all_runs(self, user_id: Optional[str] = None) -> List[AssistantRun]:
conversations: List[AssistantRun] = []
try:
with self.Session() as sess:
# get all runs for this user
Expand All @@ -160,13 +160,13 @@ def get_all_runs(self, user_id: Optional[str] = None) -> List[AssistantRow]:
rows = sess.execute(stmt).fetchall()
for row in rows:
if row.run_id is not None:
conversations.append(AssistantRow.model_validate(row))
conversations.append(AssistantRun.model_validate(row))
except OperationalError:
logger.debug(f"Table does not exist: {self.table.name}")
pass
return conversations

def upsert(self, row: AssistantRow) -> Optional[AssistantRow]:
def upsert(self, row: AssistantRun) -> Optional[AssistantRun]:
"""
Create a new assistant run if it does not exist, otherwise update the existing conversation.
"""
Expand Down
2 changes: 1 addition & 1 deletion phi/workspace/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ class WorkspaceStarterTemplate(str, Enum):
ai_api = "ai-api"
django_app = "django-app"
streamlit_app = "streamlit-app"
junior_de = "junior-de"
# junior_de = "junior-de"
4 changes: 2 additions & 2 deletions phi/workspace/operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@
WorkspaceStarterTemplate.ai_api: "ai-api",
WorkspaceStarterTemplate.django_app: "django-app",
WorkspaceStarterTemplate.streamlit_app: "streamlit-app",
WorkspaceStarterTemplate.junior_de: "junior-de",
# WorkspaceStarterTemplate.junior_de: "junior-de",
}
TEMPLATE_TO_REPO_MAP: Dict[WorkspaceStarterTemplate, str] = {
WorkspaceStarterTemplate.ai_app: "https://github.com/phidatahq/ai-app.git",
WorkspaceStarterTemplate.ai_api: "https://github.com/phidatahq/ai-api.git",
WorkspaceStarterTemplate.django_app: "https://github.com/phidatahq/django-app.git",
WorkspaceStarterTemplate.streamlit_app: "https://github.com/phidatahq/streamlit-app.git",
WorkspaceStarterTemplate.junior_de: "https://github.com/phidatahq/junior-de.git",
# WorkspaceStarterTemplate.junior_de: "https://github.com/phidatahq/junior-de.git",
}


Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "phidata"
version = "2.2.0"
version = "2.3.0"
description = "Build AI Assistants using language models"
requires-python = ">=3.7"
readme = "README.md"
Expand Down

0 comments on commit 5ef08a6

Please sign in to comment.