@@ -118,26 +118,8 @@ def run(self) -> None:
118118 ):
119119 return
120120
121- # Init conversation variables
122- stmt = select (ConversationVariable ).where (
123- ConversationVariable .app_id == self .conversation .app_id ,
124- ConversationVariable .conversation_id == self .conversation .id ,
125- )
126- with Session (db .engine ) as session :
127- db_conversation_variables = session .scalars (stmt ).all ()
128- if not db_conversation_variables :
129- # Create conversation variables if they don't exist.
130- db_conversation_variables = [
131- ConversationVariable .from_variable (
132- app_id = self .conversation .app_id , conversation_id = self .conversation .id , variable = variable
133- )
134- for variable in self ._workflow .conversation_variables
135- ]
136- session .add_all (db_conversation_variables )
137- # Convert database entities to variables.
138- conversation_variables = [item .to_variable () for item in db_conversation_variables ]
139-
140- session .commit ()
121+ # Initialize conversation variables
122+ conversation_variables = self ._initialize_conversation_variables ()
141123
142124 # Create a variable pool.
143125 system_inputs = SystemVariable (
@@ -292,3 +274,100 @@ def moderation_for_inputs(
292274 message_id = message_id ,
293275 trace_manager = app_generate_entity .trace_manager ,
294276 )
277+
278+ def _initialize_conversation_variables (self ) -> list [VariableUnion ]:
279+ """
280+ Initialize conversation variables for the current conversation.
281+
282+ This method:
283+ 1. Loads existing variables from the database
284+ 2. Creates new variables if none exist
285+ 3. Syncs missing variables from the workflow definition
286+
287+ :return: List of conversation variables ready for use
288+ """
289+ with Session (db .engine ) as session :
290+ existing_variables = self ._load_existing_conversation_variables (session )
291+
292+ if not existing_variables :
293+ # First time initialization - create all variables
294+ existing_variables = self ._create_all_conversation_variables (session )
295+ else :
296+ # Check and add any missing variables from the workflow
297+ existing_variables = self ._sync_missing_conversation_variables (session , existing_variables )
298+
299+ # Convert to Variable objects for use in the workflow
300+ conversation_variables = [var .to_variable () for var in existing_variables ]
301+
302+ session .commit ()
303+ return cast (list [VariableUnion ], conversation_variables )
304+
305+ def _load_existing_conversation_variables (self , session : Session ) -> list [ConversationVariable ]:
306+ """
307+ Load existing conversation variables from the database.
308+
309+ :param session: Database session
310+ :return: List of existing conversation variables
311+ """
312+ stmt = select (ConversationVariable ).where (
313+ ConversationVariable .app_id == self .conversation .app_id ,
314+ ConversationVariable .conversation_id == self .conversation .id ,
315+ )
316+ return list (session .scalars (stmt ).all ())
317+
318+ def _create_all_conversation_variables (self , session : Session ) -> list [ConversationVariable ]:
319+ """
320+ Create all conversation variables for a new conversation.
321+
322+ :param session: Database session
323+ :return: List of created conversation variables
324+ """
325+ new_variables = [
326+ ConversationVariable .from_variable (
327+ app_id = self .conversation .app_id , conversation_id = self .conversation .id , variable = variable
328+ )
329+ for variable in self ._workflow .conversation_variables
330+ ]
331+
332+ if new_variables :
333+ session .add_all (new_variables )
334+
335+ return new_variables
336+
337+ def _sync_missing_conversation_variables (
338+ self , session : Session , existing_variables : list [ConversationVariable ]
339+ ) -> list [ConversationVariable ]:
340+ """
341+ Sync missing conversation variables from the workflow definition.
342+
343+ This handles the case where new variables are added to a workflow
344+ after conversations have already been created.
345+
346+ :param session: Database session
347+ :param existing_variables: List of existing conversation variables
348+ :return: Updated list including any newly created variables
349+ """
350+ # Get IDs of existing and workflow variables
351+ existing_ids = {var .id for var in existing_variables }
352+ workflow_variables = {var .id : var for var in self ._workflow .conversation_variables }
353+
354+ # Find missing variable IDs
355+ missing_ids = set (workflow_variables .keys ()) - existing_ids
356+
357+ if not missing_ids :
358+ return existing_variables
359+
360+ # Create missing variables with their default values
361+ new_variables = [
362+ ConversationVariable .from_variable (
363+ app_id = self .conversation .app_id ,
364+ conversation_id = self .conversation .id ,
365+ variable = workflow_variables [var_id ],
366+ )
367+ for var_id in missing_ids
368+ ]
369+
370+ session .add_all (new_variables )
371+
372+ # Return combined list
373+ return existing_variables + new_variables
0 commit comments