|
17 | 17 | AttachmentFileTypes, |
18 | 18 | ImageFile, |
19 | 19 | ) |
| 20 | +from basilisk.conversation.content_utils import split_reasoning_and_content |
20 | 21 | from basilisk.conversation.conversation_model import ( |
21 | 22 | Conversation, |
22 | 23 | Message, |
@@ -234,6 +235,7 @@ def _save_message( |
234 | 235 | message_block_id=block_id, |
235 | 236 | role=role, |
236 | 237 | content=message.content, |
| 238 | + reasoning=getattr(message, "reasoning", None), |
237 | 239 | audio_data=getattr(message, "audio_data", None), |
238 | 240 | audio_format=getattr(message, "audio_format", None), |
239 | 241 | ) |
@@ -740,56 +742,72 @@ def load_conversation(self, conv_id: int) -> Conversation: |
740 | 742 | version=BSKC_VERSION, |
741 | 743 | ) |
742 | 744 |
|
| 745 | + def _load_message_attachments( |
| 746 | + self, db_msg: DBMessage |
| 747 | + ) -> list[AttachmentFile | ImageFile] | None: |
| 748 | + """Load attachments from a DB message.""" |
| 749 | + if not db_msg.attachment_links: |
| 750 | + return None |
| 751 | + attachments = [] |
| 752 | + for link in sorted(db_msg.attachment_links, key=lambda x: x.position): |
| 753 | + attachment = self._load_attachment( |
| 754 | + link.attachment, link.description |
| 755 | + ) |
| 756 | + if attachment: |
| 757 | + attachments.append(attachment) |
| 758 | + return attachments or None |
| 759 | + |
| 760 | + def _load_message_citations(self, db_msg: DBMessage) -> list[dict] | None: |
| 761 | + """Load citations from a DB message.""" |
| 762 | + if not db_msg.citations: |
| 763 | + return None |
| 764 | + citations = [] |
| 765 | + for db_cit in sorted(db_msg.citations, key=lambda x: x.position): |
| 766 | + citation = {} |
| 767 | + if db_cit.cited_text is not None: |
| 768 | + citation["cited_text"] = db_cit.cited_text |
| 769 | + if db_cit.source_title is not None: |
| 770 | + citation["source_title"] = db_cit.source_title |
| 771 | + if db_cit.source_url is not None: |
| 772 | + citation["source_url"] = db_cit.source_url |
| 773 | + if db_cit.start_index is not None: |
| 774 | + citation["start_index"] = db_cit.start_index |
| 775 | + if db_cit.end_index is not None: |
| 776 | + citation["end_index"] = db_cit.end_index |
| 777 | + citations.append(citation) |
| 778 | + return citations |
| 779 | + |
| 780 | + def _resolve_reasoning_and_content( |
| 781 | + self, reasoning: str | None, content: str |
| 782 | + ) -> tuple[str | None, str]: |
| 783 | + """Resolve reasoning and content, parsing legacy format if needed.""" |
| 784 | + if reasoning is not None or not content: |
| 785 | + return reasoning, content |
| 786 | + parsed_reasoning, parsed_content = split_reasoning_and_content(content) |
| 787 | + if parsed_reasoning is not None: |
| 788 | + return parsed_reasoning, parsed_content |
| 789 | + return reasoning, content |
| 790 | + |
743 | 791 | def _load_message(self, db_msg: DBMessage) -> Message: |
744 | 792 | """Convert a DB message to a Pydantic message.""" |
745 | 793 | role = ( |
746 | 794 | MessageRoleEnum.USER |
747 | 795 | if db_msg.role == "user" |
748 | 796 | else MessageRoleEnum.ASSISTANT |
749 | 797 | ) |
750 | | - |
751 | | - # Load attachments |
752 | | - attachments = None |
753 | | - if db_msg.attachment_links: |
754 | | - attachments = [] |
755 | | - sorted_links = sorted( |
756 | | - db_msg.attachment_links, key=lambda x: x.position |
757 | | - ) |
758 | | - for link in sorted_links: |
759 | | - db_att = link.attachment |
760 | | - attachment = self._load_attachment(db_att, link.description) |
761 | | - if attachment: |
762 | | - attachments.append(attachment) |
763 | | - |
764 | | - # Load citations |
765 | | - citations = None |
766 | | - if db_msg.citations: |
767 | | - citations = [] |
768 | | - sorted_cites = sorted(db_msg.citations, key=lambda x: x.position) |
769 | | - for db_cit in sorted_cites: |
770 | | - citation = {} |
771 | | - if db_cit.cited_text is not None: |
772 | | - citation["cited_text"] = db_cit.cited_text |
773 | | - if db_cit.source_title is not None: |
774 | | - citation["source_title"] = db_cit.source_title |
775 | | - if db_cit.source_url is not None: |
776 | | - citation["source_url"] = db_cit.source_url |
777 | | - if db_cit.start_index is not None: |
778 | | - citation["start_index"] = db_cit.start_index |
779 | | - if db_cit.end_index is not None: |
780 | | - citation["end_index"] = db_cit.end_index |
781 | | - citations.append(citation) |
782 | | - |
783 | | - audio_data = getattr(db_msg, "audio_data", None) |
784 | | - audio_format = getattr(db_msg, "audio_format", None) |
785 | | - |
| 798 | + attachments = self._load_message_attachments(db_msg) |
| 799 | + citations = self._load_message_citations(db_msg) |
| 800 | + reasoning, content = self._resolve_reasoning_and_content( |
| 801 | + getattr(db_msg, "reasoning", None), db_msg.content |
| 802 | + ) |
786 | 803 | return Message( |
787 | 804 | role=role, |
788 | | - content=db_msg.content, |
789 | | - attachments=attachments or None, |
790 | | - citations=citations or None, |
791 | | - audio_data=audio_data, |
792 | | - audio_format=audio_format, |
| 805 | + content=content, |
| 806 | + reasoning=reasoning, |
| 807 | + attachments=attachments, |
| 808 | + citations=citations, |
| 809 | + audio_data=getattr(db_msg, "audio_data", None), |
| 810 | + audio_format=getattr(db_msg, "audio_format", None), |
793 | 811 | ) |
794 | 812 |
|
795 | 813 | @staticmethod |
|
0 commit comments