feat: Enhance Agent Editor and Chat History Management
- Added support for internal message handling in the AgentChatHistoryCodec, allowing messages marked as internal to be excluded from user display. - Updated the AgentChatWidget to skip rendering internal messages, improving user experience by reducing clutter. - Introduced a comprehensive bot profile management system in the AgentEditor, enabling users to create, save, load, and manage bot profiles with detailed configurations. - Enhanced the UI for the AgentEditor, including a new tabbed interface for better organization of settings, prompts, and profiles, along with improved metrics and chat history viewing capabilities. - Implemented JSON support for bot profile management, allowing for easy export and import of profiles, streamlining user workflows.
This commit is contained in:
@@ -159,6 +159,7 @@ absl::StatusOr<AgentChatHistoryCodec::Snapshot> AgentChatHistoryCodec::Load(
|
|||||||
: cli::agent::ChatMessage::Sender::kAgent;
|
: cli::agent::ChatMessage::Sender::kAgent;
|
||||||
message.message = item.value("message", "");
|
message.message = item.value("message", "");
|
||||||
message.timestamp = ParseTimestamp(item["timestamp"]);
|
message.timestamp = ParseTimestamp(item["timestamp"]);
|
||||||
|
message.is_internal = item.value("is_internal", false);
|
||||||
|
|
||||||
if (item.contains("json_pretty") && item["json_pretty"].is_string()) {
|
if (item.contains("json_pretty") && item["json_pretty"].is_string()) {
|
||||||
message.json_pretty = item["json_pretty"].get<std::string>();
|
message.json_pretty = item["json_pretty"].get<std::string>();
|
||||||
@@ -260,6 +261,7 @@ absl::Status AgentChatHistoryCodec::Save(
|
|||||||
entry["timestamp"] = absl::FormatTime(absl::RFC3339_full,
|
entry["timestamp"] = absl::FormatTime(absl::RFC3339_full,
|
||||||
message.timestamp,
|
message.timestamp,
|
||||||
absl::UTCTimeZone());
|
absl::UTCTimeZone());
|
||||||
|
entry["is_internal"] = message.is_internal;
|
||||||
|
|
||||||
if (message.json_pretty.has_value()) {
|
if (message.json_pretty.has_value()) {
|
||||||
entry["json_pretty"] = *message.json_pretty;
|
entry["json_pretty"] = *message.json_pretty;
|
||||||
|
|||||||
@@ -324,6 +324,11 @@ void AgentChatWidget::HandleAgentResponse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AgentChatWidget::RenderMessage(const ChatMessage& msg, int index) {
|
void AgentChatWidget::RenderMessage(const ChatMessage& msg, int index) {
|
||||||
|
// Skip internal messages (tool results meant only for the LLM)
|
||||||
|
if (msg.is_internal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::PushID(index);
|
ImGui::PushID(index);
|
||||||
|
|
||||||
const bool from_user = (msg.sender == ChatMessage::Sender::kUser);
|
const bool from_user = (msg.sender == ChatMessage::Sender::kUser);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -5,10 +5,13 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "absl/status/statusor.h"
|
#include "absl/status/statusor.h"
|
||||||
#include "app/editor/editor.h"
|
#include "app/editor/editor.h"
|
||||||
|
#include "app/gui/modules/text_editor.h"
|
||||||
|
#include "cli/service/agent/conversational_agent_service.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
|
|
||||||
@@ -27,18 +30,22 @@ class NetworkCollaborationCoordinator;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @class AgentEditor
|
* @class AgentEditor
|
||||||
* @brief AI Agent Configuration Dashboard (separate from chat)
|
* @brief Comprehensive AI Agent Platform & Bot Creator
|
||||||
*
|
*
|
||||||
* A comprehensive configuration editor for the AI agent:
|
* A full-featured bot creation and management platform:
|
||||||
* - Agent provider configuration (Ollama, Gemini, Mock)
|
* - Agent provider configuration (Ollama, Gemini, Mock)
|
||||||
* - Model selection and parameters
|
* - Model selection and parameters
|
||||||
|
* - System prompt editing with live syntax highlighting
|
||||||
|
* - Bot profile management (create, save, load custom bots)
|
||||||
|
* - Chat history viewer and management
|
||||||
|
* - Session metrics and analytics dashboard
|
||||||
* - Collaboration settings (Local/Network)
|
* - Collaboration settings (Local/Network)
|
||||||
* - Z3ED command automation presets
|
* - Z3ED command automation presets
|
||||||
* - Multimodal/vision configuration
|
* - Multimodal/vision configuration
|
||||||
* - Session metrics and monitoring
|
* - Export/Import bot configurations
|
||||||
* - System prompt customization
|
|
||||||
*
|
*
|
||||||
* The chat widget is separate and managed by EditorManager.
|
* The chat widget is separate and managed by EditorManager, with
|
||||||
|
* a dense/compact mode for focused conversations.
|
||||||
*/
|
*/
|
||||||
class AgentEditor : public Editor {
|
class AgentEditor : public Editor {
|
||||||
public:
|
public:
|
||||||
@@ -67,7 +74,25 @@ class AgentEditor : public Editor {
|
|||||||
// Main rendering (called by Update())
|
// Main rendering (called by Update())
|
||||||
void DrawDashboard();
|
void DrawDashboard();
|
||||||
|
|
||||||
// Get current agent configuration (for chat to use)
|
// Bot Configuration & Profile Management
|
||||||
|
struct BotProfile {
|
||||||
|
std::string name = "Default Bot";
|
||||||
|
std::string description;
|
||||||
|
std::string provider = "mock";
|
||||||
|
std::string model;
|
||||||
|
std::string ollama_host = "http://localhost:11434";
|
||||||
|
std::string gemini_api_key;
|
||||||
|
std::string system_prompt;
|
||||||
|
bool verbose = false;
|
||||||
|
bool show_reasoning = true;
|
||||||
|
int max_tool_iterations = 4;
|
||||||
|
int max_retry_attempts = 3;
|
||||||
|
std::vector<std::string> tags;
|
||||||
|
absl::Time created_at = absl::Now();
|
||||||
|
absl::Time modified_at = absl::Now();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Legacy support
|
||||||
struct AgentConfig {
|
struct AgentConfig {
|
||||||
std::string provider = "mock";
|
std::string provider = "mock";
|
||||||
std::string model;
|
std::string model;
|
||||||
@@ -81,6 +106,16 @@ class AgentEditor : public Editor {
|
|||||||
AgentConfig GetCurrentConfig() const;
|
AgentConfig GetCurrentConfig() const;
|
||||||
void ApplyConfig(const AgentConfig& config);
|
void ApplyConfig(const AgentConfig& config);
|
||||||
|
|
||||||
|
// Bot Profile Management
|
||||||
|
absl::Status SaveBotProfile(const BotProfile& profile);
|
||||||
|
absl::Status LoadBotProfile(const std::string& name);
|
||||||
|
absl::Status DeleteBotProfile(const std::string& name);
|
||||||
|
std::vector<BotProfile> GetAllProfiles() const;
|
||||||
|
BotProfile GetCurrentProfile() const { return current_profile_; }
|
||||||
|
void SetCurrentProfile(const BotProfile& profile);
|
||||||
|
absl::Status ExportProfile(const BotProfile& profile, const std::filesystem::path& path);
|
||||||
|
absl::Status ImportProfile(const std::filesystem::path& path);
|
||||||
|
|
||||||
// Chat widget access (for EditorManager)
|
// Chat widget access (for EditorManager)
|
||||||
AgentChatWidget* GetChatWidget() { return chat_widget_.get(); }
|
AgentChatWidget* GetChatWidget() { return chat_widget_.get(); }
|
||||||
bool IsChatActive() const;
|
bool IsChatActive() const;
|
||||||
@@ -143,11 +178,21 @@ class AgentEditor : public Editor {
|
|||||||
void DrawConfigurationPanel();
|
void DrawConfigurationPanel();
|
||||||
void DrawStatusPanel();
|
void DrawStatusPanel();
|
||||||
void DrawMetricsPanel();
|
void DrawMetricsPanel();
|
||||||
|
void DrawPromptEditorPanel();
|
||||||
|
void DrawBotProfilesPanel();
|
||||||
|
void DrawChatHistoryViewer();
|
||||||
|
void DrawAdvancedMetricsPanel();
|
||||||
|
|
||||||
// Setup callbacks
|
// Setup callbacks
|
||||||
void SetupChatWidgetCallbacks();
|
void SetupChatWidgetCallbacks();
|
||||||
void SetupMultimodalCallbacks();
|
void SetupMultimodalCallbacks();
|
||||||
|
|
||||||
|
// Bot profile helpers
|
||||||
|
std::filesystem::path GetProfilesDirectory() const;
|
||||||
|
absl::Status EnsureProfilesDirectory();
|
||||||
|
std::string ProfileToJson(const BotProfile& profile) const;
|
||||||
|
absl::StatusOr<BotProfile> JsonToProfile(const std::string& json) const;
|
||||||
|
|
||||||
// Internal state
|
// Internal state
|
||||||
std::unique_ptr<AgentChatWidget> chat_widget_; // Owned by AgentEditor
|
std::unique_ptr<AgentChatWidget> chat_widget_; // Owned by AgentEditor
|
||||||
std::unique_ptr<AgentCollaborationCoordinator> local_coordinator_;
|
std::unique_ptr<AgentCollaborationCoordinator> local_coordinator_;
|
||||||
@@ -159,8 +204,19 @@ class AgentEditor : public Editor {
|
|||||||
ProposalDrawer* proposal_drawer_ = nullptr;
|
ProposalDrawer* proposal_drawer_ = nullptr;
|
||||||
Rom* rom_ = nullptr;
|
Rom* rom_ = nullptr;
|
||||||
|
|
||||||
// Configuration state
|
// Configuration state (legacy)
|
||||||
AgentConfig current_config_;
|
AgentConfig current_config_;
|
||||||
|
|
||||||
|
// Bot Profile System
|
||||||
|
BotProfile current_profile_;
|
||||||
|
std::vector<BotProfile> loaded_profiles_;
|
||||||
|
|
||||||
|
// System Prompt Editor
|
||||||
|
std::unique_ptr<TextEditor> prompt_editor_;
|
||||||
|
bool prompt_editor_initialized_ = false;
|
||||||
|
std::string active_prompt_file_ = "system_prompt_v3.txt";
|
||||||
|
|
||||||
|
// Collaboration state
|
||||||
CollaborationMode current_mode_ = CollaborationMode::kLocal;
|
CollaborationMode current_mode_ = CollaborationMode::kLocal;
|
||||||
bool in_session_ = false;
|
bool in_session_ = false;
|
||||||
std::string current_session_id_;
|
std::string current_session_id_;
|
||||||
@@ -169,6 +225,15 @@ class AgentEditor : public Editor {
|
|||||||
|
|
||||||
// UI state
|
// UI state
|
||||||
bool show_advanced_settings_ = false;
|
bool show_advanced_settings_ = false;
|
||||||
|
bool show_prompt_editor_ = false;
|
||||||
|
bool show_bot_profiles_ = false;
|
||||||
|
bool show_chat_history_ = false;
|
||||||
|
bool show_metrics_dashboard_ = false;
|
||||||
|
int selected_tab_ = 0; // 0=Config, 1=Prompts, 2=Bots, 3=History, 4=Metrics
|
||||||
|
|
||||||
|
// Chat history viewer state
|
||||||
|
std::vector<cli::agent::ChatMessage> cached_history_;
|
||||||
|
bool history_needs_refresh_ = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
|
|||||||
@@ -337,8 +337,9 @@ absl::StatusOr<ChatMessage> ConversationalAgentService::SendMessage(
|
|||||||
"The tool returned the following data:\n",
|
"The tool returned the following data:\n",
|
||||||
tool_output, "\n\n",
|
tool_output, "\n\n",
|
||||||
"Please provide a text_response field in your JSON to summarize this information for the user.");
|
"Please provide a text_response field in your JSON to summarize this information for the user.");
|
||||||
history_.push_back(
|
auto tool_result_msg = CreateMessage(ChatMessage::Sender::kUser, marked_output);
|
||||||
CreateMessage(ChatMessage::Sender::kUser, marked_output));
|
tool_result_msg.is_internal = true; // Don't show this to the human user
|
||||||
|
history_.push_back(tool_result_msg);
|
||||||
}
|
}
|
||||||
executed_tool = true;
|
executed_tool = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ struct ChatMessage {
|
|||||||
absl::Time timestamp;
|
absl::Time timestamp;
|
||||||
std::optional<std::string> json_pretty;
|
std::optional<std::string> json_pretty;
|
||||||
std::optional<TableData> table_data;
|
std::optional<TableData> table_data;
|
||||||
|
bool is_internal = false; // True for tool results and other messages not meant for user display
|
||||||
struct SessionMetrics {
|
struct SessionMetrics {
|
||||||
int turn_index = 0;
|
int turn_index = 0;
|
||||||
int total_user_messages = 0;
|
int total_user_messages = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user