diff --git a/cognition_objects/business_model.py b/cognition_objects/business_model.py new file mode 100644 index 00000000..64f48980 --- /dev/null +++ b/cognition_objects/business_model.py @@ -0,0 +1,120 @@ +from typing import List, Dict, Any + +from ..business_objects import general +from ..session import session + +from ..models import ( + DataManagerBusinessModels, + DataManagerBusinessModelQuestions, + DataManagerDataConcepts, +) +from submodules.model.util import sql_alchemy_to_dict + + +def create_business_model( + org_id: str, + name: str, + description: str, + question_ids: List[str], + llm_config: Dict[str, Any], + with_commit: bool = False, +) -> Dict[str, Any]: + + bm = DataManagerBusinessModels( + organization_id=org_id, + name=name, + description=description, + llm_config=llm_config, + ) + + general.add(bm, False) + + questions = [] + for q_id in question_ids: + q = DataManagerBusinessModelQuestions(business_model_id=bm.id, question_id=q_id) + general.add(q, False) + questions.append(q) + general.flush_or_commit(with_commit) + + bm_dict = {**sql_alchemy_to_dict(bm), "questions": sql_alchemy_to_dict(questions)} + return bm_dict + + +def get_business_model_by_id( + org_id: str, business_model_id: str +) -> DataManagerBusinessModels: + return ( + session.query(DataManagerBusinessModels) + .filter( + DataManagerBusinessModels.organization_id == org_id, + DataManagerBusinessModels.id == business_model_id, + ) + .first() + ) + + +def create_data_concept( + business_model_id: str, + created_by: str, + question_id: str, + input: str, + with_commit: bool = False, +) -> Dict[str, Any]: + + dc = DataManagerDataConcepts( + business_model_id=business_model_id, + question_id=question_id, + created_by=created_by, + input=input, + ) + general.add(dc, with_commit) + return dc + + +def get_data_concepts_by_ids( + data_concept_ids: List[str], +) -> List[DataManagerDataConcepts]: + return ( + session.query(DataManagerDataConcepts) + .filter(DataManagerDataConcepts.id.in_(data_concept_ids)) + .all() + ) + + +def get_all(org_id: str) -> List[DataManagerBusinessModels]: + return ( + session.query(DataManagerBusinessModels) + .filter(DataManagerBusinessModels.organization_id == org_id) + .all() + ) + + +def get_questions_for_business_model( + org_id: str, business_model_id: str +) -> List[DataManagerBusinessModelQuestions]: + + query = f""" + SELECT * + FROM data_manager.business_model_questions bmq + JOIN data_manager.organization_questions oq on oq.id = bmq.question_id + WHERE bmq.business_model_id = '{business_model_id}' and oq.organization_id = '{org_id}' + """ + + return general.execute_all(query) + + +def get_data_concepts_by_user( + user_id: str, business_model_id: str +) -> List[DataManagerBusinessModelQuestions]: + + return ( + session.query(DataManagerDataConcepts) + .join( + DataManagerBusinessModelQuestions, + DataManagerBusinessModelQuestions.question_id + == DataManagerDataConcepts.question_id, + ) + .filter(DataManagerDataConcepts.business_model_id == business_model_id) + .filter(DataManagerDataConcepts.created_by == user_id) + .all() + ) diff --git a/cognition_objects/organization_question.py b/cognition_objects/organization_question.py new file mode 100644 index 00000000..5d739a5d --- /dev/null +++ b/cognition_objects/organization_question.py @@ -0,0 +1,63 @@ +from typing import Any, Dict, List +from ..session import session +from submodules.model.business_objects import general +from submodules.model.models import DataManagerOrganizationQuestions, Team + + +def create( + org_id: str, + type: str, + config: Dict[str, Any], + with_commit: bool = True, +) -> DataManagerOrganizationQuestions: + new_question = DataManagerOrganizationQuestions( + organization_id=org_id, + type=type, + config=config, + ) + + general.add(new_question, with_commit) + return new_question + + +def get_all(org_id: str) -> List[DataManagerOrganizationQuestions]: + return ( + session.query(DataManagerOrganizationQuestions) + .filter(DataManagerOrganizationQuestions.organization_id == org_id) + .all() + ) + + +def delete_many(org_id: str, question_ids: List[str], with_commit: bool = True) -> None: + session.query(DataManagerOrganizationQuestions).filter( + DataManagerOrganizationQuestions.organization_id == org_id, + DataManagerOrganizationQuestions.id.in_(question_ids), + ).delete(synchronize_session=False) + + general.flush_or_commit(with_commit) + + +def get_by_id(org_id: str, question_id: str) -> DataManagerOrganizationQuestions: + return ( + session.query(DataManagerOrganizationQuestions) + .filter( + DataManagerOrganizationQuestions.organization_id == org_id, + DataManagerOrganizationQuestions.id == question_id, + ) + .one() + ) + + +def update( + org_id: str, + question_id: str, + type: str, + config: Dict[str, Any], + with_commit: bool = True, +) -> DataManagerOrganizationQuestions: + question = get_by_id(org_id, question_id) + question.type = type + question.config = config + + general.flush_or_commit(with_commit) + return question diff --git a/enums.py b/enums.py index ec551c02..f8cb9dc0 100644 --- a/enums.py +++ b/enums.py @@ -141,6 +141,12 @@ class Tablenames(Enum): MACRO_EDGE = "macro_edge" # connection between steps of a macro MACRO_EXECUTION = "macro_execution" # links macro id to an execution id MACRO_EXECUTION_LINK = "macro_execution_link" # execution to a conversation id + ORGANIZATION_QUESTIONS = "organization_questions" + BUSINESS_MODELS = "business_models" + BUSINESS_MODEL_QUESTIONS = "business_model_questions" + DATA_CONCEPTS = "data_concepts" + RULES = "rules" + RESOURCE = "resource" def snake_case_to_pascal_case(self): # the type name (written in PascalCase) of a table is needed to create backrefs @@ -516,6 +522,9 @@ class StrategyStepType(Enum): # INFO: done in exec env to prevent installing sklearn in gateway TMP_DOC_RETRIEVAL = "TMP_DOC_RETRIEVAL" + # INFO: needs a good business model to work properly + BUSINESS_MODEL_CONSUMPTION = "BUSINESS_MODEL_CONSUMPTION" + def get_description(self): return STEP_DESCRIPTIONS.get(self, "No description available") @@ -539,6 +548,7 @@ def get_progress_text(self): StrategyStepType.TRUNCATE_CONTEXT: "Truncate context", StrategyStepType.HEADER: "Writing header", StrategyStepType.TMP_DOC_RETRIEVAL: "Temporary document retrieval", + StrategyStepType.BUSINESS_MODEL_CONSUMPTION: "Business model consumption", } STEP_WHEN_TO_USE = { @@ -554,6 +564,7 @@ def get_progress_text(self): StrategyStepType.TRUNCATE_CONTEXT: "When you want to truncate context", StrategyStepType.HEADER: "When you want to set a header based on the conversation", StrategyStepType.TMP_DOC_RETRIEVAL: "When you want to retrieve results from conversation specific documents", + StrategyStepType.BUSINESS_MODEL_CONSUMPTION: "When you want to understand what business resources are relevant", } STEP_PROGRESS_TEXTS = { @@ -569,6 +580,7 @@ def get_progress_text(self): StrategyStepType.TRUNCATE_CONTEXT: "Truncating context", StrategyStepType.HEADER: "Headline generation", StrategyStepType.TMP_DOC_RETRIEVAL: "Retrieving facts from conversation specific documents", + StrategyStepType.BUSINESS_MODEL_CONSUMPTION: "Analyzing relevant resources", } STEP_ERRORS = { @@ -745,3 +757,20 @@ class AdminMacrosDisplay(Enum): FOR_ADMINS = "FOR_ADMINS" FOR_ENGINEERS = "FOR_ENGINEERS" FOR_ALL = "FOR_ALL" + + +class QuestionType(Enum): + INPUT_TEXT = "INPUT_TEXT" + INPUT_CHECKBOX = "INPUT_CHECKBOX" + TEXTAREA = "TEXTAREA" + DROPDOWN = "DROPDOWN" + + +class RuleType(Enum): + GLOBAL_CONTEXT = "GLOBAL_CONTEXT" + RESOURCE_CONTEXT = "RESOURCE_CONTEXT" + RESOURCE_RELATION = "RESOURCE_RELATION" + + +class ResourceType(Enum): + PDF = "PDF" diff --git a/models.py b/models.py index 040a467e..0fac3ed2 100644 --- a/models.py +++ b/models.py @@ -1691,3 +1691,116 @@ class GlobalWebsocketAccess(Base): ForeignKey(f"{Tablenames.USER.value}.id", ondelete="CASCADE"), index=True, ) + + +class DataManagerBusinessModels(Base): + __tablename__ = Tablenames.BUSINESS_MODELS.value + __table_args__ = {"schema": "data_manager"} + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + organization_id = Column( + UUID(as_uuid=True), + ForeignKey(f"{Tablenames.ORGANIZATION.value}.id", ondelete="CASCADE"), + index=True, + ) + name = Column(String) + description = Column(String) + created_at = Column(DateTime, default=sql.func.now()) + llm_config = Column(JSON) + + +class DataManagerBusinessModelQuestions(Base): + __tablename__ = Tablenames.BUSINESS_MODEL_QUESTIONS.value + __table_args__ = {"schema": "data_manager"} + business_model_id = Column( + UUID(as_uuid=True), + ForeignKey( + f"data_manager.{Tablenames.BUSINESS_MODELS.value}.id", ondelete="CASCADE" + ), + index=True, + primary_key=True, + ) + question_id = Column( + UUID(as_uuid=True), + ForeignKey( + f"data_manager.{Tablenames.ORGANIZATION_QUESTIONS.value}.id", + ondelete="CASCADE", + ), + index=True, + primary_key=True, + ) + + +class DataManagerOrganizationQuestions(Base): + __tablename__ = Tablenames.ORGANIZATION_QUESTIONS.value + __table_args__ = {"schema": "data_manager"} + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + organization_id = Column( + UUID(as_uuid=True), + ForeignKey(f"{Tablenames.ORGANIZATION.value}.id", ondelete="CASCADE"), + index=True, + ) + type = Column(String) # of type enums.QuestionType.*.value + config = Column(JSON) + + +class DataManagerDataConcepts(Base): + __tablename__ = Tablenames.DATA_CONCEPTS.value + __table_args__ = {"schema": "data_manager"} + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + business_model_id = Column( + UUID(as_uuid=True), + ForeignKey( + f"data_manager.{Tablenames.BUSINESS_MODELS.value}.id", ondelete="CASCADE" + ), + index=True, + ) + question_id = Column( + UUID(as_uuid=True), + ForeignKey( + f"data_manager.{Tablenames.ORGANIZATION_QUESTIONS.value}.id", + ondelete="CASCADE", + ), + index=True, + ) + created_at = Column(DateTime, default=sql.func.now()) + created_by = Column( + UUID(as_uuid=True), + ForeignKey(f"{Tablenames.USER.value}.id", ondelete="CASCADE"), + index=True, + ) + input = Column(String) + + +class DataManagerRules(Base): + __tablename__ = Tablenames.RULES.value + __table_args__ = {"schema": "data_manager"} + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + data_concept_id = Column( + UUID(as_uuid=True), + ForeignKey(f"data_manager.{Tablenames.DATA_CONCEPTS.value}.id"), + index=True, + ) + type = Column(String) # of type enums.RuleType.*.value + created_at = Column(DateTime, default=sql.func.now()) + created_by = Column( + UUID(as_uuid=True), + ForeignKey(f"{Tablenames.USER.value}.id", ondelete="CASCADE"), + index=True, + ) + autogenerated = Column(Boolean, default=True) + config = Column(JSON) + + +class DataManagerResource(Base): + __tablename__ = Tablenames.RESOURCE.value + __table_args__ = {"schema": "data_manager"} + id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + created_at = Column(DateTime, default=sql.func.now()) + created_by = Column( + UUID(as_uuid=True), + ForeignKey(f"{Tablenames.USER.value}.id", ondelete="CASCADE"), + index=True, + ) + original_name = Column(String) + aliases = Column(ARRAY(String)) + type = Column(String) # of type enums.ResourceType.*.value