fix(chats): filter messages to include only relevant user and assistant content in chat retrieval
Browse filesfix(message): change links type from HttpUrl to string for consistency
fix(agent): ensure links are converted to strings when structuring output
- api/routers/chats.py +12 -3
- db/schemas/message.py +2 -2
- workflow/agent.py +2 -2
    	
        api/routers/chats.py
    CHANGED
    
    | @@ -69,7 +69,18 @@ def get_user_chats(*, db: Session = Depends(get_db), user_id: uuid.UUID = Depend | |
| 69 | 
             
            def get_single_chat_with_messages(*, chat_id: uuid.UUID, user_id: uuid.UUID = Depends(get_current_user), db: Session = Depends(get_db)):
         | 
| 70 | 
             
                """Retrieves a specific chat with all its messages."""
         | 
| 71 | 
             
                chat = get_chat_for_user(chat_id, user_id, db)
         | 
| 72 | 
            -
                 | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 73 |  | 
| 74 | 
             
            @router.patch("/{chat_id}", response_model=ChatReadSimple)
         | 
| 75 | 
             
            def rename_chat(*, chat_id: uuid.UUID, chat_update: ChatUpdate, user_id: uuid.UUID = Depends(get_current_user), db: Session = Depends(get_db)):
         | 
| @@ -117,7 +128,6 @@ async def post_message_and_get_response( | |
| 117 | 
             
                final_answer = response["answer"]
         | 
| 118 | 
             
                links = response["links"]
         | 
| 119 | 
             
                updated_messages_from_agent = response["messages"]
         | 
| 120 | 
            -
             | 
| 121 | 
             
                # 6. Isolate the messages that are new to this turn
         | 
| 122 | 
             
                new_lc_messages = updated_messages_from_agent[initial_message_count - 1:]
         | 
| 123 |  | 
| @@ -137,5 +147,4 @@ async def post_message_and_get_response( | |
| 137 |  | 
| 138 | 
             
                # 9. Find the final AI message from the list of newly saved messages.
         | 
| 139 | 
             
                final_ai_message = newly_created_db_messages[-1]
         | 
| 140 | 
            -
                
         | 
| 141 | 
             
                return final_ai_message
         | 
|  | |
| 69 | 
             
            def get_single_chat_with_messages(*, chat_id: uuid.UUID, user_id: uuid.UUID = Depends(get_current_user), db: Session = Depends(get_db)):
         | 
| 70 | 
             
                """Retrieves a specific chat with all its messages."""
         | 
| 71 | 
             
                chat = get_chat_for_user(chat_id, user_id, db)
         | 
| 72 | 
            +
                filtered_messages = [
         | 
| 73 | 
            +
                    msg for msg in chat.messages
         | 
| 74 | 
            +
                    if msg.role == 'user' or (msg.role == 'assistant' and msg.content)
         | 
| 75 | 
            +
                ]
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                return ChatReadWithMessages(
         | 
| 78 | 
            +
                    id=chat.id,
         | 
| 79 | 
            +
                    title=chat.title,
         | 
| 80 | 
            +
                    created_at=chat.created_at,
         | 
| 81 | 
            +
                    updated_at=chat.updated_at,
         | 
| 82 | 
            +
                    messages=filtered_messages
         | 
| 83 | 
            +
                )
         | 
| 84 |  | 
| 85 | 
             
            @router.patch("/{chat_id}", response_model=ChatReadSimple)
         | 
| 86 | 
             
            def rename_chat(*, chat_id: uuid.UUID, chat_update: ChatUpdate, user_id: uuid.UUID = Depends(get_current_user), db: Session = Depends(get_db)):
         | 
|  | |
| 128 | 
             
                final_answer = response["answer"]
         | 
| 129 | 
             
                links = response["links"]
         | 
| 130 | 
             
                updated_messages_from_agent = response["messages"]
         | 
|  | |
| 131 | 
             
                # 6. Isolate the messages that are new to this turn
         | 
| 132 | 
             
                new_lc_messages = updated_messages_from_agent[initial_message_count - 1:]
         | 
| 133 |  | 
|  | |
| 147 |  | 
| 148 | 
             
                # 9. Find the final AI message from the list of newly saved messages.
         | 
| 149 | 
             
                final_ai_message = newly_created_db_messages[-1]
         | 
|  | |
| 150 | 
             
                return final_ai_message
         | 
    	
        db/schemas/message.py
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 | 
             
            import uuid
         | 
| 2 | 
             
            from datetime import datetime
         | 
| 3 | 
            -
            from pydantic import BaseModel, Field,  | 
| 4 | 
             
            from typing import Optional
         | 
| 5 |  | 
| 6 | 
             
            # -------------------
         | 
| @@ -17,7 +17,7 @@ class MessageRead(BaseModel): | |
| 17 | 
             
                role: str
         | 
| 18 | 
             
                created_at: datetime
         | 
| 19 |  | 
| 20 | 
            -
                links: Optional[list[ | 
| 21 |  | 
| 22 | 
             
                raw_content: Optional[str] = Field(None, alias='content', exclude=True)
         | 
| 23 | 
             
                answer: Optional[str] = Field(None, alias='answer', exclude=True)
         | 
|  | |
| 1 | 
             
            import uuid
         | 
| 2 | 
             
            from datetime import datetime
         | 
| 3 | 
            +
            from pydantic import BaseModel, Field, computed_field
         | 
| 4 | 
             
            from typing import Optional
         | 
| 5 |  | 
| 6 | 
             
            # -------------------
         | 
|  | |
| 17 | 
             
                role: str
         | 
| 18 | 
             
                created_at: datetime
         | 
| 19 |  | 
| 20 | 
            +
                links: Optional[list[str]] = None
         | 
| 21 |  | 
| 22 | 
             
                raw_content: Optional[str] = Field(None, alias='content', exclude=True)
         | 
| 23 | 
             
                answer: Optional[str] = Field(None, alias='answer', exclude=True)
         | 
    	
        workflow/agent.py
    CHANGED
    
    | @@ -44,14 +44,14 @@ def agent(messages: list[BaseMessage], config: RunnableConfig): | |
| 44 |  | 
| 45 | 
             
                # Check if any tools other than search_memories were called
         | 
| 46 | 
             
                other_tools_called = any(name != "search_memories" for name in tool_names_called)
         | 
| 47 | 
            -
             | 
| 48 | 
             
                if tool_calls_count > 0 and other_tools_called:
         | 
| 49 | 
             
                    # Structure the final output
         | 
| 50 | 
             
                    structured_output = (
         | 
| 51 | 
             
                        get_structued_output(llm_response.content).result().model_dump()
         | 
| 52 | 
             
                    )
         | 
| 53 | 
             
                    answer = structured_output["text"]
         | 
| 54 | 
            -
                    links = structured_output.get("links", [])
         | 
| 55 | 
             
                else:
         | 
| 56 | 
             
                    answer = llm_response.content
         | 
| 57 |  | 
|  | |
| 44 |  | 
| 45 | 
             
                # Check if any tools other than search_memories were called
         | 
| 46 | 
             
                other_tools_called = any(name != "search_memories" for name in tool_names_called)
         | 
| 47 | 
            +
                
         | 
| 48 | 
             
                if tool_calls_count > 0 and other_tools_called:
         | 
| 49 | 
             
                    # Structure the final output
         | 
| 50 | 
             
                    structured_output = (
         | 
| 51 | 
             
                        get_structued_output(llm_response.content).result().model_dump()
         | 
| 52 | 
             
                    )
         | 
| 53 | 
             
                    answer = structured_output["text"]
         | 
| 54 | 
            +
                    links = [str(link) for link in structured_output.get("links", [])]
         | 
| 55 | 
             
                else:
         | 
| 56 | 
             
                    answer = llm_response.content
         | 
| 57 |  |