databao/executors/frontend/messages.py (29 lines of code) (raw):
from langchain_core.messages import AIMessage, AIMessageChunk, BaseMessage, ToolCall, ToolMessage
def get_tool_call(messages: list[BaseMessage], tool_message: ToolMessage) -> ToolCall | None:
"""Returns the tool call which caused the ToolMessage."""
for message in reversed(messages):
if isinstance(message, AIMessage):
for tool_call in message.tool_calls:
if tool_call["id"] == tool_message.tool_call_id:
return tool_call
return None
def get_tool_call_sql(tool_call: ToolCall) -> str | None:
args = tool_call["args"]
# Currently, there is only run_sql_query with an sql param
if "sql" in args:
sql = args["sql"]
assert isinstance(sql, str), f"Expected SQL to be a string, got {type(sql)}"
return sql
return None
def get_reasoning_content(message: AIMessage | AIMessageChunk) -> str:
# Assume only one of the reasoning parts is present, so there will be no duplication.
reasoning_text = ""
# OpenAI output_version: v0
reasoning_chunk = message.additional_kwargs.get("reasoning", {})
reasoning_summary_chunks = reasoning_chunk.get("summary", [])
for reasoning_summary_chunk in reasoning_summary_chunks:
reasoning_text += reasoning_summary_chunk.get("text", "")
# "Qwen" style reasoning:
reasoning_text += message.additional_kwargs.get("reasoning_content", "")
# OpenAI output_version: responses/v1
blocks = message.content if isinstance(message.content, list) else [message.content]
for block in blocks:
if isinstance(block, dict) and block.get("type", "text") == "reasoning":
for summary in block["summary"]:
reasoning_text += summary["text"]
assert isinstance(reasoning_text, str), f"Expected a string, got {type(reasoning_text)}"
return reasoning_text