|
- import json
- import logging
- import os
- import sqlite3
- import threading
- from typing import Any, Dict, List, Optional, Tuple
-
- from ..datamodel import AgentFlowSpec, AgentWorkFlowConfig, Gallery, Message, Model, Session, Skill
- from ..version import __version__ as __db_version__
-
- VERSION_TABLE_SQL = """
- CREATE TABLE IF NOT EXISTS version (
-
- version TEXT NOT NULL,
- UNIQUE (version)
- )
- """
-
- MODELS_TABLE_SQL = """
- CREATE TABLE IF NOT EXISTS models (
- id TEXT NOT NULL,
- user_id TEXT NOT NULL,
- timestamp DATETIME NOT NULL,
- model TEXT,
- api_key TEXT,
- base_url TEXT,
- api_type TEXT,
- api_version TEXT,
- description TEXT,
- UNIQUE (id, user_id)
- )
- """
-
-
- MESSAGES_TABLE_SQL = """
- CREATE TABLE IF NOT EXISTS messages (
- user_id TEXT NOT NULL,
- session_id TEXT,
- root_msg_id TEXT NOT NULL,
- msg_id TEXT,
- role TEXT NOT NULL,
- content TEXT NOT NULL,
- metadata TEXT,
- timestamp DATETIME,
- UNIQUE (user_id, root_msg_id, msg_id)
- )
- """
-
- SESSIONS_TABLE_SQL = """
- CREATE TABLE IF NOT EXISTS sessions (
- id TEXT NOT NULL,
- user_id TEXT NOT NULL,
- timestamp DATETIME NOT NULL,
- name TEXT,
- flow_config TEXT,
- UNIQUE (user_id, id)
- )
- """
-
- SKILLS_TABLE_SQL = """
- CREATE TABLE IF NOT EXISTS skills (
- id TEXT NOT NULL,
- user_id TEXT NOT NULL,
- timestamp DATETIME NOT NULL,
- content TEXT,
- title TEXT,
- file_name TEXT,
- UNIQUE (id, user_id)
- )
- """
- AGENTS_TABLE_SQL = """
- CREATE TABLE IF NOT EXISTS agents (
-
- id TEXT NOT NULL,
- user_id TEXT NOT NULL,
- timestamp DATETIME NOT NULL,
- config TEXT,
- type TEXT,
- skills TEXT,
- UNIQUE (id, user_id)
- )
- """
-
- WORKFLOWS_TABLE_SQL = """
- CREATE TABLE IF NOT EXISTS workflows (
- id TEXT NOT NULL,
- user_id TEXT NOT NULL,
- timestamp DATETIME NOT NULL,
- sender TEXT,
- receiver TEXT,
- type TEXT,
- name TEXT,
- description TEXT,
- summary_method TEXT,
- UNIQUE (id, user_id)
- )
- """
-
- GALLERY_TABLE_SQL = """
- CREATE TABLE IF NOT EXISTS gallery (
- id TEXT NOT NULL,
- session TEXT,
- messages TEXT,
- tags TEXT,
- timestamp DATETIME NOT NULL,
- UNIQUE ( id)
- )
- """
-
-
- lock = threading.Lock()
- logger = logging.getLogger()
-
-
- class DBManager:
- """
- A database manager class that handles the creation and interaction with an SQLite database.
- """
-
- def __init__(self, path: str = "database.sqlite", **kwargs: Any) -> None:
- """
- Initializes the DBManager object, creates a database if it does not exist, and establishes a connection.
-
- Args:
- path (str): The file path to the SQLite database file.
- **kwargs: Additional keyword arguments to pass to the sqlite3.connect method.
- """
-
- self.path = path
- # check if the database exists, if not create it
- # self.reset_db()
- if not os.path.exists(self.path):
- logger.info("Creating database")
- self.init_db(path=self.path, **kwargs)
-
- try:
- self.conn = sqlite3.connect(self.path, check_same_thread=False, **kwargs)
- self.cursor = self.conn.cursor()
- self.migrate()
- except Exception as e:
- logger.error("Error connecting to database: %s", e)
- raise e
-
- def migrate(self):
- """
- Run migrations to update the database schema.
- """
- self.add_column_if_not_exists("sessions", "name", "TEXT")
- self.add_column_if_not_exists("models", "description", "TEXT")
-
- def add_column_if_not_exists(self, table: str, column: str, column_type: str):
- """
- Adds a new column to the specified table if it does not exist.
-
- Args:
- table (str): The table name where the column should be added.
- column (str): The column name that should be added.
- column_type (str): The data type of the new column.
- """
- try:
- self.cursor.execute(f"PRAGMA table_info({table})")
- column_names = [row[1] for row in self.cursor.fetchall()]
- if column not in column_names:
- self.cursor.execute(f"ALTER TABLE {table} ADD COLUMN {column} {column_type}")
- self.conn.commit()
- logger.info(f"Migration: New '{column}' column has been added to the '{table}' table.")
- else:
- logger.info(f"'{column}' column already exists in the '{table}' table.")
-
- except Exception as e:
- print(f"Error while checking and updating '{table}' table: {e}")
-
- def reset_db(self):
- """
- Reset the database by deleting the database file and creating a new one.
- """
- print("resetting db")
- if os.path.exists(self.path):
- os.remove(self.path)
- self.init_db(path=self.path)
-
- def init_db(self, path: str = "database.sqlite", **kwargs: Any) -> None:
- """
- Initializes the database by creating necessary tables.
-
- Args:
- path (str): The file path to the SQLite database file.
- **kwargs: Additional keyword arguments to pass to the sqlite3.connect method.
- """
- # Connect to the database (or create a new one if it doesn't exist)
- self.conn = sqlite3.connect(path, check_same_thread=False, **kwargs)
- self.cursor = self.conn.cursor()
-
- # Create the version table
- self.cursor.execute(VERSION_TABLE_SQL)
- self.cursor.execute("INSERT INTO version (version) VALUES (?)", (__db_version__,))
-
- # Create the models table
- self.cursor.execute(MODELS_TABLE_SQL)
-
- # Create the messages table
- self.cursor.execute(MESSAGES_TABLE_SQL)
-
- # Create a sessions table
- self.cursor.execute(SESSIONS_TABLE_SQL)
-
- # Create a skills
- self.cursor.execute(SKILLS_TABLE_SQL)
-
- # Create a gallery table
- self.cursor.execute(GALLERY_TABLE_SQL)
-
- # Create a agents table
- self.cursor.execute(AGENTS_TABLE_SQL)
-
- # Create a workflows table
- self.cursor.execute(WORKFLOWS_TABLE_SQL)
-
- # init skills table with content of defaultskills.json in current directory
- current_dir = os.path.dirname(os.path.realpath(__file__))
- with open(os.path.join(current_dir, "dbdefaults.json"), "r", encoding="utf-8") as json_file:
- data = json.load(json_file)
- skills = data["skills"]
- agents = data["agents"]
- models = data["models"]
- for model in models:
- model = Model(**model)
- self.cursor.execute(
- "INSERT INTO models (id, user_id, timestamp, model, api_key, base_url, api_type, api_version, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
- (
- model.id,
- "default",
- model.timestamp,
- model.model,
- model.api_key,
- model.base_url,
- model.api_type,
- model.api_version,
- model.description,
- ),
- )
-
- for skill in skills:
- skill = Skill(**skill)
-
- self.cursor.execute(
- "INSERT INTO skills (id, user_id, timestamp, content, title, file_name) VALUES (?, ?, ?, ?, ?, ?)",
- (skill.id, "default", skill.timestamp, skill.content, skill.title, skill.file_name),
- )
- for agent in agents:
- agent = AgentFlowSpec(**agent)
- agent.skills = [skill.dict() for skill in agent.skills] if agent.skills else None
- self.cursor.execute(
- "INSERT INTO agents (id, user_id, timestamp, config, type, skills) VALUES (?, ?, ?, ?, ?, ?)",
- (
- agent.id,
- "default",
- agent.timestamp,
- json.dumps(agent.config.dict()),
- agent.type,
- json.dumps(agent.skills),
- ),
- )
-
- for workflow in data["workflows"]:
- workflow = AgentWorkFlowConfig(**workflow)
- self.cursor.execute(
- "INSERT INTO workflows (id, user_id, timestamp, sender, receiver, type, name, description, summary_method) VALUES (?, ?, ?, ?, ?, ?, ?, ?,?)",
- (
- workflow.id,
- "default",
- workflow.timestamp,
- json.dumps(workflow.sender.dict()),
- json.dumps(workflow.receiver.dict()),
- workflow.type,
- workflow.name,
- workflow.description,
- workflow.summary_method,
- ),
- )
-
- # Commit the changes and close the connection
- self.conn.commit()
-
- def query(self, query: str, args: Tuple = (), return_json: bool = False) -> List[Dict[str, Any]]:
- """
- Executes a given SQL query and returns the results.
-
- Args:
- query (str): The SQL query to execute.
- args (Tuple): The arguments to pass to the SQL query.
- return_json (bool): If True, the results will be returned as a list of dictionaries.
-
- Returns:
- List[Dict[str, Any]]: The result of the SQL query.
- """
- try:
- with lock:
- self.cursor.execute(query, args)
- result = self.cursor.fetchall()
- self.commit()
- if return_json:
- result = [dict(zip([key[0] for key in self.cursor.description], row)) for row in result]
- return result
- except Exception as e:
- logger.error("Error running query with query %s and args %s: %s", query, args, e)
- raise e
-
- def commit(self) -> None:
- """
- Commits the current transaction Modelto the database.
- """
- self.conn.commit()
-
- def close(self) -> None:
- """
- Closes the database connection.
- """
- self.conn.close()
-
-
- def get_models(user_id: str, dbmanager: DBManager) -> List[dict]:
- """
- Get all models for a given user from the database.
-
- Args:
- user_id: The user id to get models for
- dbmanager: The DBManager instance to interact with the database
-
- Returns:
- A list of model configurations
- """
- query = "SELECT * FROM models WHERE user_id = ? OR user_id = ?"
- args = (user_id, "default")
- results = dbmanager.query(query, args, return_json=True)
- return results
-
-
- def upsert_model(model: Model, dbmanager: DBManager) -> List[dict]:
- """
- Insert or update a model configuration in the database.
-
- Args:
- model: The Model object containing model configuration data
- dbmanager: The DBManager instance to interact with the database
-
- Returns:
- A list of model configurations
- """
-
- # Check if the model config with the provided id already exists in the database
- existing_model = get_item_by_field("models", "id", model.id, dbmanager)
-
- if existing_model:
- # If the model config exists, update it with the new data
- updated_data = {
- "model": model.model,
- "api_key": model.api_key,
- "base_url": model.base_url,
- "api_type": model.api_type,
- "api_version": model.api_version,
- "user_id": model.user_id,
- "timestamp": model.timestamp,
- "description": model.description,
- }
- update_item("models", model.id, updated_data, dbmanager)
- else:
- # If the model config does not exist, insert a new one
- query = """
- INSERT INTO models (id, user_id, timestamp, model, api_key, base_url, api_type, api_version, description)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
- """
- args = (
- model.id,
- model.user_id,
- model.timestamp,
- model.model,
- model.api_key,
- model.base_url,
- model.api_type,
- model.api_version,
- model.description,
- )
- dbmanager.query(query=query, args=args)
-
- # Return the inserted or updated model config
- models = get_models(model.user_id, dbmanager)
- return models
-
-
- def delete_model(model: Model, dbmanager: DBManager) -> List[dict]:
- """
- Delete a model configuration from the database where id = model.id and user_id = model.user_id.
-
- Args:
- model: The Model object containing model configuration data
- dbmanager: The DBManager instance to interact with the database
-
- Returns:
- A list of model configurations
- """
-
- query = "DELETE FROM models WHERE id = ? AND user_id = ?"
- args = (model.id, model.user_id)
- dbmanager.query(query=query, args=args)
-
- # Return the remaining model configs
- models = get_models(model.user_id, dbmanager)
- return models
-
-
- def create_message(message: Message, dbmanager: DBManager) -> List[dict]:
- """
- Save a message in the database using the provided database manager.
-
- :param message: The Message object containing message data
- :param dbmanager: The DBManager instance used to interact with the database
- """
- query = "INSERT INTO messages (user_id, root_msg_id, msg_id, role, content, metadata, timestamp, session_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
- args = (
- message.user_id,
- message.root_msg_id,
- message.msg_id,
- message.role,
- message.content,
- message.metadata,
- message.timestamp,
- message.session_id,
- )
- dbmanager.query(query=query, args=args)
- messages = get_messages(user_id=message.user_id, session_id=message.session_id, dbmanager=dbmanager)
- return messages
-
-
- def get_messages(user_id: str, session_id: str, dbmanager: DBManager) -> List[dict]:
- """
- Load messages for a specific user and session from the database, sorted by timestamp.
-
- :param user_id: The ID of the user whose messages are to be loaded
- :param session_id: The ID of the session whose messages are to be loaded
- :param dbmanager: The DBManager instance to interact with the database
-
- :return: A list of dictionaries, each representing a message
- """
- query = "SELECT * FROM messages WHERE user_id = ? AND session_id = ?"
- args = (user_id, session_id)
- result = dbmanager.query(query=query, args=args, return_json=True)
- # Sort by timestamp ascending
- result = sorted(result, key=lambda k: k["timestamp"], reverse=False)
- return result
-
-
- def get_sessions(user_id: str, dbmanager: DBManager) -> List[dict]:
- """
- Load sessions for a specific user from the database, sorted by timestamp.
-
- :param user_id: The ID of the user whose sessions are to be loaded
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing a session
- """
- query = "SELECT * FROM sessions WHERE user_id = ?"
- args = (user_id,)
- result = dbmanager.query(query=query, args=args, return_json=True)
- # Sort by timestamp ascending
- result = sorted(result, key=lambda k: k["timestamp"], reverse=True)
- for row in result:
- row["flow_config"] = json.loads(row["flow_config"])
- return result
-
-
- def create_session(user_id: str, session: Session, dbmanager: DBManager) -> List[dict]:
- """
- Create a new session for a specific user in the database.
-
- :param user_id: The ID of the user whose session is to be created
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing a session
- """
- query = "INSERT INTO sessions (user_id, id, timestamp, flow_config) VALUES (?, ?, ?,?)"
- args = (session.user_id, session.id, session.timestamp, json.dumps(session.flow_config.dict()))
- dbmanager.query(query=query, args=args)
- sessions = get_sessions(user_id=user_id, dbmanager=dbmanager)
-
- return sessions
-
-
- def rename_session(name: str, session: Session, dbmanager: DBManager) -> List[dict]:
- """
- Edit a session for a specific user in the database.
-
- :param name: The new name of the session
- :param session: The Session object containing session data
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing a session
- """
-
- query = "UPDATE sessions SET name = ? WHERE id = ?"
- args = (name, session.id)
- dbmanager.query(query=query, args=args)
- sessions = get_sessions(user_id=session.user_id, dbmanager=dbmanager)
-
- return sessions
-
-
- def delete_session(session: Session, dbmanager: DBManager) -> List[dict]:
- """
- Delete a specific session and all messages for that session in the database.
-
- :param session: The Session object containing session data
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of the remaining sessions
- """
-
- query = "DELETE FROM sessions WHERE id = ?"
- args = (session.id,)
- dbmanager.query(query=query, args=args)
-
- query = "DELETE FROM messages WHERE session_id = ?"
- args = (session.id,)
- dbmanager.query(query=query, args=args)
-
- return get_sessions(user_id=session.user_id, dbmanager=dbmanager)
-
-
- def create_gallery(session: Session, dbmanager: DBManager, tags: List[str] = []) -> Gallery:
- """
- Publish a session to the gallery table in the database. Fetches the session messages first, then saves session and messages object to the gallery database table.
- :param session: The Session object containing session data
- :param dbmanager: The DBManager instance used to interact with the database
- :param tags: A list of tags to associate with the session
- :return: A gallery object containing the session and messages objects
- """
-
- messages = get_messages(user_id=session.user_id, session_id=session.id, dbmanager=dbmanager)
- gallery_item = Gallery(session=session, messages=messages, tags=tags)
- query = "INSERT INTO gallery (id, session, messages, tags, timestamp) VALUES (?, ?, ?, ?,?)"
- args = (
- gallery_item.id,
- json.dumps(gallery_item.session.dict()),
- json.dumps([message.dict() for message in gallery_item.messages]),
- json.dumps(gallery_item.tags),
- gallery_item.timestamp,
- )
- dbmanager.query(query=query, args=args)
- return gallery_item
-
-
- def get_gallery(gallery_id, dbmanager: DBManager) -> List[Gallery]:
- """
- Load gallery items from the database, sorted by timestamp. If gallery_id is provided, only the gallery item with the matching gallery_id will be returned.
-
- :param gallery_id: The ID of the gallery item to be loaded
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of Gallery objects
- """
-
- if gallery_id:
- query = "SELECT * FROM gallery WHERE id = ?"
- args = (gallery_id,)
- else:
- query = "SELECT * FROM gallery"
- args = ()
- result = dbmanager.query(query=query, args=args, return_json=True)
- # Sort by timestamp ascending
- result = sorted(result, key=lambda k: k["timestamp"], reverse=True)
- gallery = []
- for row in result:
- gallery_item = Gallery(
- id=row["id"],
- session=Session(**json.loads(row["session"])),
- messages=[Message(**message) for message in json.loads(row["messages"])],
- tags=json.loads(row["tags"]),
- timestamp=row["timestamp"],
- )
- gallery.append(gallery_item)
- return gallery
-
-
- def get_skills(user_id: str, dbmanager: DBManager) -> List[Skill]:
- """
- Load skills from the database, sorted by timestamp. Load skills where id = user_id or user_id = default.
-
- :param user_id: The ID of the user whose skills are to be loaded
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of Skill objects
- """
-
- query = "SELECT * FROM skills WHERE user_id = ? OR user_id = ?"
- args = (user_id, "default")
- result = dbmanager.query(query=query, args=args, return_json=True)
- # Sort by timestamp ascending
- result = sorted(result, key=lambda k: k["timestamp"], reverse=True)
- skills = []
- for row in result:
- skill = Skill(**row)
- skills.append(skill)
- return skills
-
-
- def upsert_skill(skill: Skill, dbmanager: DBManager) -> List[Skill]:
- """
- Insert or update a skill for a specific user in the database.
-
- If the skill with the given ID already exists, it will be updated with the new data.
- Otherwise, a new skill will be created.
-
- :param skill: The Skill object containing skill data
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing a skill
- """
-
- existing_skill = get_item_by_field("skills", "id", skill.id, dbmanager)
-
- if existing_skill:
- updated_data = {
- "user_id": skill.user_id,
- "timestamp": skill.timestamp,
- "content": skill.content,
- "title": skill.title,
- "file_name": skill.file_name,
- }
- update_item("skills", skill.id, updated_data, dbmanager)
- else:
- query = "INSERT INTO skills (id, user_id, timestamp, content, title, file_name) VALUES (?, ?, ?, ?, ?, ?)"
- args = (skill.id, skill.user_id, skill.timestamp, skill.content, skill.title, skill.file_name)
- dbmanager.query(query=query, args=args)
-
- skills = get_skills(user_id=skill.user_id, dbmanager=dbmanager)
-
- return skills
-
-
- def delete_skill(skill: Skill, dbmanager: DBManager) -> List[Skill]:
- """
- Delete a skill for a specific user in the database.
-
- :param skill: The Skill object containing skill data
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing a skill
- """
- # delete where id = skill.id and user_id = skill.user_id
- query = "DELETE FROM skills WHERE id = ? AND user_id = ?"
- args = (skill.id, skill.user_id)
- dbmanager.query(query=query, args=args)
-
- return get_skills(user_id=skill.user_id, dbmanager=dbmanager)
-
-
- def delete_message(
- user_id: str, msg_id: str, session_id: str, dbmanager: DBManager, delete_all: bool = False
- ) -> List[dict]:
- """
- Delete a specific message or all messages for a user and session from the database.
-
- :param user_id: The ID of the user whose messages are to be deleted
- :param msg_id: The ID of the specific message to be deleted (ignored if delete_all is True)
- :param session_id: The ID of the session whose messages are to be deleted
- :param dbmanager: The DBManager instance to interact with the database
- :param delete_all: If True, all messages for the user will be deleted
- :return: A list of the remaining messages if not all were deleted, otherwise an empty list
- """
-
- if delete_all:
- query = "DELETE FROM messages WHERE user_id = ? AND session_id = ?"
- args = (user_id, session_id)
- dbmanager.query(query=query, args=args)
- return []
- else:
- query = "DELETE FROM messages WHERE user_id = ? AND msg_id = ? AND session_id = ?"
- args = (user_id, msg_id, session_id)
- dbmanager.query(query=query, args=args)
- messages = get_messages(user_id=user_id, session_id=session_id, dbmanager=dbmanager)
- return messages
-
-
- def get_agents(user_id: str, dbmanager: DBManager) -> List[AgentFlowSpec]:
- """
- Load agents from the database, sorted by timestamp. Load agents where id = user_id or user_id = default.
-
- :param user_id: The ID of the user whose agents are to be loaded
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of AgentFlowSpec objects
- """
-
- query = "SELECT * FROM agents WHERE user_id = ? OR user_id = ?"
- args = (user_id, "default")
- result = dbmanager.query(query=query, args=args, return_json=True)
- # Sort by timestamp ascending
- result = sorted(result, key=lambda k: k["timestamp"], reverse=True)
- agents = []
- for row in result:
- row["config"] = json.loads(row["config"])
- row["skills"] = json.loads(row["skills"] or "[]")
- agent = AgentFlowSpec(**row)
- agents.append(agent)
- return agents
-
-
- def upsert_agent(agent_flow_spec: AgentFlowSpec, dbmanager: DBManager) -> List[Dict[str, Any]]:
- """
- Insert or update an agent for a specific user in the database.
-
- If the agent with the given ID already exists, it will be updated with the new data.
- Otherwise, a new agent will be created.
-
- :param agent_flow_spec: The AgentFlowSpec object containing agent configuration
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing an agent after insertion or update
- """
-
- existing_agent = get_item_by_field("agents", "id", agent_flow_spec.id, dbmanager)
-
- if existing_agent:
- updated_data = {
- "user_id": agent_flow_spec.user_id,
- "timestamp": agent_flow_spec.timestamp,
- "config": json.dumps(agent_flow_spec.config.dict()),
- "type": agent_flow_spec.type,
- "skills": json.dumps([x.dict() for x in agent_flow_spec.skills] if agent_flow_spec.skills else []),
- }
- update_item("agents", agent_flow_spec.id, updated_data, dbmanager)
- else:
- query = "INSERT INTO agents (id, user_id, timestamp, config, type, skills) VALUES (?, ?, ?, ?, ?,?)"
- config_json = json.dumps(agent_flow_spec.config.dict())
- args = (
- agent_flow_spec.id,
- agent_flow_spec.user_id,
- agent_flow_spec.timestamp,
- config_json,
- agent_flow_spec.type,
- json.dumps([x.dict() for x in agent_flow_spec.skills] if agent_flow_spec.skills else []),
- )
- dbmanager.query(query=query, args=args)
-
- agents = get_agents(user_id=agent_flow_spec.user_id, dbmanager=dbmanager)
- return agents
-
-
- def delete_agent(agent: AgentFlowSpec, dbmanager: DBManager) -> List[Dict[str, Any]]:
- """
- Delete an agent for a specific user from the database.
-
- :param agent: The AgentFlowSpec object containing agent configuration
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing an agent after deletion
- """
-
- # delete based on agent.id and agent.user_id
- query = "DELETE FROM agents WHERE id = ? AND user_id = ?"
- args = (agent.id, agent.user_id)
- dbmanager.query(query=query, args=args)
-
- return get_agents(user_id=agent.user_id, dbmanager=dbmanager)
-
-
- def get_item_by_field(table: str, field: str, value: Any, dbmanager: DBManager) -> Optional[Dict[str, Any]]:
- query = f"SELECT * FROM {table} WHERE {field} = ?"
- args = (value,)
- result = dbmanager.query(query=query, args=args)
- return result[0] if result else None
-
-
- def update_item(table: str, item_id: str, updated_data: Dict[str, Any], dbmanager: DBManager) -> None:
- set_clause = ", ".join([f"{key} = ?" for key in updated_data.keys()])
- query = f"UPDATE {table} SET {set_clause} WHERE id = ?"
- args = (*updated_data.values(), item_id)
- dbmanager.query(query=query, args=args)
-
-
- def get_workflows(user_id: str, dbmanager: DBManager) -> List[Dict[str, Any]]:
- """
- Load workflows for a specific user from the database, sorted by timestamp.
-
- :param user_id: The ID of the user whose workflows are to be loaded
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing a workflow
- """
- query = "SELECT * FROM workflows WHERE user_id = ? OR user_id = ?"
- args = (user_id, "default")
- result = dbmanager.query(query=query, args=args, return_json=True)
- # Sort by timestamp ascending
- result = sorted(result, key=lambda k: k["timestamp"], reverse=True)
- workflows = []
- for row in result:
- row["sender"] = json.loads(row["sender"])
- row["receiver"] = json.loads(row["receiver"])
- workflow = AgentWorkFlowConfig(**row)
- workflows.append(workflow)
- return workflows
-
-
- def upsert_workflow(workflow: AgentWorkFlowConfig, dbmanager: DBManager) -> List[Dict[str, Any]]:
- """
- Insert or update a workflow for a specific user in the database.
-
- If the workflow with the given ID already exists, it will be updated with the new data.
- Otherwise, a new workflow will be created.
-
- :param workflow: The AgentWorkFlowConfig object containing workflow data
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing a workflow after insertion or update
- """
- existing_workflow = get_item_by_field("workflows", "id", workflow.id, dbmanager)
-
- # print(workflow.receiver)
-
- if existing_workflow:
- updated_data = {
- "user_id": workflow.user_id,
- "timestamp": workflow.timestamp,
- "sender": json.dumps(workflow.sender.dict()),
- "receiver": json.dumps(
- [receiver.dict() for receiver in workflow.receiver]
- if isinstance(workflow.receiver, list)
- else workflow.receiver.dict()
- ),
- "type": workflow.type,
- "name": workflow.name,
- "description": workflow.description,
- "summary_method": workflow.summary_method,
- }
- update_item("workflows", workflow.id, updated_data, dbmanager)
- else:
- query = "INSERT INTO workflows (id, user_id, timestamp, sender, receiver, type, name, description, summary_method) VALUES (?, ?, ?, ?, ?, ?, ?, ?,?)"
- args = (
- workflow.id,
- workflow.user_id,
- workflow.timestamp,
- json.dumps(workflow.sender.dict()),
- json.dumps(
- [receiver.dict() for receiver in workflow.receiver]
- if isinstance(workflow.receiver, list)
- else workflow.receiver.dict()
- ),
- workflow.type,
- workflow.name,
- workflow.description,
- workflow.summary_method,
- )
- dbmanager.query(query=query, args=args)
-
- return get_workflows(user_id=workflow.user_id, dbmanager=dbmanager)
-
-
- def delete_workflow(workflow: AgentWorkFlowConfig, dbmanager: DBManager) -> List[Dict[str, Any]]:
- """
- Delete a workflow for a specific user from the database. If the workflow does not exist, do nothing.
-
- :param workflow: The AgentWorkFlowConfig object containing workflow data
- :param dbmanager: The DBManager instance to interact with the database
- :return: A list of dictionaries, each representing a workflow after deletion
- """
-
- # delete where workflow.id =id and workflow.user_id = user_id
-
- query = "DELETE FROM workflows WHERE id = ? AND user_id = ?"
- args = (workflow.id, workflow.user_id)
- dbmanager.query(query=query, args=args)
-
- return get_workflows(user_id=workflow.user_id, dbmanager=dbmanager)
|