Change assistant render order to reasoning -> content -> tool calls.

Previously reasoning and tool calls were rendered first, followed by
content. The tool call response was then rendered in the second reasoning
section. This made the tool call and response disjoint and, with the
current reasoning hiding logic, not visible at the same time.
This commit is contained in:
Bartosz Taudul
2026-01-02 12:25:25 +01:00
parent b7a51d265c
commit b6f03ef75d
3 changed files with 44 additions and 31 deletions

View File

@@ -467,7 +467,16 @@ void TracyLlm::Draw()
}
ImGui::PushID( turnIdx++ );
if( !m_chatUi->Turn( role, line, thinkIdx <= turnIdx, turnIdx == m_chat.size() - 1 ) )
TracyLlmChat::Think think = TracyLlmChat::Think::Hide;
if( thinkIdx <= turnIdx )
{
think = TracyLlmChat::Think::Show;
}
else if( thinkIdx == turnIdx + 1 && role == TracyLlmChat::TurnRole::Assistant && line.contains( "content" ) )
{
think = TracyLlmChat::Think::ToolCall;
}
if( !m_chatUi->Turn( role, line, think, turnIdx == m_chat.size() - 1 ) )
{
if( role == TracyLlmChat::TurnRole::Assistant )
{

View File

@@ -104,7 +104,7 @@ void TracyLlmChat::End()
}
}
bool TracyLlmChat::Turn( TurnRole role, const nlohmann::json& json, bool think, bool last )
bool TracyLlmChat::Turn( TurnRole role, const nlohmann::json& json, Think think, bool last )
{
bool keep = true;
const auto& roleData = roles[(int)role];
@@ -207,39 +207,27 @@ bool TracyLlmChat::Turn( TurnRole role, const nlohmann::json& json, bool think,
}
else
{
if( think )
if( think == Think::Show && json.contains( "reasoning_content" ) )
{
if( json.contains( "reasoning_content" ) )
auto& reasoning = json["reasoning_content"].get_ref<const std::string&>();
ThinkScope( !roleChange );
if( m_thinkOpen )
{
auto& reasoning = json["reasoning_content"].get_ref<const std::string&>();
ThinkScope( !roleChange );
if( m_thinkOpen )
{
PrintThink( reasoning.c_str(), reasoning.size() );
}
else if( last && !json.contains( "content" ) )
{
const auto cutlen = std::max( int( utflen( reasoning.c_str() ) ) - 40, 0 );
const auto cut = utfendl( reasoning.c_str(), cutlen );
std::string str = cut;
for( auto& c : str )
{
if( c == '\n' ) c = ' ';
}
ImGui::SameLine();
ImGui::PushStyleColor( ImGuiCol_Text, 0xFF555555 );
ImGui::Text( "…%s", str.c_str() );
ImGui::PopStyleColor();
}
PrintThink( reasoning.c_str(), reasoning.size() );
}
if( json.contains( "tool_calls" ) )
else if( last && !json.contains( "content" ) )
{
ThinkScope( !roleChange );
if( m_thinkOpen )
const auto cutlen = std::max( int( utflen( reasoning.c_str() ) ) - 40, 0 );
const auto cut = utfendl( reasoning.c_str(), cutlen );
std::string str = cut;
for( auto& c : str )
{
auto calls = json["tool_calls"].dump( 2 );
PrintToolCall( calls.c_str(), calls.size() );
if( c == '\n' ) c = ' ';
}
ImGui::SameLine();
ImGui::PushStyleColor( ImGuiCol_Text, 0xFF555555 );
ImGui::Text( "…%s", str.c_str() );
ImGui::PopStyleColor();
}
}
if( json.contains( "content" ) )
@@ -247,7 +235,7 @@ bool TracyLlmChat::Turn( TurnRole role, const nlohmann::json& json, bool think,
auto& content = json["content"].get_ref<const std::string&>();
if( json["role"].get_ref<const std::string&>() == "tool" )
{
if( think )
if( think == Think::Show )
{
ThinkScope( !roleChange );
if( m_thinkOpen )
@@ -293,6 +281,15 @@ bool TracyLlmChat::Turn( TurnRole role, const nlohmann::json& json, bool think,
}
}
}
if( think != Think::Hide && json.contains( "tool_calls" ) )
{
ThinkScope( !roleChange || json.contains( "content" ) );
if( m_thinkOpen )
{
auto calls = json["tool_calls"].dump( 2 );
PrintToolCall( calls.c_str(), calls.size() );
}
}
}
ImGui::PopStyleColor();

View File

@@ -25,13 +25,20 @@ public:
None,
};
enum class Think
{
Hide,
Show,
ToolCall
};
TracyLlmChat();
~TracyLlmChat();
void Begin();
void End();
bool Turn( TurnRole role, const nlohmann::json& json, bool think, bool last );
bool Turn( TurnRole role, const nlohmann::json& json, Think think, bool last );
private:
void NormalScope();