From 5ec9519b7cf2bc033017dc3c25fa5bfe3eefafdd Mon Sep 17 00:00:00 2001 From: JWittmeyer Date: Mon, 7 Jul 2025 15:47:35 +0200 Subject: [PATCH 1/3] Record edit on embedding lists --- business_objects/embedding.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/business_objects/embedding.py b/business_objects/embedding.py index 7adc48ed..c93829e5 100644 --- a/business_objects/embedding.py +++ b/business_objects/embedding.py @@ -830,7 +830,7 @@ def delete_by_record_ids( def delete_by_record_ids_and_sub_keys( project_id: str, embedding_id: str, - to_del: Iterable[Tuple[str, str]], + to_del: Iterable[Tuple[str, Any]], with_commit: bool = False, ) -> None: # deletes entries based on record_id and sub_key tuples for record changes @@ -843,7 +843,11 @@ def delete_by_record_ids_and_sub_keys( project_id = prevent_sql_injection(project_id, isinstance(project_id, str)) embedding_id = prevent_sql_injection(embedding_id, isinstance(embedding_id, str)) query_adds = [ - (prevent_sql_injection(r), prevent_sql_injection(s)) for r, s in to_del + ( + prevent_sql_injection(r, isinstance(r, str)), + prevent_sql_injection(s, isinstance(s, int)), + ) + for r, s in to_del ] query_adds = [ From 61ee231c61dc3509b79b6fc738f5871e77911ecb Mon Sep 17 00:00:00 2001 From: JWittmeyer Date: Tue, 8 Jul 2025 17:05:08 +0200 Subject: [PATCH 2/3] New admin queries --- enums.py | 4 + global_objects/admin_queries.py | 157 +++++++++++++++++++++++++++++++- 2 files changed, 160 insertions(+), 1 deletion(-) diff --git a/enums.py b/enums.py index b9a9461d..388674a0 100644 --- a/enums.py +++ b/enums.py @@ -908,6 +908,10 @@ class AdminQueries(Enum): "AVG_MESSAGES_PER_CONVERSATION_GLOBAL" # parameter options: organization_id ) AVG_MESSAGES_PER_CONVERSATION = "AVG_MESSAGES_PER_CONVERSATION" # parameter options: period (days, weeks or months), slices, organization_id + MACRO_EXECUTIONS = "MACRO_EXECUTIONS" # parameter options: period (days, weeks or months), slices, organization_id + FOLDER_MACRO_EXECUTION_SUMMARY = ( + "FOLDER_MACRO_EXECUTION_SUMMARY" # parameter options: organization_id + ) class CognitionIntegrationType(Enum): diff --git a/global_objects/admin_queries.py b/global_objects/admin_queries.py index 98c37cf8..b0c1108e 100644 --- a/global_objects/admin_queries.py +++ b/global_objects/admin_queries.py @@ -35,9 +35,164 @@ def get_result_admin_query( return __get_global_messages_per_conversation(**parameters, as_query=as_query) elif query == enums.AdminQueries.AVG_MESSAGES_PER_CONVERSATION: return __get_avg_messages_per_conversation(**parameters, as_query=as_query) + elif query == enums.AdminQueries.MACRO_EXECUTIONS: + return __get_macro_executions(**parameters, as_query=as_query) + elif query == enums.AdminQueries.FOLDER_MACRO_EXECUTION_SUMMARY: + return __get_folder_macro_execution_summary(**parameters, as_query=as_query) return [] +def __get_folder_macro_execution_summary( + slices: int = 7, # how many chunks are relevant + organization_id: Optional[str] = None, + as_query: bool = False, +) -> List[Row]: + + slices = max(min(slices, 30), 1) + + org_where = "" + if organization_id: + organization_id = prevent_sql_injection( + organization_id, isinstance(organization_id, str) + ) + org_where = f""" WHERE me.organization_id = '{organization_id}'""" + + query = f""" + WITH params AS ( + SELECT + 'months' ::text AS period, -- sum table so fixed to months + {slices} ::int AS n -- ← how many of those periods you want + ), + + -- 1) build the list of period-start dates + periods AS ( + SELECT + (generate_series( + date_trunc(p.period, CURRENT_DATE) + - (p.n - 1) * ( '1 ' || p.period )::interval, + date_trunc(p.period, CURRENT_DATE), + ( '1 ' || p.period )::interval + ))::date AS period_start, + p.period + FROM params p + ), + filtered AS ( + SELECT + me.organization_id, + date_trunc(p.period, me.creation_month)::date AS period_start, + execution_count, + processed_files_count + FROM cognition.macro_execution_summary me + INNER JOIN params p + ON me.creation_month >= ( + SELECT MIN(period_start) + FROM periods + ) + AND me.creation_month < ( + SELECT MAX(period_start) + ( '1 ' || p.period )::interval + FROM periods, params + ) + {org_where} + ) + + + SELECT + o.name organization_name, + period_start, + (period_start + ( '1 ' || pa.period )::INTERVAL - '1 day'::interval )::date AS period_end, + execution_count, + processed_files_count + FROM filtered m + INNER JOIN organization o + ON m.organization_id = o.id + , params pa + ORDER BY 1,2 DESC +""" + if as_query: + return query + return general.execute_all(query) + + +def __get_macro_executions( + period: str = "days", # options: days, weeks, months + slices: int = 7, # how many chunks are relevant + organization_id: Optional[str] = None, + as_query: bool = False, +) -> List[Row]: + + if period not in PERIOD_OPTIONS: + raise ValueError(f"Invalid period: {period}. Must be one of {PERIOD_OPTIONS}.") + slices = max(min(slices, 30), 1) + + org_where = "" + if organization_id: + organization_id = prevent_sql_injection( + organization_id, isinstance(organization_id, str) + ) + org_where = f""" WHERE me.organization_id = '{organization_id}'""" + + query = f""" + WITH params AS ( + SELECT + '{period}' ::text AS period, -- ← 'days' | 'weeks' | 'months' + {slices} ::int AS n -- ← how many of those periods you want + ), + + -- 1) build the list of period-start dates + periods AS ( + SELECT + (generate_series( + date_trunc(p.period, CURRENT_DATE) + - (p.n - 1) * ( '1 ' || p.period )::interval, + date_trunc(p.period, CURRENT_DATE), + ( '1 ' || p.period )::interval + ))::date AS period_start, + p.period + FROM params p + ), + filtered AS ( + SELECT + me.organization_id, + date_trunc(p.period, me.created_at)::date AS period_start + FROM cognition.macro_execution me + INNER JOIN params p + ON me.created_at >= ( + SELECT MIN(period_start) + FROM periods + ) + AND me.created_at < ( + SELECT MAX(period_start) + ( '1 ' || p.period )::interval + FROM periods, params + ) + {org_where} + ) + + + SELECT + o.name organization_name, + period_start, + (period_start + ( '1 ' || pa.period )::INTERVAL - '1 day'::interval )::date AS period_end, + macro_executions + FROM ( + SELECT + organization_id, + period_start, + COUNT(*) macro_executions + FROM filtered M + GROUP BY + m.organization_id, + period_start + )y + INNER JOIN organization o + ON y.organization_id = o.id + , params pa + ORDER BY 1,2 DESC +""" + if as_query: + return query + return general.execute_all(query) + + def __get_avg_messages_per_conversation( period: str = "days", # options: days, weeks, months slices: int = 7, # how many chunks are relevant @@ -131,7 +286,7 @@ def __get_avg_messages_per_conversation( INNER JOIN organization o ON p.organization_id = o.id , params pa - ORDER BY 1,5 DESC + ORDER BY 1,3 DESC """ if as_query: return query From a2fc3f4c3f1d9b301cb065e508350b3a71683a38 Mon Sep 17 00:00:00 2001 From: LennartSchmidtKern Date: Tue, 8 Jul 2025 17:10:03 +0200 Subject: [PATCH 3/3] get execution group --- cognition_objects/macro.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cognition_objects/macro.py b/cognition_objects/macro.py index 053261de..5f207c62 100644 --- a/cognition_objects/macro.py +++ b/cognition_objects/macro.py @@ -77,6 +77,13 @@ def get_overview_for_all_for_me( return final_list +def get_execution_group(execution_group_id: str) -> CognitionMacro: + query = session.query(CognitionMacroExecution).filter( + CognitionMacroExecution.execution_group_id == execution_group_id, + ) + return query.first() + + def get_all_macro_executions( macro_id: str, execution_group_id: str,