Enhance agent chat functionality with ROM context support and structured message rendering

This commit is contained in:
scawful
2025-10-03 14:46:22 -04:00
parent dc6040551e
commit 3715ae98eb
11 changed files with 341 additions and 29 deletions

View File

@@ -933,6 +933,10 @@ absl::Status EditorManager::Update() {
}
#ifdef YAZE_WITH_GRPC
if (show_agent_chat_widget_) {
Rom* rom_context =
(current_rom_ != nullptr && current_rom_->is_loaded()) ? current_rom_
: nullptr;
agent_chat_widget_.SetRomContext(rom_context);
agent_chat_widget_.Draw();
}
#endif

View File

@@ -1,6 +1,49 @@
#include "app/editor/system/agent_chat_widget.h"
#include <cstring>
#include <string>
#include <vector>
#include "imgui.h"
namespace {
const ImVec4 kUserColor = ImVec4(0.88f, 0.76f, 0.36f, 1.0f);
const ImVec4 kAgentColor = ImVec4(0.56f, 0.82f, 0.62f, 1.0f);
const ImVec4 kJsonTextColor = ImVec4(0.78f, 0.83f, 0.90f, 1.0f);
void RenderTable(const yaze::cli::agent::ChatMessage::TableData& table_data) {
const int column_count = static_cast<int>(table_data.headers.size());
if (column_count <= 0) {
ImGui::TextDisabled("(empty)");
return;
}
if (ImGui::BeginTable("structured_table", column_count,
ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg |
ImGuiTableFlags_SizingStretchProp)) {
for (const auto& header : table_data.headers) {
ImGui::TableSetupColumn(header.c_str());
}
ImGui::TableHeadersRow();
for (const auto& row : table_data.rows) {
ImGui::TableNextRow();
for (int col = 0; col < column_count; ++col) {
ImGui::TableSetColumnIndex(col);
if (col < static_cast<int>(row.size())) {
ImGui::TextWrapped("%s", row[col].c_str());
} else {
ImGui::TextUnformatted("-");
}
}
}
ImGui::EndTable();
}
}
} // namespace
namespace yaze {
namespace editor {
@@ -9,6 +52,10 @@ AgentChatWidget::AgentChatWidget() {
memset(input_buffer_, 0, sizeof(input_buffer_));
}
void AgentChatWidget::SetRomContext(Rom* rom) {
agent_service_.SetRomContext(rom);
}
void AgentChatWidget::Draw() {
if (!active_) {
return;
@@ -17,13 +64,54 @@ void AgentChatWidget::Draw() {
ImGui::Begin(title_.c_str(), &active_);
// Display message history
ImGui::BeginChild("History", ImVec2(0, -ImGui::GetFrameHeightWithSpacing()));
for (const auto& msg : agent_service_.GetHistory()) {
std::string prefix =
msg.sender == cli::agent::ChatMessage::Sender::kUser ? "You: " : "Agent: ";
ImGui::TextWrapped((prefix + msg.message).c_str());
const auto& history = agent_service_.GetHistory();
if (ImGui::BeginChild("History", ImVec2(0, -ImGui::GetFrameHeightWithSpacing()),
false,
ImGuiWindowFlags_AlwaysVerticalScrollbar |
ImGuiWindowFlags_HorizontalScrollbar)) {
for (size_t index = 0; index < history.size(); ++index) {
const auto& msg = history[index];
ImGui::PushID(static_cast<int>(index));
const bool from_user =
msg.sender == cli::agent::ChatMessage::Sender::kUser;
const ImVec4 header_color = from_user ? kUserColor : kAgentColor;
const char* header_label = from_user ? "You" : "Agent";
ImGui::TextColored(header_color, "%s", header_label);
ImGui::Indent();
if (msg.json_pretty.has_value()) {
if (ImGui::SmallButton("Copy JSON")) {
ImGui::SetClipboardText(msg.json_pretty->c_str());
}
ImGui::SameLine();
ImGui::TextDisabled("Structured response");
}
if (msg.table_data.has_value()) {
RenderTable(*msg.table_data);
} else if (msg.json_pretty.has_value()) {
ImGui::PushStyleColor(ImGuiCol_Text, kJsonTextColor);
ImGui::TextUnformatted(msg.json_pretty->c_str());
ImGui::PopStyleColor();
} else {
ImGui::TextWrapped("%s", msg.message.c_str());
}
ImGui::Unindent();
ImGui::Spacing();
ImGui::Separator();
ImGui::PopID();
}
if (history.size() > last_history_size_) {
ImGui::SetScrollHereY(1.0f);
}
}
ImGui::EndChild();
last_history_size_ = history.size();
// Display input text box
if (ImGui::InputText("Input", input_buffer_, sizeof(input_buffer_),

View File

@@ -6,6 +6,9 @@
#include "cli/service/agent/conversational_agent_service.h"
namespace yaze {
class Rom;
namespace editor {
class AgentChatWidget {
@@ -14,6 +17,8 @@ class AgentChatWidget {
void Draw();
void SetRomContext(Rom* rom);
bool* active() { return &active_; }
void set_active(bool active) { active_ = active; }
@@ -22,6 +27,7 @@ class AgentChatWidget {
char input_buffer_[1024];
bool active_ = false;
std::string title_;
size_t last_history_size_ = 0;
};
} // namespace editor