Skip to content

Commit 6900b08

Browse files
authored
fix: sync missing conversation variables for existing conversations (langgenius#23649)
1 parent dc64134 commit 6900b08

2 files changed

Lines changed: 518 additions & 20 deletions

File tree

api/core/app/apps/advanced_chat/app_runner.py

Lines changed: 99 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)