File size: 1,228 Bytes
7ff7119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"""synthesizer_node — at the end of the tool loop, take the last AIMessage.content as final_answer."""

from __future__ import annotations

from langchain_core.messages import AIMessage

from graph.states.chat_state import ChatState


async def synthesizer_node(state: ChatState) -> dict:
    """Take the last AIMessage.content from messages as final_answer."""
    messages = state.get("messages") or []
    last_ai_content = ""
    for m in reversed(messages):
        if isinstance(m, AIMessage):
            content = m.content
            if isinstance(content, str) and content.strip():
                last_ai_content = content
                break
            elif isinstance(content, list):
                # Anthropic-style content blocks
                text_parts = [
                    part.get("text", "") for part in content
                    if isinstance(part, dict) and part.get("type") == "text"
                ]
                if any(text_parts):
                    last_ai_content = "\n".join(t for t in text_parts if t)
                    break

    return {
        "final_answer": last_ai_content or "(empty answer)",
        "trace": [f"synthesizer: {len(last_ai_content)} characters"],
    }