Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions apps/application/serializers/application_chat_record.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,34 @@ def get_loop_workflow_node(details):
result.append(inner_item)
return result

@staticmethod
def execution_order_key(item):
# ChatRecord.details is stored as PostgreSQL jsonb, which does not
# preserve object key order, so a details dict read back from the
# database is no longer in node execution order. Every node records
# its execution sequence in "index" (see INode.get_details), so sort
# by it; entries without an index are auxiliary records (e.g.
# problem_padding) and keep their stored order after the indexed ones.
index = item.get("index") if isinstance(item, dict) else None
return (index is None, index if isinstance(index, int) else 0)

@staticmethod
def sort_loop_node_iterations(execution_details):
# Per-iteration dicts of a loop node are keyed by runtime_node_id and
# suffer from the same jsonb key-order loss; restore the inner
# execution order too.
for item in execution_details:
loop_node_data = item.get("loop_node_data") if isinstance(item, dict) else None
if isinstance(loop_node_data, list):
for i, iteration in enumerate(loop_node_data):
if isinstance(iteration, dict):
loop_node_data[i] = dict(
sorted(
iteration.items(),
key=lambda kv: ApplicationChatRecordQuerySerializers.execution_order_key(kv[1]),
)
)

@staticmethod
def reset_chat_record(chat_record, show_source, show_exec):
knowledge_list = []
Expand Down Expand Up @@ -214,6 +242,11 @@ def reset_chat_record(chat_record, show_source, show_exec):
if (True if show_exec else chat_record.details[key].get("type") == "start-node")
]
}
# A details dict read back from the database is in PostgreSQL jsonb key
# order, not execution order (the debug window reads the in-memory
# cache and is unaffected); restore the execution order before output.
show_exec_dict["execution_details"].sort(key=ApplicationChatRecordQuerySerializers.execution_order_key)
ApplicationChatRecordQuerySerializers.sort_loop_node_iterations(show_exec_dict["execution_details"])
return {
**ChatRecordSerializerModel(chat_record).data,
"padding_problem_text": chat_record.details.get("problem_padding").get("padding_problem_text")
Expand Down